写在之前
耗时2个月,写完公司的音视频处理系统。对于整个音视频处理有了基本的了解。个人感觉最坑的地方有三:
- 编解码
- 音视频录制的同步
- 视频预览渲染(视频帧的渲染)
由于在以后要支持同时多路1080P录制及预览,所以对于性能的要求也是非常高的。虽然目前实现是分两步走,先录制再处理,但如果能做到一步到位就非常好了。有空再去优化整个项目。
渲染
选择API
对于视频的渲染来说,已经去世的雷博给了一个DEMO。其中包含了OPENGL/DIRECT3D9/GDI等不同的实现方式,也给了我很大的帮助。
必须要说的是,我个人喜欢用新不用旧。故在第一版的demo实现之后,便想摒弃D3D9的实现方式了。毕竟他是一个十几年前的API了,且WIN10系统已经不包含d3dx9这个组件了。在选择实现的方式上,通过各方资料来看。有这么一些选择:
- D3D11 —D3D11貌似是现有很多商业视频播放器必须包含的组件了。但D3D11在WIN10系统上的编译还是需要从原来的SDK中拷贝过来的头文件和库,不爽!= =
- D3D12 —D3D12是微软最新的库,而且是Win10 only,十分符合我的价值观嘻嘻嘻。但由于多线程及性能上的考虑,整个API设计的非常底层。原有的很多便利的接口已经没有了,原来很多显卡驱动做的事情也必须交由程序员自己去控制。学习成本我感觉是很高, 对于没有学习过图形API的人来说。然而我还是最终选择了他去实现。
- D2D —D2D是微软在最近几个Direct版本中,独立出来用于2D开发的一套API(貌似用于替换原有的DirectShow)。其底层还是使用D3D进行硬件加速。而且API风格与D3D很像,并可以和D3D、MF等组件方便的沟通。第二版程序便是用此实现。相对于D3D12来说,的确在绘制视频帧上有很大的方便。
- MMF —Microsoft Media Foundation是微软最新的音视频处理体系,在知乎上看轮子哥说非常强大,看官方的Demo的确非常好用,但是由于学习成本和我的职业规划路线,并没有选择这个API。(其实应该选用此的。。。)
所以最终,我们选择了D3D12来实现,本文会将第二版D2D实现一起给出。
D3D12 RGBA渲染
我们本文关注的重点为如何将获取到的RGBA数据或YUV数据以较低的开销渲染到屏幕上。
整个程序的UI是用QT5.8来画的,所以对于创建窗口来说也是非常简单。直接一个QWidget就解决问题了。直接利用Qt中的时间来驱动整个流程。
D3D12的初始化是比较麻烦的,借鉴了微软的官方例程D3D12HelloTexture(