usb摄像头数据格式默认识别是NV12格式无法使用调试过程

操作系统 : linux + 安卓5.1
操作平台:RK3288/RK3128

新的usb摄像头数据格式默认识别是NV12,不能使用,调试过程

方法:抓logcat日志。
usb摄像头数据格式默认识别是NV12格式无法使用调试过程_第1张图片
从logcat日志中分析,发现新的摄像头支持4中格式MJPG,YUYV,H264,NV12,默认为NV12格式;旧的摄像头支持三种格式MJPG,YUYV,H264,默认MJPG;而rk写的usb camera安卓模块(位置:rk3288_5.1\swh5184_mid\hardware\rockchip\camera\CameraHal\CameraAdapter.cpp中的cameraCreate函数)中只支持MJPG,YUYV,所以旧的摄像头可用,而新的不可用。
第一种方法:
强制使新的摄像头使用MJPG模式,新的可用(…..CameraHal\CameraAdapter.cpp中的cameraCreate函数)。
第二种方法:
觉得新摄像头的NV12格式也应该支持,追代码发现(位置:rk3288_5.1\swh5184_mid\hardware\rockchip\camera\CameraHal\CameraUSBAdapter.cpp中的reprocessFrame函数)当摄像头为MJPG和YUYV格式,rk把MJPG和YUYV转成NV12,而摄像头为NV12格式时,居然直接返回错误了。修复RK此处错误,增加了NV12格式的支持。增加NV12格式后,不需要将新摄像头的NV12格式转为MJPG格式,也可以正常使用了,且摄像头频率更高。
增加部分的cameraFormatConvert函数的作用:就是将源vir_addr的内容,即width * hight,的3/2倍的数据复制到目标getbuffVirAddr中,最后再将getbuffVirAddr数据赋值给vir_addr。问题1:为何将vir_addr的内容扩展1.5倍?
usb摄像头数据格式默认识别是NV12格式无法使用调试过程_第2张图片
如下图所示,红框内为增加的内容:
usb摄像头数据格式默认识别是NV12格式无法使用调试过程_第3张图片
测试rk3288平台下,旧摄像头的相机拍摄视频的帧率为25fps。新的摄像头的相机拍摄视频的帧率为29.8fps

问题1:为何将vir_addr的内容扩展1.5倍?
YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。
usb摄像头数据格式默认识别是NV12格式无法使用调试过程_第4张图片
先记住下面这段话,以后提取每个像素的YUV分量会用到。
1.YUV 4:4:4采样,每一个Y对应一组UV分量。
2.YUV 4:2:2采样,每两个Y共用一组UV分量。
3.YUV 4:2:0采样,每四个Y共用一组UV分量。

NV12和NV21属于YUV420格式,是一种two-plane模式,即Y和UV分为两个Plane,但是UV(CbCr)为交错存储,而不是分为三个plane。其提取方式与上一种类似,即Y’00、Y’01、Y’10、Y’11共用Cr00、Cb00
YUV420 planar数据, 以720×488大小图象YUV420 planar为例,
其存储格式是: 共大小为(720×480×3>>1)字节,
分为三个部分:Y,U和V
Y分量: (720×480)个字节
U(Cb)分量:(720×480>>2)个字节
V(Cr)分量:(720×480>>2)个字节
所以YUV420 数据在内存中的长度是 width * hight * 3 / 2,

问题2:为何要将将源vir_addr的内容,即width * hight,数据复制到目标getbuffVirAddr中,最后再将getbuffVirAddr数据赋值给vir_addr?
因为摄像头采集到的数据是直接扔进源vir_addr的,当不复制时,摄像头一直向源vir_addr里存放数据,而我的程序一直在读取处理源vir_addr里的数据,这样搞,当摄像头快速移动时,相机预览界面就会发现图像花屏,(因为上一帧数据没有处理完,摄像头就将下一帧数据扔进源vir_addr中了)

问题3:前置摄像头改后置摄像头
usb摄像头数据格式默认识别是NV12格式无法使用调试过程_第5张图片
usb摄像头数据格式默认识别是NV12格式无法使用调试过程_第6张图片

你可能感兴趣的:(其它)