Nvidia NVENC 硬编码预研总结
本篇博客记录NVENC硬编码的预研过程
github: https://github.com/MarkRepo/NvencEncoder
步骤如下:
(1)环境搭建
(2)demo编译,测试,ARGB编码
(3)研究demo源码,阅读API文档
(4)封装so共享库,联调测试多路编码性能
(5)研究内存,显存拷贝方案,尝试解决CPU,GPU消耗过高等性能问题
1. 环境搭建
(1)编译环境,预研中这个环境不是我亲手搭建的,需要CUDAToolKit, NVENC SDK
(2)运行环境,需要Nvidia独立显卡,另外还要注意NVENC SDK的版本对显卡驱动版本有要求,具体在SDK的文档中会有说明。
2. demo测试
demo中提供了Makefile,只需拷贝到编译环境,编译官方SDK中的demo,测试yuv编码h264, 用VLC正确播放出来。尝试编码RGB,一开始由于缺乏对YUV和RGB的理解,导致走了不少弯路,尝试了挺久才试出来。后来预研了QSVE之后才发现NVENC的编码接口更简单,需要注意的是YUV,RGB等输入数据在缓存中要行对齐。
3.研究源码,封装so共享库
在能够正确编码rgb数据之后,设计能与SPICE服务端通信的接口,提供SO供其调用,这一步主要是研究demo源码中各个API如何调用,查看API文档的详细解说。(后面会把相关代码、文档放到github上管理)。
4.内存到显存拷贝方案。(各种方案的使用方法,不在这里细讲,参见github上的源码和相关文档)
(1)使用NVENC API分配的input buffer, 将显存指针映射成cpu指针,然后调用memcpy拷贝
(2)使用cuda的api分配的显存,然后将显存注册到NVENC,调用cuda api将内存拷贝到显存
(3)使用zero-copy, 调用cuda api分配锁页内存,映射到显存,然后注册到NVENC,往主机锁页内存写数据,当调用NVENC的编码接口时,gpu调用DMA进行数据拷贝。
三种方案总结:
NVENC显存: 占用cpu最高,主要是memcpy占用
GPU显存: 占用cpu也很高,主要CUDA api的内存拷贝
zero-copy 不占用cpu, 但是拷贝效率也不高,实际运用中体验效果不如前面两种方案。