[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