FFmpeg x264 Encoding Reference


Video settings
-c:v libx264 -crf 18 -pix_fmt yuv444p -profile:v high444 -level 5.1 -coder 1 -partitions +parti8x8+parti4x4+partp8x8+partb8x8 -x264opts me=umh:subme=8:merange=16:bframes=12:b-adapt=1:b-bias=0:b-pyramid=normal:weightb=1:ref=12:mixed-refs=1:psy=1:psy-rd=1.00=0.00:fast_pskip=1:deblock=0=-1:trellis=2:keyint=240

Audio settings
-c:a libvorbis -aq 8 OR
-c:a libfdk_aac -b:a 576k -afterburner 1

Ffmpeg extra args
-map_chapters -1 -map_metadata -1 -disposition:a:0 default -metadata:s:a:0 language=eng -threads 0 -f mp4 -y $outputfile

HDR / Colorspaces
-pix_fmt yuv444p10le -x264opts colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:fullrange=off #HDR
#fullrange/color_range must match source (Full(PC)=on / Limited(TV)=off)
-color_primaries smpte170m -color_trc smpte170m -colorspace smpte170m -color_range tv #BT601
-color_primaries bt709 -color_trc bt709 -colorspace bt709 -color_range tv #BT709
#Tone mapping HDR > SDR
-vf zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,
tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p

Common Filters

Audio Normalization
#loudnorm equilizes based on volumes through the whole track
#by default loudnorm upsamples the audio rate, so you need to explicitly state it. Usually the same as input
-af loudnorm=i=-22 -ar 48000
#dynaudnorm processes faster but equalizes based only on the volumes near the current mark
#setting the target volume with the volume filter is optional
-af dynaudnorm=f=1500:g=41,volume=-13

Scaling
-vf scale=iw/2:ih/2:flags=bicubic+full_chroma_inp:sws_dither=none
#this will half the height and width

Deinterlace
-vf yadif
#if deinterlacing and denoising, make sure to run yadif first
-vf yadif,hqdn3d

Checkerboard interlace two images
#Images must be same size. Or you can apply padding to one
-i img1.jpg -i img2.jpg -filter_complex "[0:V:0][1:V:0]interleave,tinterlace=4,transpose=1[a];[0:V:0][1:V:0]interleave,tinterlace=5,transpose=1[b];[a][b]interleave,tinterlace=4,transpose=2[c]" -map "[c]"

Concat AV Segments
-filter_complex "[0:V]trim=duration=60[va];[0:V]trim=start=120:end=180,setpts=PTS-STARTPTS[vb];[0:a]atrim=duration=60[aa];[0:a]atrim=start=120:end=180,asetpts=PTS-STARTPTS[ab];[va][vb]concat[fv];[aa][ab]concat=v=0:a=1[fa]" -map "[fv]" -map "[fa]"
#Make a video out of only the 1st and 3rd minutes of an input file

Inverse Telecine (IVTC)
#remove a hard 2:3 / 3:2 Pulldown. Turn 30fps to 24fps CFR
#for CFR input:
-vf fieldmatch=mode=pc_n_ub:combmatch=full:combpel=70,yadif=deint=1,decimate
#for VFR input:
-vf dejudder,fps=30000/1001,fieldmatch=mode=pc_n_ub:combmatch=full:combpel=70,yadif=deint=1,decimate
#for VFR/CFR input and 30fps output (preferred):
-vf fieldmatch=mode=pc_n_ub:combmatch=full:combpel=70,yadif=deint=1

Crop Detect
ffmpeg -i "$1" -ss 120 -vsync vfr -vf fps=1/2,cropdetect -f null - 2>&1 | awk '/crop/ { print $NF }' | tr ' ' '\n' | sort | uniq -c | sort -n
#Testing just a few frames can give you the wrong crop window. This tests the whole video and sorts all answer variations by prevalence

Denoise
-vf hqdn3d=3
#The default value of hqdn3d is 4. Going above that degrades quality significantly
-x264opts nr=250 #faster and less destructive/effective. not temporal (0-1000)

Generate Thumbnails
#This specifically selects frames after a scene cut, that are at least 300 sec apart, until it makes 16 thumbnails
ffmpeg -ss 90 -i "$1" -vf "select=gt(scene\,0.5)*isnan(prev_selected_t)+gte(t-prev_selected_t\,300),scale=480:270:force_original_aspect_ratio=decrease" -frames:v 16 -vsync vfr -q:v 2 -y thumb-%03d.jpg
#Make a 2x4 collage of thumbs
ffmpeg -ss 90 -i "$1" -vf "select=gt(scene\,0.5)*isnan(prev_selected_t)+gte(t-prev_selected_t\,600),scale=480:270:force_original_aspect_ratio=decrease,tile=2x4" -frames:v 1 -vsync vfr -q:v 2 -y thumb-collage.jpg
#For even temporal spacing, get the video duration:
ffprobe -v 0 -show_entries format=duration -of compact=p=0:nk=1 "$1"
#divide by the number of thumbs you want, and set the fps filter to the inverse
ffmpeg -i "$1" -map 0:V -vsync vfr -vf fps=1/300 thumb%03d.png

#Or get total frames instead of seconds
ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 file.mp4 #MP4
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 file.mkv #MKV
mediainfo --Output="Video;%FrameCount%" file.mkv #MKV
(num of thumbs wanted / total frames) * framerate = new framerate
ffmpeg -i "$1" -map 0:V -vsync vfr -vf fps=1/300 thumb%03d.png

Codec Support Check
ffmpeg -h
ffmpeg -[formats/(de)muxers/codecs/en(de)coders/filters/pix_fmts/sample_fmts]
ffmpeg -h encoder=libx264

Example 1
#The overlay filter is to hardcode subtitle track 16: English, only while non-English is spoken
ffmpeg -i The.Avengers.BluRay.mkv -filter_complex "[0:V][0:16]overlay" -ar 48000 -ac 6 -af loudnorm=i=-22 -c:a libfdk_aac -b:a 480k -afterburner 1 -c:v libx264 -crf 18 -pix_fmt yuv444p -profile:v high444 -level 5.1 -coder 1 -partitions +parti8x8+parti4x4+partp8x8+partb8x8 -x264opts me=umh:subme=8:merange=16:bframes=16:b-adapt=1:b-bias=0:b-pyramid=normal:weightb=1:ref=10:mixed-refs=1:psy=1:psy-rd=1.00=0.00:fast_pskip=1:deblock=0=0:trellis=2:keyint=240 -disposition:a:0 default -metadata:s:a:0 language=eng -sn -map_chapters -1 -map_metadata -1 -threads 0 -f mp4 The\ Avengers.mp4

Example 2
#Futurama S01 DVDs w/ 2:3 Pulldown. English audio + commentary. Note: the video track is marked english w/ metadata otherwise it would need to be mapped separately
ffmpeg -i "$1" -map 0:m:language:eng -pix_fmt yuv444p -vf dejudder,fps=30000/1001,fieldmatch=combmatch=full,yadif=deint=1,decimate,crop=704:480:10:0 -c:v libx264 -crf 16 -profile:v high444 -level 5.1 -coder 1 -partitions +parti8x8+parti4x4+partp8x8+partb8x8 -x264opts me=hex:subme=8:merange=16:bframes=16:b-adapt=1:b-bias=0:b-pyramid=normal:weightb=1:ref=14:mixed-refs=1:no-dct-decimate:psy=1:nr=100:psy-rd=1.00=0.00:fast_pskip=1:deblock=0=-1:trellis=2:keyint=240 -c:a libvorbis -q:a:0 9 -q:a:1 7 -sn -disposition:v:0 0 -disposition:a:0 default -metadata:s:a language=eng -metadata:s:a:1 title=Commentary -map_chapters -1 -map_metadata -1 -threads 0 -f matroska "$1.mkv"