Ghosts in the Machine: Debugging FFmpeg’s Libvpx Encoder (Season 1, Episode 11)
ffmpeg -i input.mov -c:v libvpx-vp9 \ -tile-columns 2 -row-mt 1 \ -lag-in-frames 16 \ # Reduce from default 25 -auto-alt-ref 1 \ # Keep on, but be careful -arnr-maxframes 3 \ # Reduce temporal filtering -cpu-used 2 \ output.webm Two-pass encoding often masks the bug because the first pass forces the encoder to re-evaluate scene boundaries more strictly. ghosts s01e11 libvpx
ffmpeg -i input.mov -c:v libvpx-vp9 -b:v 0 -crf 18 -pass 1 -f null /dev/null ffmpeg -i input.mov -c:v libvpx-vp9 -b:v 0 -crf 18 -pass 2 output.webm Libvpx is a phenomenal encoder—it often beats x265 at half the bitrate for animated or grainy content. But it is also a complex state machine. Ghosting artifacts are a reminder that "lossy" doesn't just mean losing detail; sometimes, it means gaining things that were never there. Ghosts in the Machine: Debugging FFmpeg’s Libvpx Encoder
ffmpeg -i master.mov -c:v libvpx-vp9 -pix_fmt yuv420p10le -crf 18 -b:v 0 output.webm The first pass looked incredible. Grain was preserved. Banding was minimal. But during playback on a high-refresh-rate display, we noticed it: . Ghosting artifacts are a reminder that "lossy" doesn't