1. 说明
由于项目性能优化需求需要将原来的虚拟相机进行性能优化,包括CPU和内存使用率,根据之前的实现方式使用ffmpeg将视频资源解码YUYV数据写入V4l2loopback驱动,系统framework从驱动读取对应数据传递给APP。
2. 需求说明
数据传递流程 videoFile -> ffmpeg -> 解码YUYV 然后进行旋转裁剪 -> v4l
系统framework 从 v4l读取数据,转换RGB 然后传递给APP。
这中间有多次对视频数据的拷贝以及转换,次过程消耗了大量的CPU与内存。为此需要减少拷贝或这使用硬件加速。
3. 实现方式
由于设备使用的是rockchip 硬件,支持DMA/RGA,由此联想到让ffmpeg解码视频直接输出DMA ,然后直接将DMA fd写入v4l ,v4l 将写入的fd 转换成dmabuf,当framework从v4l读取数据时v4l将dmabuf映射一个dma fd再传递给framework,framework获取到该fd后可直接使用RGA进行硬件加速裁剪旋转等操作。此过程对比之前少了多次原始视频数据的拷贝,对原始视频数据的转换也用上了硬件加速,经过测试CPU使用率从之前的40%降到了4%,极大的提升了性能,内存使用从之前的7%将到了0.1%。
可惜官方v4l2loopback 并不支持dma,故此需要对驱动进行扩展。
官方地址:https://github.com/v4l2loopback/v4l2loopback
扩展DMA后的地址:https://github.com/LucasDevelop/V4l2loopback_dma
该扩展是基于官方v0.12.7版本,如需兼容最新官方版本请自行移植。具体扩展的代码可以与官方代码进行对比,这里也不再描述。具体原理如前面所说,支持v4l传入dmafd然后转换dmabuf 再输出dmafd.
注意:官方版本的ffmpeg是不支持直接输出dma 数据的,需要使用rockchip提供的ffmpeg,这个不是本博客的重点,不深入。