Wouldn't it be nice to store your favorite options in a configuration file once and for all? Yes it would and yes you can!
Finding the ffmpeg / x264 preset files
Just head for the ffmpeg source and look at the ffpresets directory:
ubuntu% cd ffmpeg/ffpresets
ubuntu% ls
libx264-default.ffpreset libx264-hq.ffpreset libx264-normal.ffpreset
libx264-fastfirstpass.ffpreset libx264-max.ffpreset
Nice. Let's copy these to your ffmpeg configuration directory:
ubuntu% mkdir ~/.ffmpeg
ubuntu% cp *.ffpreset ~/.ffmpeg
A (terrifying) look at a preset file
What do you find in a preset file? Well, a long list of ffmpeg flags related to H.264 encoding:
ubuntu% cat libx264-normal.ffpreset
coder=1
flags=+loop
cmp=+chroma
partitions=+parti8x8+parti4x4+partp8x8+partb8x8
me_method=hex
subq=6
me_range=16
g=250
keyint_min=25
sc_threshold=40
i_qfactor=0.71
b_strategy=1
qcomp=0.6
qmin=10
qmax=51
qdiff=4
bf=16
refs=2
directpred=3
trellis=0
flags2=+bpyramid+wpred+dct8x8+fastpskip
Ouch! Welcome to the wonderful world of H.264 encoding ;)
Keep in mind that these are ffmpeg flags (not x264 flags), so although they really are meant to configure the x264 encoding process, they differ from the actual flags that you would pass directly to the x264 encoder. To ease the pain of translating and understanding these flags, you will certainly need:
- this mapping guide written by one of the ffmpeg developers,
- this detailed list of x264 flags, and I guess this guide too,
- the doom9 forum on H.264.
Using a preset file
So how do you use a preset file? Just set the '-vpre' flag after the '-vcodec' flag (the flag order does matter):
ubuntu% ffmpeg -i video.mpg -vcodec libx264 -vpre normal video.mp4
Alternatively, you can set it to the full path to the preset file (useful if you don't want to keep them in ~/.ffmpeg)
ubuntu% ffmpeg -i video.mpg -vcodec libx264 -vpre ~/myPresets/libx264-normal.ffpreset video.mp4
Easy, isn't it?
Now let's look at the different preset files and run some tests. Here, I will encode a 3-minute MPEG video to H.264 using each of the available presets.
Audio encoding is disabled ('-an') and we let ffmpeg decide how many threads to run ('-threads 0').
'Default quality' preset file
ubuntu% ffmpeg -i video.mpg -f mp4
-vcodec libx264
-vpre default -an -threads 0 video.mp4
--> 39 seconds, 4.68 Mb
As the name implies, settings are default values and generate a video compliant with the 'Main' H.264 profile. If you need to encode to the 'Baseline' profile, you just need to change 'coder=1' to 'coder=0' in the preset file: this will disable CABAC entropy coding, which is only supported in the 'Main' profile and upwards.
'Normal quality' preset file
ubuntu% ffmpeg -i video.mpg -f mp4
-vcodec libx264
-vpre normal -an -threads 0 video.mp4
--> 43 seconds, 4.67 Mb
These settings bring a little bit more quality and generate a video compliant with the 'High' H.264 profile. The key flags is 'dct8x8', which is only supported in the 'High' profile and upwards: removing it will drop back to the 'Main' profile.
I would recommend this preset for everyday use.
'High quality' preset file
ubuntu% ffmpeg -i video.mpg -f mp4
-vcodec libx264
-vpre hq -an -threads 0 video.mp4
--> 1 minute 26 seconds, 4.71 Mb
These settings bring a even more quality, notably a more accurate motion estimation method (umh) and trellis quantization. The output video is compliant with the 'High' H.264 profile.
Encoding time is 2x longer compared to the 'Normal quality' preset. Let your eyes decide if there's a notable improvement :)
'Maximum quality' preset file
ubuntu% ffmpeg -i video.mpg -f mp4
-vcodec libx264
-vpre max -an -threads 0 video.mp4
--> 15 minutes 4 seconds, 4.72 Mb
These settings bring a lot more quality, thanks to generous B-frames settings, a very efficient (but very slow) motion estimation method (tesa) and more trellis quantization. The output video is compliant with the 'High' H.264 profile.
Still, encoding time is 10x longer compared to the 'High quality' preset. Not sure it's really worth it...
That's it for today. We barely scratched the surface and there's much more to be said on H.264, but hopefully this will get you started :)
=================
Updated on 2009/01/19: a while new bunch of lossless & iPod presets have surfaced!
libx264-baseline.ffpreset
libx264-default.ffpreset
libx264-fastfirstpass.ffpreset
libx264-hq.ffpreset
libx264-ipod320.ffpreset
libx264-ipod640.ffpreset
libx264-lossless_fast.ffpreset
libx264-lossless_max.ffpreset
libx264-lossless_medium.ffpreset
libx264-lossless_slower.ffpreset
libx264-lossless_slow.ffpreset
libx264-lossless_ultrafast.ffpreset
libx264-main.ffpreset
libx264-max.ffpreset
libx264-normal.ffpreset
libx264-slowfirstpass.ffpreset
Hello there,
ReplyDeleteI stumbled across your blog and then found this page. I am the author of the x264 presets in FFmpeg. Your usage isn't quite right.
I will add an installation target to the FFmpeg Makefile at some point.
If you have copied the preset files into ~/.ffmpeg/ or they have been installed to ${prefix}/share/ffmpeg/ then you only need to use the specific preset name.
The first bit of the preset file name is the vcodec, acodec or so. The second bit is the specific preset name. For example - libx264-hq.ffpreset can be used as follows:
ffmpeg -i infile -vcodec libx264 -vpre hq outfile.mp4
We will probably add a lot more speed/quality tradeoff presets soon to cater to more people's tastes and patience. :)
Please note that I document this stuff on my website, so you can check there for significant updates: http://rob.opendot.cl/
Hi Robert,
ReplyDeletethanks for the info, I'll update the post.
I also found out that -vcodec must be specified before -vpre, or else the preset file isn't found...
Cheers!
HI Robert,
ReplyDeletehow can we set the preset by using ffmpeg api and not by cli?
This comment has been removed by a blog administrator.
ReplyDelete