ffmpegvideo-encodingx264libx264

ffmpeg libx264 encoder different machines different output


I'm new to development with ffmpeg and I was wondering if it is possible to get the same bit exact output by running ffmpeg with the libx264 encoder on different machines (compiled using different compilers) with the same input file and same configuration options?

If it is possible, are there additional configuration options that need to be set when compiling libx264/ffmpeg? If it is not possible, why?

Below is the output from my running two versions off ffmpeg with libx264 that yield different MD5 hashes of the outputs.

ffmpeg installed via homebrew on OSX

ffmpeg version 3.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 9.0.0 (clang-900.0.38)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.4 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --disable-lzma --enable-nonfree

ffmpeg on Alpine Linux (in a Docker container based on https://github.com/jrottenberg/ffmpeg/blob/master/docker-images/3.4/alpine/Dockerfile)

ffmpeg version 3.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.2.1 (Alpine 6.2.1) 20160822
  configuration: --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --disable-lzma --enable-nonfree --prefix=/opt/ffmpeg

Test run with ffmpeg on OSX

ffmpeg -i seg.ts -c:v libx264 -s 1280x720 -minrate 6000k -maxrate 6000k -bufsize 6000k -r 60 -threads 1 -f md5 -

Output

MD5=b7c84c0bae5da6749e389a5b69d88582

Test run with ffmpeg on Alpine Linux (in a Docker container based on https://github.com/jrottenberg/ffmpeg/blob/master/docker-images/3.4/alpine/Dockerfile)

docker run --rm -v /code/:/tmp/workdir -w=/tmp/workdir ffmpeg -i seg.ts -c:v libx264 -s 1280x720 -minrate 6000k -maxrate 6000k -bufsize 6000k -r 60 -threads 1 -f md5 -

Output

MD5=c46af8fbdbbb2bfbb9f7042ab28accfc


Solution

  • If you use different builds of libx264 on different CPUs nobody can guarantee you bit identical output. With same libx264 build on different CPUs (different instruction set extensions support) you also can get different output but can try to fix it by using --cpu-independent param (for ffmpeg through -x264-params) during encoding (on both).

    As for why it can be not possible with different libx264 builds is because different compilers can generate different float-math code which will differ in rounding errors (use x87 or sse) and so nothing is guaranteed. You can try to minimize probability by disabling AQ, MBTree or using CQP ratecontrol but that is all.

    UPDATE. Also don't forget about using same threads number on different CPUs instead of auto.