ffmpeg libx264编码器不同机器输出不同
ffmpeg libx264 encoder different machines different output
我是 ffmpeg 开发的新手,我想知道是否有可能通过 运行ning ffmpeg 在不同机器(使用不同编译器编译)上使用 libx264 编码器获得相同位的精确输出相同的输入文件和相同的配置选项?
如果可以的话,编译时是否需要设置额外的配置选项libx264/ffmpeg?如果不可能,为什么?
下面是我的运行使用 libx264 关闭 ffmpeg 的两个版本的输出,它们产生不同的输出 MD5 哈希值。
ffmpeg 通过自制软件安装在 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
Alpine Linux 上的 ffmpeg(在基于 https://github.com/jrottenberg/ffmpeg/blob/master/docker-images/3.4/alpine/Dockerfile 的 Docker 容器中)
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
在 OSX
上使用 ffmpeg 测试 运行
ffmpeg -i seg.ts -c:v libx264 -s 1280x720 -minrate 6000k -maxrate 6000k -bufsize 6000k -r 60 -threads 1 -f md5 -
输出
MD5=b7c84c0bae5da6749e389a5b69d88582
在 Alpine Linux 上使用 ffmpeg 测试 运行(在基于 https://github.com/jrottenberg/ffmpeg/blob/master/docker-images/3.4/alpine/Dockerfile 的 Docker 容器中)
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 -
输出
MD5=c46af8fbdbbb2bfbb9f7042ab28accfc
如果您在不同的 CPU 上使用不同版本的 libx264,没有人能保证您的输出完全相同。使用在不同 CPU 上构建的相同 libx264(不同的指令集扩展支持),您也可以获得不同的输出,但可以尝试通过在编码期间使用 --cpu-independent 参数(对于 ffmpeg 到 -x264-params)来修复它(在两者上)。
至于为什么不能使用不同的 libx264 构建是因为不同的编译器可以生成不同的浮点数学代码,这些代码在舍入误差方面会有所不同(使用 x87 或 sse),因此无法保证。您可以尝试通过禁用 AQ、MBTree 或使用 CQP 速率控制来最小化概率,但仅此而已。
更新。也不要忘记在不同的 CPU 上使用相同的线程数而不是自动。
我 运行 在 docker 机器 运行 i7 和 i9s 上测试时遇到了这个问题。起初我尝试在 https://github.com/FFmpeg/FFmpeg/blob/master/configure
中禁用不同的 cpu 功能
但后来我注意到两台机器都使用相同的 cpu 功能。我从 运行 命令输出的日志中看到了这一点。然后我在日志中看到他们有不同的线程和 lookahead_thread 计数。所以我通过使用此参数 -x264-params threads=6:lookahead_threads=1
指定计数进行更新
我是 ffmpeg 开发的新手,我想知道是否有可能通过 运行ning ffmpeg 在不同机器(使用不同编译器编译)上使用 libx264 编码器获得相同位的精确输出相同的输入文件和相同的配置选项?
如果可以的话,编译时是否需要设置额外的配置选项libx264/ffmpeg?如果不可能,为什么?
下面是我的运行使用 libx264 关闭 ffmpeg 的两个版本的输出,它们产生不同的输出 MD5 哈希值。
ffmpeg 通过自制软件安装在 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
Alpine Linux 上的 ffmpeg(在基于 https://github.com/jrottenberg/ffmpeg/blob/master/docker-images/3.4/alpine/Dockerfile 的 Docker 容器中)
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
在 OSX
上使用 ffmpeg 测试 运行ffmpeg -i seg.ts -c:v libx264 -s 1280x720 -minrate 6000k -maxrate 6000k -bufsize 6000k -r 60 -threads 1 -f md5 -
输出
MD5=b7c84c0bae5da6749e389a5b69d88582
在 Alpine Linux 上使用 ffmpeg 测试 运行(在基于 https://github.com/jrottenberg/ffmpeg/blob/master/docker-images/3.4/alpine/Dockerfile 的 Docker 容器中)
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 -
输出
MD5=c46af8fbdbbb2bfbb9f7042ab28accfc
如果您在不同的 CPU 上使用不同版本的 libx264,没有人能保证您的输出完全相同。使用在不同 CPU 上构建的相同 libx264(不同的指令集扩展支持),您也可以获得不同的输出,但可以尝试通过在编码期间使用 --cpu-independent 参数(对于 ffmpeg 到 -x264-params)来修复它(在两者上)。
至于为什么不能使用不同的 libx264 构建是因为不同的编译器可以生成不同的浮点数学代码,这些代码在舍入误差方面会有所不同(使用 x87 或 sse),因此无法保证。您可以尝试通过禁用 AQ、MBTree 或使用 CQP 速率控制来最小化概率,但仅此而已。
更新。也不要忘记在不同的 CPU 上使用相同的线程数而不是自动。
我 运行 在 docker 机器 运行 i7 和 i9s 上测试时遇到了这个问题。起初我尝试在 https://github.com/FFmpeg/FFmpeg/blob/master/configure
中禁用不同的 cpu 功能但后来我注意到两台机器都使用相同的 cpu 功能。我从 运行 命令输出的日志中看到了这一点。然后我在日志中看到他们有不同的线程和 lookahead_thread 计数。所以我通过使用此参数 -x264-params threads=6:lookahead_threads=1