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

时间:2016-12-06 23:17:45

标签: 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

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

$ 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

这是我开始感到困惑的地方。相反,如果我将输入-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

如果我使用-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

但是,如果第二个输出也指定了两个线程,则线程计数跳转到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

-threads 2以外的每次增量收益都将使用额外的3个主题(例如threads 2使用8个,threads 3使用11个,threads 4使用14个。

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

1 + [ (1 + (3 * output_n_threads)) + ... ]

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

感谢。

1 个答案:

答案 0 :(得分:7)

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

长答案如下:

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

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

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