使用-threads时,FFmpeg使用的线程数超出了我的预期

Tom*_*ers 6 ffmpeg

FFmpeg使用的实际线程数与我使用-threads参数传递的数字不对齐.

我在我的MacBook Air(有4个内核)和一个拥有2个内核的VM上运行测试.两台机器使用的线程数一致.

使用单个线程返回我期望的内容:使用1个线程.

$ ffmpeg -threads 1 -i clip.mp4 -threads 1 -acodec libfdk_aac -vcodec libx264 -b:v 200k -vf scale=200:-2 -y clip-200.mp4

$ cat /proc/$(pgrep ffmpeg)/status | grep Threads
Threads:        1
Run Code Online (Sandbox Code Playgroud)

如果我-threads在输入上设置选项,它会增加用于3的线程数.这对我来说有点意义,因为输入将使用2个线程,输出将使用单个线程.

$ ffmpeg -threads 2 -i clip.mp4 -threads 1 -acodec libfdk_aac -vcodec libx264 -b:v 200k -vf scale=200:-2 -y clip-200.mp4

$ cat /proc/$(pgrep ffmpeg)/status | grep Threads
Threads:        3
Run Code Online (Sandbox Code Playgroud)

这是我开始感到困惑的地方.相反,我将输入保留-threads为1并将输出设置-threads为2,它使用8个线程(不像我期望的那样3个).

$ ffmpeg -threads 1 -i clip.mp4 -threads 2 -acodec libfdk_aac -vcodec libx264 -b:v 200k -vf scale=200:-2 -y clip-200.mp4

cat /proc/$(pgrep ffmpeg)/status | grep Threads
Threads:        8
Run Code Online (Sandbox Code Playgroud)

如果我添加第二个输出-threads 1,它不会增加使用的线程数.

$ ffmpeg -threads 1 -i clip.mp4 -threads 2 -acodec libfdk_aac -vcodec libx264 -b:v 200k -vf scale=200:-2 -y clip-200.mp4 \
                                -threads 1 -acodec libfdk_aac -vcodec libx264 -b:v 250k -vf scale=250:-2 -y clip-250.mp4

cat /proc/$(pgrep ffmpeg)/status | grep Threads
Threads:        8
Run Code Online (Sandbox Code Playgroud)

但是,如果第二个输出也指定了两个线程,则线程计数跳转到15.

$ ffmpeg -threads 1 -i clip.mp4 -threads 2 -acodec libfdk_aac -vcodec libx264 -b:v 200k -vf scale=200:-2 -y clip-200.mp4 \
                                -threads 2 -acodec libfdk_aac -vcodec libx264 -b:v 250k -vf scale=250:-2 -y clip-250.mp4

cat /proc/$(pgrep ffmpeg)/status | grep Threads
Threads:        15
Run Code Online (Sandbox Code Playgroud)

每增加一个增量-threads 2将使用额外的3个线程(例如threads 2使用8,threads 3使用11,threads 4使用14.

因此,似乎任何时候你使用-threads 2公式是这样的:

1 + [ (1 + (3 * output_n_threads)) + ... ]
Run Code Online (Sandbox Code Playgroud)

最后我的问题是为什么使用的实际线程数量与我指定的选项有很大不同.

谢谢.

And*_*kin 7

简短的回答 - 这些选项并不完全符合您的想法.

答案如下:

FFmpeg总是有一个主线程来完成大部分处理.在多个输入的情况下,还有用于解复用的输入线程(每个输入1个线程); 单个输入多路分解在主线程上完成.

在输入上设置"线程N"(其中N> 1)启用多线程解码,这可以为支持它的每个解码器产生N个附加线程.在你的情况下,视频解码器支持它,音频解码器不支持它,因此它是3个线程 - 1个主线程+ 2个用于视频解码的线程.

类似地,在输出上设置"线程N"可以启用多线程过滤和编码,这可以为每个过滤器图生成N个额外的线程(我认为在较旧的ffmpeg版本中,"每个过滤器最多N个线程")和支持它的每个编码器.还有一个重要的警告 - 这仅适用于通过ffmpeg进行线程管理的编码器; libx264没有这样做 - 它将请求的线程数转发给x264库,后者执行自己的线程管理.然后x264可能会创建最多2*N个线程(确切的数量取决于许多编码参数).因此,对于具有单个输出的"线程2",您将获得1个主线程+ 2个线程用于缩放器+至少2个线程用于libx264.这仍然没有加起来num_outputs * (1 + num_threads)你看到的行为,我有兴趣了解其他线程的来源,但希望我的答案解释为什么"线程2"选项不会将线程数增加2.