int v4l2_overlay_set_position(int fd, int32_t x, int32_t y, int32_t w, int32_t h) { LOG_FUNCTION_NAME struct v4l2_format format; int ret; /* configure the src format pix */ /* configure the dst v4l2_overlay window */ format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get v4l2_overlay format"); if (ret) return ret; LOGV("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height); if (mRotateOverlay) { w = 480; h = 800; x = 0; y = 0; } configure_window(&format.fmt.win, w, h, x, y); format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set v4l2_overlay format"); LOGV("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height); if (ret) return ret; v4l2_overlay_dump_state(fd); return 0; }
int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt) { LOG_FUNCTION_NAME struct v4l2_format format; int ret; format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format"); if (ret) return ret; LOGV("v4l2_overlay_init:: w=%d h=%d", format.fmt.pix.width, format.fmt.pix.height); format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = configure_pixfmt(&format.fmt.pix, fmt, w, h); if (ret) return ret; LOGV("v4l2_overlay_init set:: w=%d h=%d fmt=%d", format.fmt.pix.width, format.fmt.pix.height, format.fmt.pix.pixelformat); ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set output format"); format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get output format"); LOGV("v4l2_overlay_init get:: w=%d h=%d fmt=%d", format.fmt.pix.width, format.fmt.pix.height, format.fmt.pix.pixelformat); char value[PROPERTY_VALUE_MAX]; property_get("debug.video.rotateoverlay", value, "0"); mRotateOverlay = atoi(value); LOGD_IF(mRotateOverlay, "overlay rotation enabled"); return ret; }
int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey, int keyType) { LOG_FUNCTION_NAME int ret; struct v4l2_framebuffer fbuf; struct v4l2_format fmt; memset(&fbuf, 0, sizeof(fbuf)); ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get transparency enables"); if (ret) return ret; #ifdef TARGET_OMAP4 if (enable) { if (keyType == EVIDEO_SOURCE) { fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; } else { fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY; } } else { fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY; } #else if (enable) fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; else fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; #endif ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable colorkey"); if (ret) return ret; if (enable) { memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get colorkey"); if (ret) return ret; fmt.fmt.win.chromakey = colorkey & 0xFFFFFF; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set colorkey"); } return ret; }
int v4l2_overlay_set_zorder(int fd, int value) { LOG_FUNCTION_NAME int ret; struct v4l2_format fmt; memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get zorder"); if (ret) return ret; fmt.fmt.win.zorder = value & 0x3; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set zorder"); return ret; }
int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { LOG_FUNCTION_NAME struct v4l2_crop crop; int ret; crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop"); crop.c.left = x; crop.c.top = y; crop.c.width = w; crop.c.height = h; crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; return v4l2_overlay_ioctl(fd, VIDIOC_S_CROP, &crop, "set crop"); }
int v4l2_overlay_set_local_alpha(int fd, int enable) { int ret; struct v4l2_framebuffer fbuf; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get transparency enables"); if (ret) return ret; if (enable) fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; else fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha"); return ret; }
int v4l2_overlay_set_rotation(int fd, int degree, int step, uint32_t mirror) { LOG_FUNCTION_NAME int ret; struct v4l2_control ctrl; memset(&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_VFLIP; ctrl.value = mirror; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "set FLIP"); memset(&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_ROTATE; ctrl.value = degree; if (mRotateOverlay) { ctrl.value = 90; } ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "set rotation"); return ret; }
int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w, int32_t *h) { struct v4l2_format format; int ret; format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get v4l2_overlay format"); if (ret) return ret; get_window(&format, x, y, w, h); return 0; }
int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha) { LOG_FUNCTION_NAME int ret; struct v4l2_framebuffer fbuf; struct v4l2_format fmt; memset(&fbuf, 0, sizeof(fbuf)); ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get transparency enables"); if (ret) return ret; if (enable) fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; else fbuf.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha"); if (ret) return ret; if (enable) { memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get global alpha"); if (ret) return ret; fmt.fmt.win.global_alpha = alpha & 0xFF; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set global alpha"); } return ret; }
int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf) { LOG_FUNCTION_NAME memset(buf, 0, sizeof(struct v4l2_buffer)); buf->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; buf->memory = V4L2_MEMORY_MMAP; buf->index = index; LOGV("query buffer, mem=%u type=%u index=%u\n", buf->memory, buf->type, buf->index); return v4l2_overlay_ioctl(fd, VIDIOC_QUERYBUF, buf, "querybuf ioctl"); }
int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w, uint32_t *h) { LOG_FUNCTION_NAME struct v4l2_crop crop; int ret; crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop"); *x = crop.c.left; *y = crop.c.top; *w = crop.c.width; *h = crop.c.height; return ret; }
/***************************************************************************** * uninit ****************************************************************************/ static void uninit(void) { struct atmel_priv_t *priv = &atmel_priv; uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT; int i; printf("vo_atmel: uninit() was called\n"); v4l2_overlay_ioctl(priv->v4l2_fd, VIDIOC_STREAMOFF, &type, "stream off"); for (i = 0 ; i < BUF_NBR ; i++) { if (atmel_priv.len[i] > 0) munmap(atmel_priv.buf[i], atmel_priv.len[i]); } close(priv->v4l2_fd); priv->v4l2_fd = -1; }
int v4l2_overlay_get_input_size_and_format(int fd, uint32_t *w, uint32_t *h, uint32_t *fmt) { LOG_FUNCTION_NAME struct v4l2_format format; int ret; format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format"); *w = format.fmt.pix.width; *h = format.fmt.pix.height; if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) *fmt = OVERLAY_FORMAT_YCbYCr_422_I; else return -EINVAL; return ret; }
/***************************************************************************** * config * * Config the display driver. * params: * src_width,srcheight: image source size * dst_width,dst_height: size of the requested window size, just a hint * fullscreen: flag, 0=windowd 1=fullscreen, just a hint * title: window title, if available * format: fourcc of pixel format * returns : zero on successful initialization, non-zero on error. * ****************************************************************************/ static int config(uint32_t src_width, uint32_t src_height, uint32_t dst_width, uint32_t dst_height, uint32_t flags, char *title, uint32_t fmt) { int ret; int i; int fd = atmel_priv.v4l2_fd; struct v4l2_format format; struct v4l2_requestbuffers reqbuf; struct v4l2_buffer buf; void *start; uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if(fmt != V4L2_PIX_FMT_YUV420) { printf("vo_atmel: unsupported fourcc for this driver\n"); return -1; } atmel_priv.src_width = src_width; atmel_priv.src_height = src_height; atmel_priv.dst_width = dst_width; atmel_priv.dst_height = dst_height; memset(&format, 0x00, sizeof (struct v4l2_format)); format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format"); if (ret) return ret; printf("vo_atmel: config() G_FMT (init) w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height); format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; format.fmt.pix.pixelformat = fmt; format.fmt.pix.width = src_width; format.fmt.pix.height = src_height; printf("vo_atmel: config() S_FMT w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height); ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set output format"); if (ret) return ret; format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get output format"); printf("vo_atmel: config() G_FMT w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height); if (ret) return ret; format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get v4l2_overlay format"); printf("v4l2_overlay_get_position:: w=%d h=%d\n", format.fmt.win.w.width, format.fmt.win.w.height); if (ret) return ret; format.fmt.win.w.left = 200; format.fmt.win.w.top = 10; format.fmt.win.w.width = dst_width; format.fmt.win.w.height = dst_height; format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set v4l2_overlay format"); printf("v4l2_overlay_set_position:: w=%d h=%d\n", format.fmt.win.w.width, format.fmt.win.w.height); if (ret) return ret; reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; reqbuf.memory = V4L2_MEMORY_MMAP; reqbuf.count = BUF_NBR; printf("v4l2_overlay_request_buffer, requested=%u\n", reqbuf.count); ret = v4l2_overlay_ioctl(fd, VIDIOC_REQBUFS, &reqbuf, "requets v4l2 buffers"); printf("v4l2_overlay_request_buffer, result: requested=%u return=%u\n", reqbuf.count, ret); if (ret) return ret; for (i = 0 ; i < BUF_NBR ; i++) { memset(&buf, '\0', sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; ret = v4l2_overlay_ioctl(fd, VIDIOC_QUERYBUF, &buf, "querybuf ioctl"); printf("v4l2_overlay_query_buffer, length=%u offset=%u\n", buf.length, buf.m.offset); if (ret) return ret; if (buf.flags == V4L2_BUF_FLAG_MAPPED) { printf("Trying to mmap buffers that are already mapped!\n"); return -EINVAL; } printf("mmap, length=%u offset=%u\n", buf.length, buf.m.offset); start = (void*) mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (start == 0) { printf("map failed, length=%u offset=%u\n", buf.length, buf.m.offset); return -EINVAL; } atmel_priv.len[i] = buf.length; atmel_priv.buf[i] = start; /* Temporary fill the buffer with nothing */ memset(atmel_priv.buf[i], '\0', atmel_priv.len[i]); ret = v4l2_overlay_ioctl(fd, VIDIOC_QBUF, &buf, "qbuf"); if (ret) return ret; printf("buffer %d queued\n", i); } ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMON, &type, "stream on"); if(ret) { printf("Stream on failed\n"); return ret; } return 0; }