[FFmpeg-trac] #4287(avcodec:new): lossless libx264rgb data corruption with image2 input
FFmpeg
trac at avcodec.org
Thu Jan 29 12:35:05 CET 2015
#4287: lossless libx264rgb data corruption with image2 input
-------------------------------------+-------------------------------------
Reporter: pcordes | Type: defect
Status: new | Priority: normal
Component: avcodec | Version: git-
Keywords: libx264rgb | master
x264 corruption lossless image2 | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
Summary of the bug:
ffmpeg -c:v libx264rgb -qp 0 (lossless RGB mode) corrupts some inputs.
After disproving a couple theories while writing this bug report, I now
believe that corruption depends on the input codec. It seems it can
happen with any x264 settings (although in my testcase it's only visually
obvious with subme>=3).
With ffmpeg reading from an RGB-utvideo.mkv, I always get bit-exact
(framemd5-checked) correct output with ultrafast and veryslow. Reading
from a directory of png files, I always get corrupted output. (decodes
fine, but decode output != input for at least some frames).
I forget if I tested with a source produced by muxing the PNGs into an
mkv. (-codec copy).
Since it depends on what input source I use, I'm now almost certain this
is an ffmpeg bug, and not a libx264 bug. The x264 stand-alone cli output
decodes to bit-exact correct values. (Tested using AviSynth+ (http://avs-
plus.net/) to read directly from the same directory of PNGs, in a 64bit-
windows build of x264.)
How to reproduce:
I'm using an 8-bit color-depth build of libx264.
It's reproducible with the first 16 frames of the Sintel trailer (1080p
PNGs). With subme >= 3, there are some thin blocks of solid-blue color in
all 3 of the first non-black frames. Even worse artifacts (like a block
of all-white in the lower letterbox bar) appear around the middle of the
video, and persist until the next black frame.
https://media.xiph.org/sintel/sintel_trailer-1080-png.tar.gz from
https://media.xiph.org/. The first 16 frames only take 308kiB (since many
of them are black, starting to fade in at frame 14), so downloading just
the first 1MB of the tar.gz should be enough, if they're in order within
the archive.
Get at least the first 16 frames of the Sintel trailer, as PNGs in a
directory called 1080/. My testcase uses the first 25 frames, because I
wanted more than 3 non-black frames while I was trying to see what
affected the corruption.
{{{
# if you want to copy/paste this, then
alias ffmpeg='ffmpeg -d' # daemon mode, doesn't read stdin. -stdin
doesn't work
# or paste into a file and source it.
ffmpeg -framerate 24 -i 1080/sintel_trailer_2k_%04d.png -c:v utvideo
sintel.utvideo.mkv
mkdir "gtest-$HOSTNAME" # gtest = glitch test
ffmpeg -i sintel.utvideo.mkv -pix_fmt rgb24 -frames 25 -f framemd5
"gtest-$HOSTNAME/framemd5.rgb24.25.utvideo"
ffmpeg -framerate 24 -i 1080/sintel_trailer_2k_%04d.png -pix_fmt rgb24
-frames 25 -f framemd5 "gtest-$HOSTNAME/framemd5.rgb24.25.png-src"
# PNG input
for opt in subme={0..3}; do
fr=25 crf=0 pr=ultrafast; s="gtest-$HOSTNAME/ffmpeg$fr.from-
png.$pr.$opt";
FFREPORT=file="'$s.log'" ffmpeg -sws_flags +print_info -framerate 24 -i
1080/sintel_trailer_2k_%04d.png -c:v libx264rgb -crf $crf -preset $pr
-frames $fr -x264-params "$opt" "$s.mkv";
ffmpeg -i "$s.mkv" -pix_fmt rgb24 -f framemd5
"${s/ffmpeg/framemd5.rgb24.}";
done
# UTVideo input
for opt in subme={0..3}; do
fr=25 crf=0 pr=ultrafast; s="gtest-$HOSTNAME/ffmpeg$fr.from-
utvideo.$pr.$opt";
FFREPORT=file="'$s.log'" ffmpeg -sws_flags +print_info -i
sintel.utvideo.mkv -c:v libx264rgb -crf $crf -preset $pr -frames $fr
-x264-params "$opt" "$s.mkv";
ffmpeg -i "$s.mkv" -pix_fmt rgb24 -f framemd5
"${s/ffmpeg/framemd5.rgb24.}";
done
md5sum gtest-$HOSTNAME/framemd5.rgb24.25.* |sort
#output:
69700f8152bf3b899f8120e4c4b80567 gtest-tesla/framemd5.rgb24.25.from-
utvideo.ultrafast.subme=0
69700f8152bf3b899f8120e4c4b80567 gtest-tesla/framemd5.rgb24.25.from-
utvideo.ultrafast.subme=1
69700f8152bf3b899f8120e4c4b80567 gtest-tesla/framemd5.rgb24.25.from-
utvideo.ultrafast.subme=2
69700f8152bf3b899f8120e4c4b80567 gtest-tesla/framemd5.rgb24.25.from-
utvideo.ultrafast.subme=3
69700f8152bf3b899f8120e4c4b80567 gtest-tesla/framemd5.rgb24.25.png-src
69700f8152bf3b899f8120e4c4b80567 gtest-tesla/framemd5.rgb24.25.utvideo
6f5e1f1e0646951984deef28c77dccee gtest-tesla/framemd5.rgb24.25.from-
png.ultrafast.subme=3
789ec2dbc2c59f41f123310a757e08a1 gtest-tesla/framemd5.rgb24.25.from-
png.ultrafast.subme=0
789ec2dbc2c59f41f123310a757e08a1 gtest-tesla/framemd5.rgb24.25.from-
png.ultrafast.subme=1
789ec2dbc2c59f41f123310a757e08a1 gtest-tesla/framemd5.rgb24.25.from-
png.ultrafast.subme=2
# simplified commandline:
ffmpeg -framerate 24 -i 1080/sintel_trailer_2k_%04d.png -c:v libx264rgb
-qp 0 -frames 16 "sintel.16frames.medium.lossless.mkv"
ffmpeg version N-68120-gfdcb518 (on ubuntu, with some local patches) or
zeranoe 64bit:
ffmpeg version N-69278-gf5b3257 Copyright (c) 2000-2015 the FFmpeg
developers
built on Jan 26 2015 22:13:17 with gcc 4.9.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads
--enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r
--enable-gnutls --enable-iconv --enable-libass --enable-libbluray
--enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme
--enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame
--enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-libopus --enable-librtmp --enable-libschroedinger --enable-
libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-
libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-
libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-
libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma
--enable-decklink --enable-zlib
...
[libx264rgb @ 0000000002c84820] using mv_range_thread = 88
[libx264rgb @ 0000000002c84820] using SAR=1/1
[libx264rgb @ 0000000002c84820] using cpu capabilities: MMX2 SSE2Fast
SSSE3 SSE4.2 AVX
[libx264rgb @ 0000000002c84820] profile High 4:4:4 Predictive, level 5.1,
4:4:4 8-bit
[libx264rgb @ 0000000002c84820] 264 - core 144 r2525 40bb568
}}}
ffplay is probably the best choice for watching the output of a 16frame
video, because ffplay doesn't exit or anything at the end. It appears to
be using the wrong colorspace on windows (black shows as dark gray), but
that's different bug I guess.
Tested and reproduced on Ubuntu 14.04 (gcc 4.8.2) (on a Conroe E6600 CPU,
dual core SSSE3), and with cross-compiled ffmpeg for Windows using
https://github.com/rdp/ffmpeg-windows-build-helpers, and with zeranoe 32
and 64bit static builds (on a Sandybridge CPU, i5 quad core, SSE4.2 and
AVX).
Note that the -pix_fmt rgb24 is needed with -f framemd5, because the png
decoder outputs rgb24, but ffh264 outputs planar gbrp. Same data,
different layout, different md5sum. Or use -pix_fmt gbrp to favor
ffh264's default layout, but be consistent.
I also noticed that RGB h.264 output from ffmpeg is identified by ffmpeg
-i as "gbrp(tv, gbr/unknown/unknown)". I haven't found a way to use
-colorspace or -color_range jpeg to affect it. RGB output from the x264
cli shows up as gbrp(pc, ...), and mediainfo flags it as "full range".
For a while I suspected the bug was that ffmpeg was telling x264 the input
wasn't full range, when it actually was. But since I get perfect results
with utvideo input, even though the files say tv range, that can't be it.
The AviSynth script I used for testing on Windows was just:
{{{ImageSource("1080/sintel_trailer_2k_%04d.png", 1, 1253, 24)}}}
I checked the framemd5 output for a complete encode of the Sintel trailer,
and it's correct for ultrafast and veryslow, reading from utvideo.
Different x264 settings have different md5s when reading from png, but
surprisingly, the results are the same between my Linux dual core Conroe
and my Windows quad core Sandybridge. (i.e. bit-identical corruption.) I
also get identical results every time; this doesn't seem to depend on
freak timing of threads.
Using utvideo as the input, the framemd5 matches for the full 1253 frames,
not just the first 25.
--
Ticket URL: <https://trac.ffmpeg.org/ticket/4287>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list