这部分spec的内容没有全看懂,但是根据FSL的代码能知道这其中的sequence,下面就结合着FSL的代码来描述下video overlay过程的sequence。 

首先介绍一下video overlay,vieo overlay不同于video capture,是指不需要对video信号的帧进行copy,直接将视频信号转化成显卡的VGA信号或者将捕获到的视频帧直接存放在显卡的内存中,具体过程就是将视频帧直接写入framebuffer中,不需要经过android 平台的处理。实际上看过FSL的camera preview过程之后就知道,它就是直接将视频数据 写入framebuffer,而没有经过android的surfaceflinger的处理。Video overlay需要硬件的支持,必须是支持video
overlay的camera才能使用这套overlay interface。 

因为video overlay直接使用linux 的framebuffer来显示捕获到的image,所以和capture相比它更具有效率,而不是将捕获到的image拷贝以后通过其他的方式(android surfaceflinger)来显示。Viedo overlay只用来preview,又被称为framebuffer overlay或previwing。 

从spec上来看,实际上video capture interface也能实现preview,只是没有overlay有效率,因为video capture是将数据经过copy以后由android surfaceflinger来控制进行显示(实际上最后surfaceflinger还是通过framebuffer来显示的)。 

Video overlay和Video capture使用同样的device,overlay的功能只有在调用VIDIOC_S_FMT后才会有效。下面就看看overlay流程的sequcence。 

1、open device 

这部分同video capture,首先是要打开设备。如果是同时进行overlay和capture,应该尽量不使用同一个文件 描述符,比如说如果此时在overlay,要拍照的话应该再打开设备,使用一个分开的文件描述符来进行capture。如果driver支持同时进行overlay和capture的话,必须支持使用分开的文件描述符来分别进行overlay和capture 。

?
camera_device = open(VIDEO_DEVICE, O_RDWR)) ;

2、set output 

对于这个设置 输出不是太理解,但overlay换个角度来说是将捕获的image重新组合成能在屏幕上显示的视频信号,在这里的设置输出应该是如果device有多个输出的话,选择一个输出来将数据输入到屏幕,也就是framebuffer。

?
ioctl(camera_device, VIDIOC_S_OUTPUT, &g_display_lcd) ;

3、set control[可选] 

设置用户控制参数,FSL在这里使用了他们驱动自定义的控制参数,不是很理解这个参数设置是想实现什么操作,我觉得这个应该是可选的。 

ioctl(camera_device, VIDIOC_S_CTRL, &ctl) ; 

4、set crop 

这个同video capture是一样的,只是type由V4L2_BUF_TYPE_VIDEO_CAPTURE换成了V4L2_BUF_TYPE_VIDEO_OVERLAY,然后是取景参数的设置:left,top,width,height。

?
ioctl(camera_device, VIDIOC_S_CROP, &crop) ;

5、set format 

这个format应该是最后preview我们在屏幕上看到的image的格式,如果在video capture中,这个就是我们拍照时image的格式。

?
ioctl(camera_device, VIDIOC_S_FMT, fmt) ;

6、 get video std 

这个我觉得肯定是可选的,取得当前视频标准

?
ioctl(camera_device, VIDIOC_G_STD, &id) ;

7、set stream param 

设置流参数,这个和video capture是相同的,这里的param.type是V4L2_BUF_TYPE_VIDEO_CAPTURE,其中timeperframe的分母是需要设定的帧率,而分子是1。

?
ioctl(camera_device, VIDIOC_S_PARM, &parm) ;

  

[PS]这里补充一点stream param方面的spec: 

一般来说当前的帧率是由当前的视频标准来决定的,如果默认采用视频标准的帧率就不需要设置流参数,但是如果想获得或者设定自己的帧率就需要使用VIDIOC_G_PARM, VIDIOC_S_PARM:

?
int ioctl(int fd, int request, v4l2_streamparm *argp);

  

struct v4l2_stramparam包含以下主要成员:

enum v4l2_buf_type type union param struct v4l2_captureparm
capture struct v4l2_outputparam output

//要注意的是在这里,不管是overaly还是capture,这里的buffer type都是选择的V4L2_BUF_TYPE_VIDEO_CAPTURE。 

Struct v4l2_captureparam包含以下主要成员: 

__u32 capturemode 

//是否支持高质量图像捕捉 

struct v4l2_fract timeperframe 

//设置帧率,通过分母分子实现 

这里要注意的是,通过 VIDIOC_S_PARM设置帧率不一定成功,driver会根据硬件限制来设置这些参数,所以一般设置以后可以通过VIDIOC_G_PARM来看设定是否成功。 

前面从1-8都是设置overlay的参数,然后需要设置framebuufer的参数,framebuffer参数部分的设置通过VIDIOC_G_FBUF,VIDIOC_S_FBUF来实现,这里的参数也是比较复杂,具体可以去参照这个spec:http://v4l2spec.byte***.org/spec/r10595.htm 

我看FSL的代码,它也是采用了默认的framebuffer的参数,唯一的就是改变了一下flag: 

ioctl(camera_device, VIDIOC_G_FBUF, &fb_v4l2) ; 

fb_v4l2.flags = V4L2_FBUF_FLAG_OVERLAY; 

ioctl(camera_device, VIDIOC_S_FBUF, &fb_v4l2) ; 

在设置framebubffer参数之前,FSL打开了framebuffer设备,并对屏幕进行了一系列的配置,因为overlay状态下是直接写屏,所以它这里加入了对framebuffer设备的配置工作。 

完成这一系列的配置以后通过调用overlay即开始了overlay过程,在这里overlay的数为0时为关闭overlay,为1时为打开overlay。 

ioctl(camera_device, VIDIOC_OVERLAY, &overlay) ; 

实际上看FSL的preview代码,虽然也加入了线程的概念,但线程内没有作什么实际性的内容,在preview线程起来之前,overlay实际上已经开始了。个人觉得这个preview线程是一个多余的操作。而且它也没有用到android内部的memory,因此在overlay preview的启动过程中对initHeapLocked()的调用也完全是多余的,没有进行实质性的操作。由此可见FSL code完全就是通过linux和v4l2来实现了camera preview的功能,甚至连previewcallback都省去了。
FSL camera take picture with v4l2 

首先说明一下可能是因为FSL 的camera 不支持autofocus ,所以它没有实现对autofocus 的支持,autofucus 线程直接调用了callback ,没有进行操作。 

FSL 对拍照提供了一套它自己的jpeg 编码,获得的数据可以进行jpeg 编码,也可以直接将捕获的raw data 以call back 返回。Take picture 是建立在preview 的基础 上的,实际上就是将preview 中捕获的某个image 保存下来。在FSL code 中是在overlay 的基础上,重新打开设备,在新的文件描述符上设置take picture 相关的参数,从设备中读到数据以后,再将参数还原到overlay 的状态。下面我们看看take picture 的sequence
: 

1 、shutter callback 

因为拍照是通过快门事件激发的,所以首先会调用mShutterCallback ; 

2 、open device 

打开一个新的文件描述符来进行take picture 的操作 

3 、set format 

设置capture 的image format ,可以看看它对参数的设置:

?
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.pixelformat = g_still_pixelformat;
fmt.fmt.pix.width = g_width;
fmt.fmt.pix.height = g_height;
fmt.fmt.pix.sizeimage = fmt.fmt.pix.width * fmt.fmt.pix.height * g_still_bpp / 8;
fmt.fmt.pix.bytesperline = g_width * g_still_bpp / 8; //其中bpp 是每个像素所占有的比特位


ioctl(fd_v4l, VIDIOC_S_FMT, &fmt) ;

  

4 、set crop 

同样可以看看设置的crop parameter :

crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c.left = 0;
crop.c.top = 0; crop.c.width = g_width; crop.c.height = g_height;
ioctl(fd_v4l, VIDIOC_S_CROP, &crop);

5 、set stream paramter

parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm.parm.capture.timeperframe.numerator = 1;
parm.parm.capture.timeperframe.denominator =g_still_camera_framerate; parm.parm.capture.capturemode = g_capture_mode; ioctl(fd_v4l, VIDIOC_S_PARM, &parm)

6 、read image data 

read(camera_device, buf1, fmt.fmt.pix.sizeimage) ; 

这里存在一点疑问,这个camera_device 中的数据是从何而来的,根据v4l2 协议 就是当前overlay 到的数据么? 

7 、将数据直接以rawcallback 返回或者压缩成jpeg 返回。

【Qt开发】 V4L2_CAP_VIDEO_OVERLAY与V4L2_CAP_VIDEO_CAPTURE的区别的更多相关文章

  1. QT QTransform与QMatrix 有啥区别?

    刚开始学习QT,我使用的是QT5.12进行开发,要不时地查阅QT的官方帮助文档~ 仔细阅读QT官方帮助QTransform类以及QMatrix类,发现两个类的作用描述一模一样(“The QTransf ...

  2. windows下VisualStudio和QtCreator搭建Qt开发环境

    一.简介 集成开发平台IDE都有各自的长处,编写Qt程序可根据自己的喜好来选择相应的IDE.下述文章都是装载博友的文章,其中有很多细节还得自己调整. 二.详解 1.VisualStudio搭建Qt开发 ...

  3. 【Qt开发】【ARM-Linux开发】 QT在ARM上显示字体的问题

    在PC机上利用QT开发的应用程序在设置字体时,在PC上运行,可根据自己的设置,字体随之变大或变小.而移植到ARM上运行时发现,显示字体与所设置的字体不用,字体普遍偏小.经过上网搜索发现,是环境变量字库 ...

  4. 【Qt开发】关于Qt应用程序中的堆栈、静态存储区的使用错误

    [Qt开发]关于Qt应用程序中的堆栈.静态存储区的使用错误 标签:[Qt开发] 最近终于又碰到了这个问题,想在main函数中定义一个局部大的数组,结果运行就报错,尼玛!刚开始真的不知道到发生了什么,后 ...

  5. # ios开发 @property 和 Ivar 的区别

    ios开发 @property 和 Ivar 的区别 @property 属性其实是对成员变量的一种封装.我们先大概这样理解: @property = Ivar + setter + getter I ...

  6. win使用MSYS2安装Qt开发环境

    原文链接 MSYS2 下载地址: pacman的具体用法 有pacman的具体使用方法.我们首先对系统升级 我们首先对系统升级 pacman -Syu 就会检测整个系统可以升级的组件,并自动下载安装, ...

  7. 细数Qt开发的各种坑(欢迎围观)

    1:Qt的版本多到你数都数不清,多到你开始怀疑人生.从4.6开始到5.8,从MSVC编译器到MINGW编译器,从32位到64位,从Windows到Linux到MAC.MSVC版本还必须安装对应的VS2 ...

  8. 用Qt开发第一个Hello World程序

    配置好Qt的环境变量之后,我们才可以进行下面的通过终端来使用Qt开发这个第一个程序 因为Qt的文件路径不能有中文否则会报错,所以一般都把工程文件都建立在根目录 我们创建的Qt程序包含两个部分:1.GU ...

  9. [BS-17] iOS开发-Alpha,Hidden和Opaque区别

    iOS开发-Alpha,Hidden和Opaque区别   UIView控件都有Alpha,Hidden和Opaque这三个常见属性,UIView控件BackgroundColor是用RGBA表示的, ...

随机推荐

  1. Java基本的程序结构设计 大数操作

    大数操作 BigInteger 不可变的任意精度的整数.所有操作中,都以二进制补码形式表示 BigInteger(如 Java 的基本整数类型).BigInteger 提供所有 Java 的基本整数操 ...

  2. DevExpress Windows 10 v19.1新版亮点:UWP控件新功能全面解析

    行业领先的.NET界面控件DevExpress 日前正式发布v19.1版本,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WPF v19.1中新增的一些控件及部 ...

  3. k-means伪代码

    1.初始化k个簇中心. 2.更新所有样本点簇归属:样本点到哪个簇中心点最近就属于哪个簇. 3.重新计算每个簇的中心点(直到簇中心点不再变化或达到更新最大次数) #k-means伪代码 import n ...

  4. 在centos7.5使用DockerFile构建镜像时报错“Error parsing reference: "microsoft/dotnet:2.2-aspnetcore-runtime AS base" is not a valid repository/tag: invalid reference format”

    运行dockerfile时报出的错误 FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base Error parsing reference: &qu ...

  5. wordpress在线预览pdf插件

    插件名称:PDF.js Viewer Shortcode 插件主页:http://tphsfalconer.com/ 优点:功能强大,有分页缩略图功能,翻页,放大缩小,打印,下载,读取等功能. 使用方 ...

  6. jvm——CodeCache

    https://juejin.im/post/5c890f21f265da2d993dc692 CodeCache是热点代码的暂存区,经过即时编译器编译的代码会放在这里,它存在于堆外内存.除了JIT编 ...

  7. 使用tensorflow训练word2vec

    from http://blog.csdn.net/wangyangzhizhou/article/details/77530479?locationNum=1&fps=1 使用了tensor ...

  8. 对TypeScript进行研究

    1.npm install -g typescript 在编辑器,将下面的代码输入到greeter.ts文件里: function greeter(person) { return "Hel ...

  9. 微信点餐系统(七)-微信授权获取openid:

    章节小结: 1.学会了微信授权的步骤,学会了微信授权的文档 2.学会了使用natapp内网穿透工具 3.加深了虚拟机的网络配置以及基本使用 4.学会了抓包购票工具fiddler的使用 5.微信授权步骤 ...

  10. 【BZOJ3931】[CQOI2015]网络吞吐量

    Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择 ...