
前提:在 windows/linux 上,使用同样一个 ffmpeg 静态编译的可执行文件,对同样一个 h264 编码的 mp4 文件解码,解码命令如下: (1) .\ffmpeg.exe -hwaccel cuda -i E:\tmp\1080p_60_10M.mp4 -f null - 解码帧率为 fps=780 (2) .\ffmpeg.exe -i E:\tmp\1080p_60_10M.mp4 -f null - 解码帧率为 fps=1617
(1) 解结果:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:\tmp\1080p_60_10M.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.3.100 Duration: 00:01:36.67, start: 0.000000, bitrate: 10533 kb/s Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 10528 kb/s, 60 fps, 60 tbr, 15360 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.3.100 libx264 Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native)) Press [q] to stop, [?] for help Output #0, null, to 'pipe:': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.22.101 Stream #0:0(und): Video: wrapped_avframe, nv12(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 60 fps, 60 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.40.100 wrapped_avframe [out#0/null @ 0000017e54639b80] video:2719KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown frame= 5800 fps=780 q=-0.0 Lsize=N/A time=00:01:36.66 bitrate=N/A speed= 13x
(2) 解码结果: Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:\tmp\1080p_60_10M.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.3.100 Duration: 00:01:36.67, start: 0.000000, bitrate: 10533 kb/s Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 10528 kb/s, 60 fps, 60 tbr, 15360 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.3.100 libx264 Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native)) Press [q] to stop, [?] for help Output #0, null, to 'pipe:': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.22.101 Stream #0:0(und): Video: wrapped_avframe, yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 60 fps, 60 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.40.100 wrapped_avframe [out#0/null @ 000001f2b2f29c00] video:2719KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown frame= 5800 fps=1617 q=-0.0 Lsize=N/A time=00:01:36.66 bitrate=N/A speed=26.9x
问题:指定了 -hwaccel cuda 参数进行解码的 fps 要比不指定这个参数进行解码的帧率少了一倍,自己的主机是 nvidia 显卡,这个可能是什么原因?
1 xiaoding 2024-11-18 18:40:13 +08:00 ffmpeg.exe -hwaccel cuda -hwaccel_output_format cuda -i E:\tmp\1080p_60_10M.mp4 -f null - |
2 xyzos OP @xiaoding -hwaccel_output_format cuda 加上这个参数结果也还是 700 多 fps 没啥变化 |
3 nilaoda 2024-11-18 19:45:02 +08:00 很正常,硬解需要频繁和 GPU 进行数据交换,对于 H264 这种很好解码的编码来说硬解不会比软解快,你可以尝试一些难以软解的编码再和硬解对比。 |
4 ntedshen 2024-11-18 19:57:30 +08:00 cuda 是 cuda ,nvenc 是 nvenc ,cuda 并不是硬编/解码。。。 建议直接挂 auto 。。。 |
5 ntedshen 2024-11-18 20:11:01 +08:00 不对,是我记错了。。。 NVENC and NVDEC are NVIDIA's hardware-accelerated encoding and decoding APIs. They used to be called CUVID. They can be used for encoding and decoding on Windows and Linux. FFmpeg refers to NVENC/NVDEC interconnect as CUDA. 找个片 h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 2496x832 [SAR 1:1 DAR 3:1], 13574 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default) 测试了一下 ./ffmpeg.exe -hwaccel cuda -i .\u305.mp4 -f null - 27.9x ./ffmpeg.exe -hwaccel auto -i .\u305.mp4 -f null - 26.2x ./ffmpeg.exe -i .\u305.mp4 -f null - 97x 猜测应该是不开 hwaccel 的时候 h264 直接输出了,而 nvdec 至少还运行了一下(输出是 nv12 而不是 yuv420p )。。。 |
6 yinmin 2024-11-18 20:56:08 +08:00 via iPhone 显卡视频解码是用 gpu 的 video decode 单元,这个单元普遍很弱,打不过 cpu 多核解码,intel 、amd 也都一样。 |
7 wnpllrzodiac 2024-11-18 23:10:53 +08:00 看你速度怎么统计吧。 硬盘-》内存-》显存-》内存( yuv 数据) ffmpeg 是不能直接使用 gpu 数据的。 如果在显存那步算是结束点的话,因该快一点。硬件解码的问题是兼容性不好。 输出的像素格式可能与显示的需求不一致,需要做转换。 输出的数据结构可能有 padding ,需要按照每行做操作。 解码同时的硬件单元可能老黄没给足,不一定比 cpu 快。 解码如果 dxva2 直接现存输出到显示器的话,会快很多。 总之,硬件加速远比你想象的要复杂,不是一定比用 cpu 快的。 而且老黄的卡,发力点现在明显也不再编解码上面。AI 才是赚钱的机器。 |
8 wnpllrzodiac 2024-11-18 23:13:10 +08:00 我记得以前测试下来,硬件编码要快不少,硬件解码加成不多,有时候还起反作用。 硬件编码的主要好处是降低 cpu 的开销,不然 cpu 实在撑不了几路。但是老黄也抠门,民用 gpu 的编码并发有限制,从来给不到 2+。 硬件解码+硬件编码一起用可能省点时间,因为在 gpu 里的数据可以直接用? 不确定 ffmpeg 或者老黄有没有给这样的直通 api |
9 MrKrabs 2024-11-19 00:08:57 +08:00 cpu 多核解码把硬件解码爆了很正常 功耗就差多了 |
10 zhs227 2024-11-19 00:17:48 +08:00 硬件编码性能是优势,解码未必。编码单元和解码单元一般是独立设计的,解码的设计原则是适度冗余。已经实时解了 26 路 1080P60 了算可以了 。 |
11 erquren 2024-11-19 09:20:31 +08:00 我的 5950X 解码速度比 4090 快一倍 |
12 liaohongxing 2024-11-19 10:21:39 +08:00 主要就是硬件解码的参数是固定的,有极限。留给某一格式的晶体管就那么多。 |
13 wangtian2020 2024-11-19 11:27:43 +08:00 设计硬件解码的目标是 省电 + 够用( 4k++ + 60hz++) 足够用的分辨率和帧率下可以省电的解码,它的目标已经完成了 |
15 xyzos OP @ntedshen 验证了一下,指定输出格式为 nv12 对结果也没影响 还是差距很大,应该是硬件解码速度并不是其主要优势,优势是解放 cpu 和 能耗 |
16 xyzos OP @wnpllrzodiac 确定不是 内存 io 的限制,不管是硬解还是软解 gpu decode 模块和 cpu 都是打满的状态,但是内存都基本没变化,我解码的文件也不大 只有十几 M |
17 noahhhh 2024-11-19 15:50:20 +08:00 via iPhone @wnpllrzodiac 4070 ti 就有双编码器吧 |