多轨视频无法实时转码

多轨视频无法实时转码

最近,这个致力于绕过 Nvidia 编码限制的 Github 页面添加了 Windows 支持: https://github.com/keylase/nvidia-patch/tree/master/win

到目前为止,由于对消费级 Nvidia GPU 施加的编码限制,我一直在 GPU 和 CPU 上编码 5 个直播流,因此我的 GPU 上有 2 个流,我的 CPU 上有 3 个流。但借助此补丁,我现在可以仅使用 GPU 编码所有 5 个流,这让我想到 - 与编码 5 个单独的输出视频相比,也许我可以将所有流编码为 1 个文件。

由于分段的性质,创建一个使所有 5 个独立输出文件保持同步的命令非常困难。因此,我认为如果我在一个文件中完成所有操作,我就可以绕过其中的一些麻烦并简化我的工作流程/命令。但是,我发现当我尝试将所有内容放在一个输出文件中时,我无法实时转码。

示例命令:

ffmpeg -y -hide_banner -thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -video_size 3840x2160 `
-framerate 60 -pixel_format nv12 -i video="Video (Pro Capture)":audio="ADAT (3+4) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -video_size 3840x2160 -framerate 60 -pixel_format nv12 `
-i video="AVerMedia HD Capture GC573 1":audio="Analog (1+2) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -video_size 1920x1080 -framerate 60 -pixel_format yuv420p `
-i video="Game Capture HD60 Pro (Video) (#01)":audio="Game Capture HD60 Pro (Audio) (#01)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -i audio="ADAT (5+6) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -i audio="SPDIF/ADAT (1+2) (RME Fireface UC)" `
-c:v h264_nvenc -preset: llhp -pix_fmt nv12 -b:v 288M -minrate 288M -maxrate 288M -bufsize 288M -c:a aac -ar 44100 `
-b:a 384k -vsync 1 -max_muxing_queue_size 9999 -map 0 -map 1 -map 2 -map 3 -map 4 `
-f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 -segment_format_options max_delay=0 `
C:\Users\djcim\Videos\FFmpeg\FFmpeg%02d.ts

上述命令不会实时转码,速度约为 0.6 倍。但是,当我简单地将所有内容分离到多个输出时,我会实时转码:

ffmpeg -y -hide_banner `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147.48M -i audio="Analog (1+2) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147.48M -i audio="ADAT (5+6) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -r 25 -f lavfi -rtbufsize 2147.48M -i color=c=black:s=256x120 `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147.48M -video_size 1920x1080 -framerate 60 `
-pixel_format yuv420p -i video="Game Capture HD60 Pro (Video) (#01)":audio="Game Capture HD60 Pro (Audio) (#01)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147.48M -video_size 3840x2160 -framerate 60 `
-pixel_format nv12 -i video="Video (Pro Capture)":audio="ADAT (3+4) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147.48M -video_size 3840x2160 -framerate 60 `
-pixel_format nv12 -i video="AVerMedia HD Capture GC573 1":audio="Analog (1+2) (RME Fireface UC)" `
-map 2,0 -map 0 -c:v h264_nvenc -preset: llhp -r 25 -rc-lookahead 25 -pix_fmt nv12 -b:v 288M -minrate 288M `
-maxrate 288M -bufsize 288M -c:a aac -ar 44100 -b:a 384k -vsync 1 -max_muxing_queue_size 9999 `
-f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 -segment_format_options max_delay=0 `
C:\Users\djcim\Videos\FFmpeg\CP\CP%02d.ts `
-map 2,1 -map 1 -c:v h264_nvenc -preset: llhp -r 25 -rc-lookahead 25 -pix_fmt nv12 -b:v 288M -minrate 288M `
-maxrate 288M -bufsize 288M -c:a aac -ar 44100 -b:a 384k -vsync 1 -max_muxing_queue_size 9999 `
-f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 -segment_format_options max_delay=0 `
C:\Users\djcim\Videos\FFmpeg\SB\SB%02d.ts `
-map 3:0,3:1 -map 3:1 -c:v h264_nvenc -preset: llhp -r 60 -rc-lookahead 60 -pix_fmt yuv420p -b:v 288M -minrate 288M `
-maxrate 288M -bufsize 288M -c:a aac -ar 44100 -b:a 384k -vsync 1 -max_muxing_queue_size 9999 `
-f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 -segment_format_options max_delay=0 `
C:\Users\djcim\Videos\FFmpeg\EL\EL%02d.ts `
-map 4:0,4:1 -map 4:1 -c:v h264_nvenc -preset: llhp -r 60 -rc-lookahead 60 -pix_fmt nv12 -b:v 288M -minrate 288M `
-maxrate 288M -bufsize 288M -c:a aac -ar 44100 -b:a 384k -vsync 1 -max_muxing_queue_size 9999 `
-f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 -segment_format_options max_delay=0 `
C:\Users\djcim\Videos\FFmpeg\MW\MW%02d.ts `
-map 5:0,5:1 -map 5:1 -c:v h264_nvenc -preset: llhp -r 60 -rc-lookahead 60 -pix_fmt nv12 -b:v 288M -minrate 288M `
-maxrate 288M -bufsize 288M -c:a aac -ar 44100 -b:a 192k -vsync 1 -max_muxing_queue_size 9999 `
-f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 -segment_format_options max_delay=0 `
C:\Users\djcim\Videos\FFmpeg\AM\AM%02d.ts

这还没有提到上述命令是我实际使用的更简化的版本,我通常会向每个输出添加大量同步选项,但这与其实时转码能力并不相关。

你知道为什么单文件解决方案很难,而后者却很容易吗?如果可能的话,有什么解决方案吗?

答案1

这个谜题中缺失的部分是 -rc-lookahead,它以某种方式从我原始帖子的第二个命令中被省略了。

如果我向多轨文件添加 -rc-lookahead 60,它很快就会实现实时转码,例如:

ffmpeg -y -hide_banner -thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -video_size 3840x2160 `
-framerate 60 -pixel_format nv12 -i video="Video (Pro Capture)":audio="ADAT (3+4) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -video_size 3840x2160 -framerate 60 -pixel_format nv12 `
-i video="AVerMedia HD Capture GC573 1":audio="Analog (1+2) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -video_size 1920x1080 -framerate 60 -pixel_format yuv420p `
-i video="Game Capture HD60 Pro (Video) (#01)":audio="Game Capture HD60 Pro (Audio) (#01)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -i audio="ADAT (5+6) (RME Fireface UC)" `
-thread_queue_size 9999 -indexmem 9999 -f dshow -rtbufsize 2147M -i audio="SPDIF/ADAT (1+2) (RME Fireface UC)" `
-c:v h264_nvenc -preset: llhp -pix_fmt nv12 -rc-lookahead 60 -b:v 288M -minrate 288M -maxrate 288M -bufsize 288M -c:a aac `
-ar 44100 -b:a 384k -vsync 1 -max_muxing_queue_size 9999 -map 0 -map 1 -map 2 -map 3 -map 4 `
-f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 -segment_format_options max_delay=0 `
C:\Users\djcim\Videos\FFmpeg\FFmpeg%02d.ts

相关内容