Overlay技术跟帧缓存技术都可以用于显示。Overlay在驱动层是v4l2架构。
在android中,overlay用于视频播放,canera视频预览。Overlay没有给java层提供接口,仅仅供中间件部分调用。为了使用overlay,必须自己编写调用overlay的接口。
Overlay的输入是视频流,至于具体是什么格式,大小,都要通过下面的接口设置。
struct v4l2_format format;
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
ret = ioctl(fd, VIDIOC_G_FMT, &format, "get format");
if (ret)
return ret;
LOGI("v4l2_overlay_reinit:: w=%d h=%d\n",format.fmt.pix.width, format.fmt.pix.height);
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
LOGI("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width,format.fmt.pix.height);
ret = ioctl(fd, VIDIOC_S_FMT, &format, "set outputformat");
通过这种方法,就可以设置overlay的输入源,格式是(比如:OVERLAY_FORMAT_CbYCrY_420_I),width (比如:720),heigjt(比如:480)。
有时候,并不需要把所有的输入图像数据都显示出来,我们只需要把部分图像数据显示,可以通过下面的设置:
struct v4l2_crop crop;
int ret;
crop.type =V4L2_BUF_TYPE_VIDEO_OUTPUT;
ret = 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;
ioctl(fd,VIDIOC_S_CROP, &crop, "set crop");
这样就可以:比如 把上面的720*480 的一个矩形(x, y , w, h)显示到显示设备上。
Overlay的输出是显示设备,显示设备都有一个分辨率,比如是800*480,但是大多数的情况下,我们并不要全屏显示,因为这样会造成图像的拉伸,使得视频看起来不自然。比如上面的例子,如果把720*480的数据在800*480的显示设备上显示,就会使得图像在水平方向拉伸,所以我们要设置图像具体在显示设备上的显示区域:
structv4l2_format format;
format.fmt.win->w.left = x;
format.fmt. win->w.top = y;
format.fmt. win->w.width = w;
format.fmt. win->w.height = h;
LOGI("v4l2_overlay_set_position::set to w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height);
format.type =V4L2_BUF_TYPE_VIDEO_OVERLAY;
ret = v4l2_overlay_ioctl(fd,VIDIOC_S_FMT, &format,
"setv4l2_overlay format");
LOGI("v4l2_overlay_set_position::new w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height);
这样就可以视频输入源的数据(被crop后的数据)在显示显示设备的(x, y,w, h)矩形区域里面显示。