我从摄像头获取到的单帧数据是YUV格式的, 系统里也移植了opencv3.4, 尝试了将获取到的YUV数据进行如下转换:
YUV数据->opencv的Mat格式数据->Mat格式的RGB数据->Qt的QImage->Qt的Qpixmap
这样最终视频是可以刷出来, 可是这其中经历了大量的浮点运算, 刷出来的视频像幻灯片一样。统计了一下时间, 光YUV转opencv的RGB Mat这一步就用了270ms左右。
我们厂商给的示例代码是直接将YUV格式的数据通过Linux的drm框架刷出来的, 效率非常高, 毫无延迟现象。 但我们的应用要基于Qt构建。 如何能在Qt中, 将视频通过drm框架直接刷出来呢?
在Qt中不可以直接调用Drm接口直接显示视图。Drm是Linux下Qt底层渲染视图的接口。 Qt上层显示视图就两种方法:
QWidget->Drm->Dri->/dev/dri/card0
QGLWidget->EGL->Drm->Dri->/dev/dri/card0
两者的区别是, 通过QWidget显示视图完全通过CPU运算, 而QGLWidget显示视图会用到GPU进行运算。
我使用opencv将YUV转RGB耗时原因是, 1. 交叉编译开发板上的opencv时没有加
WITH_OPENGL
选项, 导致所有的转换操作都是在CPU下完成的, 没有用到GPU。2. 数据源的问题, 图像是直接从摄像头硬件地址中读取到的, 转换操作一直使用的都是这个地址。 把图像数据保存成本地文件, 通过循环读取的方式, 可以看到使用opencv转换数据速度很快, YUYV转RGB耗时约12ms左右。综上,最终的解决方案就是:1.重新编译opencv, 2.摄像头数据memcpy到内存中再做转换运算