037、海思HI3516的VI/VPSS/VENC全链路适配——从sensor接入到编码输出的ISP参数映射
037、海思HI3516的VI/VPSS/VENC全链路适配——从sensor接入到编码输出的ISP参数映射
上周在客户现场调一块HI3516EV300的板子,sensor是SC2239,输出1080p25。客户反馈画面偏色,而且暗部噪点像下雪。我第一反应是ISP参数没映射对,结果一查代码,发现他们直接在VI通道上改了sensor的曝光寄存器,VPSS那边完全没动。这问题太典型了——海思平台最坑的地方就是VI、VPSS、VENC三层各有各的参数域,你以为改的是全局,其实只改了某一层的局部。
先理清楚HI3516的链路结构。VI负责把sensor的RAW数据收进来,做基本的坏点校正、黑电平、镜头阴影校正,然后输出给VPSS。VPSS才是真正的ISP主战场,3DNR、2DNR、锐化、对比度、饱和度全在这里。VENC只管编码,但编码器的码率控制会反过来影响VPSS的帧率,进而影响ISP的曝光策略。这三层是串行依赖关系,任何一层的参数映射错了,画面表现就是错的。
我见过太多人直接在VI层调ISP参数,因为海思的sample代码里VI层确实暴露了ISP相关的结构体。但VI层的ISP寄存器映射是给sensor RAW数据做预处理用的,不是给最终图像做美化用的。你在VI层把对比度拉高,VPSS层再做一次对比度增强,画面直接过曝。正确的做法是:VI层只做sensor数据的基础校正,VPSS层做画质调整,VENC层做码率控制。
具体到参数映射,我拿一个实际调试案例说。SC2239输出的是10bit RAW,接入VI后,VI的ISP模块会做黑电平校正。这里有个坑——SC2239的黑电平是64,但海思的VI默认黑电平是128。如果你不把VI的ISP黑电平参数改成64,暗部细节全被吃掉,画面发灰。这个参数在VI的ISP结构体里叫black_level,直接赋值就行。但注意,这个值跟sensor的寄存器值不是一回事,sensor寄存器里可能存的是偏移量,VI里存的是绝对值,中间要换算。
VPSS层的参数映射更复杂。VPSS有多个通道,每个通道可以独立设置3DNR强度、锐化强度、色度增益。但VPSS的通道0是给VENC用的,通道1是给编码预览用的,通道2是给抓拍用的。如果你在通道0上把3DNR开到最大,通道1的预览画面就会跟编码画面不一致。我建议的做法是:通道0和通道1共用一套参数,通道2单独设置,这样预览和编码一致,抓拍可以单独调。
3DNR的参数映射有个经验值。HI3516的3DNR强度范围是0到255,但实际有效范围是0到200。超过200,运动物体的拖影会非常明显。我一般把3DNR设在120到150之间,配合2DNR的30到50,暗部噪点能压住,运动物体也不糊。但这里有个前提——sensor的增益不能太高。如果sensor的ISO已经拉到1600以上,3DNR再强也救不回来,反而会把细节磨平。所以VPSS的3DNR参数要跟sensor的增益做联动,这个联动逻辑要写在应用层,不能写在ISP驱动里。
VENC层的参数映射容易被忽略。VENC的码率控制会影响VPSS的输出帧率,帧率波动会影响ISP的自动曝光收敛速度。我遇到过一个问题:客户把VENC的码率设成2Mbps,1080p25,结果画面在暗光下疯狂闪烁。查了半天,发现是码率太低,编码器丢帧,VPSS的帧率从25掉到15,ISP的曝光算法以为场景变暗了,拼命拉高增益,画面就闪了。解决办法是把码率提到4Mbps,或者开启VENC的智能码率控制,让编码器在暗光下自动降帧率而不是丢帧。
还有一个映射关系是sensor的曝光时间跟VPSS的帧率。HI3516的VI层支持sensor的曝光时间设置,但曝光时间不能超过一帧的周期。如果你在VI层把曝光时间设成40ms,但VPSS的帧率是30fps(帧周期33ms),那曝光时间会被截断,画面亮度不均匀。这个映射关系要在应用层做校验,曝光时间必须小于等于1000/帧率。
最后说一个容易踩的坑——sensor的镜像和翻转。SC2239支持水平镜像和垂直翻转,但这两个操作会影响ISP的坏点校正和镜头阴影校正的方向。如果你在VI层开了镜像,但VPSS的ISP参数还是按原始方向设置的,画面边缘会出现色偏。解决办法是:sensor的镜像翻转必须在VI层设置,同时VPSS的ISP参数要跟着做相应的方向映射。海思的ISP结构体里有mirror和flip字段,但这两个字段只影响ISP内部的坐标计算,不影响输出图像的方向。输出图像的方向由VI层的sensor配置决定。
经验性建议:调试HI3516的链路,先固定VENC的码率和帧率,再调VPSS的画质参数,最后调VI的sensor参数。顺序反了,你会被参数之间的耦合关系搞疯。另外,海思的ISP参数不是改完就生效的,很多参数需要重新初始化ISP才能生效,或者至少需要触发一次ISP的reload。我习惯在调试代码里加一个调试命令,可以单独reload ISP参数,不用重启整个链路。
还有一点,HI3516的ISP参数映射不是线性的。比如锐化强度,0到255不是均匀变化的,0到50几乎没效果,50到100变化明显,100到150开始出现振铃,150以上画面就假了。所以调参的时候,不要用二分法,要先用大跨度找到有效范围,再在小范围内细调。这个经验适用于所有海思平台的ISP参数。
最后提醒一句,别迷信海思的ISP tuning工具。工具导出的参数是给参考板用的,你的板子layout、sensor型号、镜头模组都跟参考板不一样,参数必须重新调。工具只能帮你快速定位问题,不能直接生成量产参数。
