Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFmpeg is using more threads than I expect when using -threads

Tags:

ffmpeg

The number of actual threads used by FFmpeg do not line up with the number I pass using the -threads argument.

I've run tests on both my MacBook Air, which has 4 cores, and a VM I have which has 2 cores. The number of threads used are consistent across both machines.

Using a single thread returns what I would expect: 1 thread is used.

$ 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

If I set the -threads option on the input, it increase the number of threads used to 3. This somewhat makes sense to me since the input would use 2 threads and the output would use a single thread.

$ 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

This is where I start to get confused. If instead, I leave the input -threads at 1 and set the output -threads to 2, it uses 8 threads (not 3 like I would expect).

$ 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

If I add a second output with -threads 1, it does not increase the number of threads used.

$ 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

However, if the second output also specifies two threads, the thread count jumps to 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

Every incremental bump beyond -threads 2 will use an additional 3 threads (e.g. threads 2 uses 8, threads 3 uses 11, threads 4 uses 14.

So it seems like anytime you use -threads 2 the formula is something like:

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

Ultimately my question is why do the number of actual threads used wildly differ from the options I'm specifying.

Thanks.

like image 282
Tom Peters Avatar asked Dec 06 '16 23:12

Tom Peters


1 Answers

Short answer - these options don't exactly do that you think.

Long answer follows:

FFmpeg always has one main thread which does most of the processing. In case of multiple inputs there are also input threads for demuxing (1 thread per input); for single input demuxing is done on main thread.

Setting "threads N" (where N > 1) on input enables multithreaded decoding which can spawn N additional threads for each decoder which supports it. In your case video decoder supports it and audio decoder doesn't so it is 3 threads - 1 main thread + 2 threads for video decoding.

Similarly, setting "threads N" on output enables multithreaded filtering and encoding which can spawn N additional threads for each filtergraph (I think in older ffmpeg versions this was "up to N threads per each filter") and each encoder which supports it. There is also one important caveat - this only applies to encoders which do their thread management via ffmpeg; libx264 doesn't do that - it forwards requested thread count to the x264 library which does its own thread management. x264 then might create up to 2*N threads (exact number depends on many encoding parameters). So for "threads 2" with single output you'll get 1 main thread + 2 threads for the scaler + at least 2 threads for libx264. This still doesn't add up to num_outputs * (1 + num_threads) behaviour you are seeing and I'd be interested to learn where additional threads come from but hopefully my answer explains why "threads 2" option doesn't increase thread count by 2.

like image 81
Andrey Turkin Avatar answered Oct 22 '22 07:10

Andrey Turkin