Camera(Rockchip Linux)
-
date_range 01/10/2017 info
rockchip-isp1
先看这里,了解下驱动和硬件。 http://opensource.rock-chips.com/wiki_Rockchip-isp1
Linux使用
这套驱动把很多原来被kernel包装住的细节暴露给了用户层,这样一来,应用层怎么使用就是个问题。
我们最先开发的是Android CamHal3。对CamHal3来说,这种按照规范暴露出的细节其实很方便开发者(看看我们CamHal3到处都是intel的header就知道了…)。 对使用者来说,使用方式也不会有差异,细节都在xml里被隐藏了。
然后回到Linux,用的是rkcamsrc(类似的nvidia有nvcamerasrc,intel有xcamsrc)。
一开始我是打算写成类似CamHal的做法—-就是使用者不用关心硬件细节,不用操作media controller,不用手动设置各个模块的format—-只需要通过下request,确定拍照还是录像还是预览,分辨率要多大—但后面发现这样的话,如果要做的完整,不损失功能,需要的工作量太大了。另外有很多奇奇怪怪的sensor,比如说HDMI IN,这么写的话,要怎么满足他的需求?
抽象这些太麻烦了。所以在Linux使用的话,还是得User自己去根据实际硬件和基础软件,操作media controller,设置pad format,配置sensor,来满足自己想要的需求。
怎么把3A用起来?
首先最好是用gstreamer,按照readme,设置3a-mode和xml path既可。tuning xml需要找rockchip获取。
但是如果你想把3A加到普通的v4l2程序里,也可以。因为我在写给rkcamsrc加3a支持的时候,用了trick的办法,让这部分的代码和rkcamsrc独立出来。
但没有例程,需要自行理解。
https://github.com/rockchip-linux/gstreamer-rockchip-extra/tree/master/gst/rkv4l2/rkcamsrc/rkisp1
拍照程序怎么写
拍照的话理论上取一个buffer就行,但实际上还有等3a收敛,不然第一个buffer的图像质量比较差。所以一般都是一边预览,跑3a,然后再拍照的。 这里要注意拍照的话需要获取3a结果,来确定是不是效果已经收敛。
拍照的分辨率:
假设拍照要求1080p,那么sensor设置一个接近的最大的分辨率。以ov5695来说,他没有1080p,最近的是2592x1944。
如果直接sensor 2592x1944输出,mainpath 1920x1080输出,那么比例会不对,因为sensor输出是4:3, 而后者是是16:9。
所以还需要设置crop,来裁剪掉sensor的输出。
预览+拍照怎么做
预览的输出一般由selfpath给出,因为selfpath支持旋转,镜像,但输出分辨率较低。 拍照一般由mainpath给出,因为mainpath的输出分辨率大,而且支持输出raw格式。
其实对于一般Linux的应用来说,不必太计较两者同时工作,可以直接mainpath工作,拍照直接从stream里取一帧数据即可。
但是如果你比较计较速度,还有资源占用(比如显示的分辨率太大,占用了GPU的资源),那么就需要两个stream同时工作。 gstreamer先开一个selfpath的pipeline用做预览,当需要拍照的时候,再create一个mainpath的pipline,输出raw到文件或者jpeg压缩,用完销毁。
双path的pipeline example可以看usr/local/bin下的test_camera-dual测试脚本。
录像怎么做
gstreamer上source接mpph264enc即可。
如果要和预览不同的分辨率(其实没必要),也是要使用到双path。
如果是单path,也要注意3a收敛的问题,前几个buffer可以跳过不要。
复杂的sensor(HDMI-IN)
HDMI-IN的subdev驱动有很多他自己的事件,比如说插入检测,分辨率改变,EDID,AUDIO等等。这种场景,需要另外在应用加代码去获取这些事件,同时做出 必要的反应。
Tips
sensor
调试sensor的技巧:
第一步是在rkisp1_mipi_isr里加中断, 确认mipi phy的信号有出来. mipi phy有信号, 可以验证以下事情: mipi phy/controler可以接收输入, sensor信号有了输出. 反之如果没有, 原因也就是这个两个, 可以用下面的命令来验证.
io -4 -l 0x100 0xff911c00(rk3288)
出来的数据, 第2个部分代表mipi status, 多输入几次, 看看有没有变化, bit 8:11代表data lane0-3的stop state, bit12代表clock lane stop state. 如果有所的stop bit没变, 需要检查sensor是不是正确输出了, 如果只是clock lane, 需要看下sensor的clock lane是不是在s_stream前没在lp11模式.
第二步, 如果mipi_isr有中断了, 但是有sync_error的错误, 表示mipi接收的图像和isp配置的信息不一致, 可以有以下原因: mipi接收的图形大小和isp配置的不一致, mipi接收的信号有问题.
第一个原因,检查下是不是sensor配置了1080p输出, 但是设置的软件size确是720p.
第二个原因,检查下是不是bitrate设置的有问题, lane num设置的有问题, 硬件信号有问题.
预览出现条纹
Horizontal and Vertical Banding Noise
Fixed-pattern noise
请检查AVDD,根据实际情况并联电容
about 3A
对没有商业支持的客户来说,用内置的ISP跑3A是用不起来的。因为每一种批次的模组,都需要经过tuning,得到参数才能用,而这个tuning是需要排队的。 所以你只能把他当成一个bypass的mipi-csi host,使用自带isp的sensor模组。
See also
http://www.360doc.com/content/16/1019/17/496343_599664458.shtml