[原创]突破NVIDIA NVENC并发Session数目限制
使用NVIDIA显卡GPU进行视频编码时,如果同时进行多路转码,在某些显卡上会报错: Out of Memory,一般就是调用nvEncOpenEncodeSessionEx函数出错,返回的错误码是10(NV_ENC_ERR_OUT_OF_MEMORY),NVENC并发的Session数目超过了限制,具体信息可以去官网查一下。
Video Encode and Decode GPU Support Matrix
2020-10-28更新到版本456.71
很奇怪NVIDIA会做如此的限制,因为并不是GPU能力不够。就我的电脑来说,NVIDIA显卡型号是GeForce GTX 1650,NVENC的并发最大数目是2,为了查找在哪里进行了限制,我写了如下代码:
cuInit(0);
CUdevice cuDevice = 0;
cuDeviceGet(&cuDevice, 0);
CUcontext cuContext = NULL;
cuCtxCreate(&cuContext, CU_CTX_SCHED_BLOCKING_SYNC, cuDevice);
NV_ENCODE_API_FUNCTION_LIST nvenc = { NV_ENCODE_API_FUNCTION_LIST_VER };
NVENCSTATUS nvStatus = NvEncodeAPICreateInstance(&nvenc);
NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS encodeSessionExParams = {
NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER };
encodeSessionExParams.device = cuContext;
encodeSessionExParams.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
encodeSessionExParams.apiVersion = NVENCAPI_VERSION;
printf("OpenEncodeSesionEx #1\n");
void *hEncoder1 = NULL;
nvStatus = nvenc.nvEncOpenEncodeSessionEx(&encodeSessionExParams, &hEncoder1);
printf("OpenEncodeSesionEx #2\n");
void *hEncoder2 = NULL;
nvStatus = nvenc.nvEncOpenEncodeSessionEx(&encodeSessionExParams, &hEncoder2);
printf("OpenEncodeSesionEx #3\n");
void *hEncoder3 = NULL;
nvStatus = nvenc.nvEncOpenEncodeSessionEx(&encodeSessionExParams, &hEncoder3);
最后在Open第3个Session时返回了NV_ENC_ERR_OUT_OF_MEMORY,之后我使用x64dbg对代码进行了跟踪调试,原来限制的模块并不是在驱动层,而是在应用层,动态库文件是nvcuvid.dll,汇编代码大概如下:
.text:00000001800E7FAF FF 90+ call qword ptr [rax+90h] ; 调用这个函数检查数目是否超过限制
.text:00000001800E7FB5 84 C0 test al, al
.text:00000001800E7FB7 74 08 jz short loc_1800E7FC1
.text:00000001800E7FB9 C6 43+ mov byte ptr [rbx+38h], 1
.text:00000001800E7FBD 33 C0 xor eax, eax
.text:00000001800E7FBF EB 05 jmp short loc_1800E7FC6
.text:00000001800E7FC1 loc_1800E7FC1:
.text:00000001800E7FC1 B8 0A+ mov eax, 0Ah ; 超过限制就设置返回值为10
找到了位置,然后就简单了,只需要把jz short loc_1800E7FC1 这个判断跳转nop掉即可
.text:00000001800E7FAF FF 90+ call qword ptr [rax+90h]
.text:00000001800E7FB5 84 C0 test al, al
.text:00000001800E7FB7 90 nop ;这里nop掉之后,就不会跳转到loc_1800E7FC1
.text:00000001800E7FB8 90 nop
.text:00000001800E7FB9 C6 43+ mov byte ptr [rbx+38h], 1
.text:00000001800E7FBD 33 C0 xor eax, eax
.text:00000001800E7FBF EB 05 jmp short loc_1800E7FC6
.text:00000001800E7FC1 loc_1800E7FC1:
.text:00000001800E7FC1 B8 0A+ mov eax, 0Ah
汇编修改之后对nvcuvid.dll打patch,替换掉系统目录下的文件,然后再运行测试程序,开十几路同时编码也没问题了,没限制的感觉太香了!哈哈...
通过一些版本的测试,发现完全是可以使用特征码来制作补丁,而且目前特征码是唯一的,因此就不需要反编译分析代码位置。
特征码:84 C0 74 08 C6 43 38 01 33 C0
修改为:84 C0 90 90 C6 43 38 01 33 C0
第二组特征码,只需要改动1个字节(Studio)
特征码:01 FF 90 B0 00 00 00 84 C0 74 08 C6 43 38 01 33
修改为:00 FF 90 B0 00 00 00 84 C0 74 08 C6 43 38 01 33
版本496.13之后(Game Ready)
特征码:B2 01 FF 90 C0 00 00 00 84 C0
修改为:B2 00 FF 90 C0 00 00 00 84 C0
使用二进制工具可以非常简单的快速破解不同的版本,Enjoy!
2020-01-02更新版本441.66的补丁: 下载
2020-04-07更新版本442.19的补丁: 下载
2020-07-28更新版本451.77的补丁: 下载
2020-09-23更新版本451.82的补丁: 下载
2020-10-28更新版本456.71的补丁: 下载
《乡里人家》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/34898.html
《最强神赐》国产动漫高清在线免费观看:https://www.jgz518.com/xingkong/130300.html
《奸杀犯》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/107392.html
兄弟写的非常好 https://www.cscnn.com/
怎么收藏这篇文章?
叼茂SEO.bfbikes.com
这里有个开源项目干了一样的事。
https://github.com/keylase/nvidia-patch
btw,楼主是否注意到,nvenc一开,显存就会至少增加120MB?就是调用nvEncOpenEncodeSessionEx这个api时候。而且每路视频都会至少120M左右的显存消耗,因此开多路的话,显存消耗很大(我的场景需要开二十多路,而且每路后面还有200M左右的图形渲染显存开销)。有什么解决方法没?有知道的欢迎联系:tyxxyhm@hotmail.com,感谢。
20220905最新版本驱动修改好的,和修改软件打包下载(自解压文件)此补丁对应的驱动版本是516.94
STUDIO
「NVDIA-ENCODE线程破解.exe」https://www.aliyundrive.com/s/uzfzvgZet4X 提取码: fi65
点击链接保存,或者复制本段内容,打开「阿里云盘」APP
请问新版本驱动可以更新一下破解补丁吗?2022年3月了
nv编码不支持交叉场吗
请问这个nvcuid.dll能下载吗,谢谢?
大神
同求Ubuntu的libnvcuvid.so
谢谢分享!!!!
我在ubuntu上尝试了好几次还是不行,求ubuntu上修改方法或者帮我改个so的版本可以吗,能邮件发我联系方式吗
同问,有ubuntu修改教程吗,或者ubuntu能用的包
我也遇到这个问题了,可以发给我一个打上patch后的nvcuvid.dll吗?十分感谢
有没有linux下的补丁?跪求
请问您现在搞定了吗
我在做视频硬编码时候也遇到这个问题了,跪求
我可以帮你弄。我的弄好了。
大佬能帮忙弄一个496.76的吗……
请问怎么弄的,我的显卡驱动版本是471.68.
能否发一个打上patch后的nvcuvid.dll给我,非常感谢。
大神求发一个打上patch后的nvcuvid.dll,万分感谢。
我需要支持2080ti的最新显卡驱动的 nvcuvid.dll