We have developed an application to transcode source .mov files into .ogg, .mp4 and .webm output. It is currently running on AWS EC2 instance g2.8xlarge. It is working (yay!).
My question: Even though I am passing in -threads 0
to the ffmpeg command (actually setting ffmpeg.threads
configuration in php-ffmpeg), the running process is sometimes only being executed on a single core. Why is this happening? See below output from htop
command:
As you can see, Core #21 is maxed out. In a few seconds, it's going to switch to another one, rather than max out all of them like I would like and greatly speed up my encoding process. The situation is transient; during some runs all of the processors are maxed out, but during others they are not and we only get use of the one processor. A colleague mentioned that perhaps the codec we're using for some of the formats don't support multi-threaded execution during encoding, though I can't verify that is the behavior I'm observing yet.
Is this the case? If so, what codecs for the formats above will allow us to transcode into these target formats while taking advantage of all of our available hardware? The default codecs set for php-ffmpeg are below;
Video Audio
Ogg libtheora libvorbis
WebM libvpx libvorbis
X264 libx264 libfaac
Update
Looking at the running processes, below is what winds up being the ffmpeg command that is run for an MP4 (currently saturating all 32 cores):
ffmpeg -y \
-i my-video.mov \
-async 1 \
-metadata:s:v:0 start_time=0 \
-async 1 \
-metadata:s:v:0 \
-async 1 \
-metadata:s:v:0 start_time=0 \
-async 1 \
-metadata:s:v:0 start_time=0 \
-s 1920x1080 \
-s 1920x1080 \
-s 1280x720 \
-threads 0 \
-vcodec libx264 \
-acodec libfaac \
-b:v 1200k \
-refs 6 \
-coder 1 \
-sc_threshold 40 \
-flags +loop \
-me_range 16 \
-subq 7 \
-i_qfactor 0.71 \
-qcomp 0.6 \
-qdiff 4 \
-trellis 1 \
-b:a 128k \
-pass 2 \
-passlogfile /tmp-ffmpeg-passes55ad0d0233f711zdrg/pass-44ad0d02340a8 \
my-video-1200.mp4
I'm not actually building this command directly, php-ffmpeg
is, though I do believe I have at least a modest amount of control over what goes in to it (for instance, I have no idea why there's multiple -metadata:s:v:0
entries at the beginning)
-s
three times, the final one with a different size). Explicitly setting a bunch of args to their current default values (e.g.-i_qfactor
,-subq
,-qcomp
) is weird, and could give bad results with future libx264. (Probably not, but only because libx264 is pretty much done, and stable, not under heavy development. If it did stuff like this for x265, that would be bad.) Anyway, 2-pass 1200k is fine, but you might prefer target-quality crf. It doesn't specify a-preset
. :(libfaac
isn't as good aslibfdk_aac
. If you're using this in a for-pay service, you'd need to check on the licensing of libfdk_aac, though. Also, this cmdline is missing-movflags +faststart
subme
levels changing, in ways that mean your cmdline hurts quality.