项目记录:GPU硬解码渲染
程序员文章站
2022-07-14 18:18:28
...
项目需求
全景视频超大分辨率Zoom-in/out点播系统
单帧解码渲染版本:通过头盔位置判断是否要更换码流进行渲染,实现放大缩小效果。
- 传统的渲染方式是:
将硬解码得到的NV12数据拷贝回CPU内存,
然后再将NV12格式转成YUV420格式,
进而再调用OpenGL渲染。
解码渲染耗时较大,卡顿,需要解决
方案
采用NVIDIA VIDEO CODEC SDK对输入8K码流进行硬解码,
使用CUDA与OpenGL互操作,
无需将数据传入CPU,将硬解码取得的NV12数据通过CUDA转成RGBA。
再进行渲染。直接用OpenGL渲染显示。
相关知识
CUDA与OpenGL互操作
OpenGL与CUDA互操作可以分成两种:
OpenGL将Buffer对象注册到CUDA中去,供CUDA读写操作,然后再在OpenGL中使用。一般这种情况**册的是VBO和PBO,VBO一般用于存储顶点坐标、索引等数据;PBO则一般用于存储图像数据,因此称作Pixel Buffer Object。
OpenGL将Texture对象注册到CUDA中去,经CUDA处理后得到纹理内容,然后在OpenGL中渲染出来。
二者的操作流程一致:
1. 在OpenGL里面初始化Buffer Object
2. 在CUDA中注册OpenGL中的Buffer Object
3. CUDA锁定资源,获取操作资源的指针,在CUDA核函数中进行处理
4. CUDA释放资源,在OpenGL中使用Buffer Object
OpenGL多线程context问题
- 将OpenGL的Texture注册到CUDA中,需要处于正确的GL环境,
- 而解码线程和主线程不共享同一个OpenGL Context。
- OpenGL Context在一个时刻只能被一个线程所拥有
NV12转RGBA
- 参考文档:
https://www.cnblogs.com/riddick/p/7724877.html
https://blog.csdn.net/evankaka/article/details/38176025
具体实现
项目使用GL渲染方式是绘制顶点,贴纹理图。
所以采用GPU渲染纹理图。
GPU设置纹理图:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// 传入参数NULL
// CUDA支持的纹理格式每个元素1或2或4个通道,所以使用GL_RGBA
实现效果:
上一篇: FFmpeg intel GPU解码加速
下一篇: 二维码