Opened 4 years ago

Closed 4 years ago

#8635 closed defect (invalid)

FFV1 not lossless when encoding RGB data (bgr0 pixel format)

Reported by: JustAnotherArchivist Owned by:
Priority: normal Component: avcodec
Version: unspecified Keywords: ffv1
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug: FFV1 encodes with RGB pixel format (specifically in my tests: bgr0) appear to not be lossless. More precisely, they produce a different video signal on decoding than the input.

How to reproduce:
I'll illustrate this with a short 1-second x11grab recording. First, capture the sample and encode losslessly with x264 (for smaller files; I've verified it behaves the same using straight rawvideo):

$ ffmpeg -thread_queue_size 512 -video_size 1920x1080 -framerate 30 -f x11grab -i :0.0 -c:v libx264rgb -crf 0 -preset ultrafast -t 00:00:01.000 rgb.mkv
ffmpeg version 4.2.2-1+b1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (Debian 9.2.1-28)
  configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
[x11grab @ 0x5582856f9540] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, x11grab, from ':0.0':
  Duration: N/A, start: 1587936125.048433, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 30 fps, 1000k tbr, 1000k tbn, 1000k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264rgb))
Press [q] to stop, [?] for help
[libx264rgb @ 0x558285706640] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264rgb @ 0x558285706640] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264rgb @ 0x558285706640] 264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, matroska, to 'rgb.mkv':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: h264 (libx264rgb) (H264 / 0x34363248), bgr0, 1920x1080, q=-1--1, 30 fps, 1k tbn, 30 tbc
    Metadata:
      encoder         : Lavc58.54.100 libx264rgb
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame=   30 fps= 30 q=-1.0 Lsize=    3494kB time=00:00:00.96 bitrate=29566.7kbits/s speed=0.965x    
video:3493kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.026925%
[libx264rgb @ 0x558285706640] frame I:1     Avg QP: 0.00  size:1149327
[libx264rgb @ 0x558285706640] frame P:29    Avg QP: 0.00  size: 83681
[libx264rgb @ 0x558285706640] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264rgb @ 0x558285706640] mb P  I16..4: 57.0%  0.0%  0.0%  P16..4:  0.1%  0.0%  0.0%  0.0%  0.0%    skip:42.8%
[libx264rgb @ 0x558285706640] coded y,u,v intra: 4.2% 4.1% 4.2% inter: 0.2% 0.2% 0.2%
[libx264rgb @ 0x558285706640] i16 v,h,dc,p: 98%  2%  0%  0%
[libx264rgb @ 0x558285706640] kb/s:28608.65

(Note the use of libx264rgb to avoid the lossy RGB-to-YUV conversion.)

Next, encode this with FFV1. The pix_fmt is automatically inferred to be bgr0.

$ ffmpeg -i rgb.mkv -c:v ffv1 ffv1.mkv
ffmpeg version 4.2.2-1+b1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (Debian 9.2.1-28)
  configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, matroska,webm, from 'rgb.mkv':
  Metadata:
    ENCODER         : Lavf58.29.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 28620 kb/s
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), gbrp(tv, gbr/unknown/unknown, progressive), 1920x1080, 30 fps, 30 tbr, 1k tbn, 60 tbc (default)
    Metadata:
      ENCODER         : Lavc58.54.100 libx264rgb
      DURATION        : 00:00:01.000000000
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> ffv1 (native))
Press [q] to stop, [?] for help
Output #0, matroska, to 'ffv1.mkv':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), bgr0, 1920x1080, q=2-31, 200 kb/s, 30 fps, 1k tbn, 30 tbc (default)
    Metadata:
      DURATION        : 00:00:01.000000000
      encoder         : Lavc58.54.100 ffv1
frame=   30 fps=0.0 q=-0.0 Lsize=    9088kB time=00:00:00.96 bitrate=76908.2kbits/s speed=1.01x    
video:9087kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.011854%

Third, check whether the two are identical. Here, I'll pipe the decoded video signal to md5sum. Running that on the two files should yield identical hashes, but it does not:

$ ffmpeg -i rgb.mkv -c:v rawvideo -f rawvideo -pix_fmt bgr0 - | md5sum
ffmpeg version 4.2.2-1+b1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (Debian 9.2.1-28)
  configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, matroska,webm, from 'rgb.mkv':
  Metadata:
    ENCODER         : Lavf58.29.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 28620 kb/s
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), gbrp(tv, gbr/unknown/unknown, progressive), 1920x1080, 30 fps, 30 tbr, 1k tbn, 60 tbc (default)
    Metadata:
      ENCODER         : Lavc58.54.100 libx264rgb
      DURATION        : 00:00:01.000000000
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to 'pipe:':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, q=2-31, 1492992 kb/s, 30 fps, 30 tbn, 30 tbc (default)
    Metadata:
      DURATION        : 00:00:01.000000000
      encoder         : Lavc58.54.100 rawvideo
frame=   30 fps=0.0 q=-0.0 Lsize=  243000kB time=00:00:01.00 bitrate=1990656.0kbits/s speed=1.47x    
video:243000kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
3c3fa2c24dcab4c163d58a32b61232fc  -
$ ffmpeg -i ffv1.mkv -c:v rawvideo -f rawvideo -pix_fmt bgr0 - | md5sum
ffmpeg version 4.2.2-1+b1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (Debian 9.2.1-28)
  configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, matroska,webm, from 'ffv1.mkv':
  Metadata:
    ENCODER         : Lavf58.29.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 74447 kb/s
    Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), bgr0, 1920x1080, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
    Metadata:
      ENCODER         : Lavc58.54.100 ffv1
      DURATION        : 00:00:01.000000000
Stream mapping:
  Stream #0:0 -> #0:0 (ffv1 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to 'pipe:':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, q=2-31, 1492992 kb/s, 30 fps, 30 tbn, 30 tbc (default)
    Metadata:
      DURATION        : 00:00:01.000000000
      encoder         : Lavc58.54.100 rawvideo
frame=   30 fps=0.0 q=-0.0 Lsize=  243000kB time=00:00:01.00 bitrate=1990656.0kbits/s speed= 1.6x    
video:243000kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
7090bbfbcfb2949d2ffac86fb262ef70  -

Oddly enough, the SSIM and PSNR filters claim that they are indeed identical:

$ ffmpeg -i rgb.mkv -i ffv1.mkv -filter_complex "ssim;[0:v][1:v]psnr" -f null -
<...>
[Parsed_ssim_0 @ 0x56235b211740] SSIM R:1.000000 (inf) G:1.000000 (inf) B:1.000000 (inf) All:1.000000 (inf)
[Parsed_psnr_1 @ 0x56235b212240] PSNR r:inf g:inf b:inf average:inf min:inf max:inf

I'm not sure how that can be true since the raw video streams are clearly not identical.

In comparison, if I first do the (lossy) conversion to yuv444p and then encode that with FFV1, I get identical video streams:

$ ffmpeg -i rgb.mkv -c:v libx264 -crf 0 -preset ultrafast yuv.mkv
ffmpeg version 4.2.2-1+b1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (Debian 9.2.1-28)
  configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, matroska,webm, from 'rgb.mkv':
  Metadata:
    ENCODER         : Lavf58.29.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 28620 kb/s
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), gbrp(tv, gbr/unknown/unknown, progressive), 1920x1080, 30 fps, 30 tbr, 1k tbn, 60 tbc (default)
    Metadata:
      ENCODER         : Lavc58.54.100 libx264rgb
      DURATION        : 00:00:01.000000000
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x560f40eab8c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x560f40eab8c0] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264 @ 0x560f40eab8c0] 264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, matroska, to 'yuv.mkv':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: h264 (libx264) (H264 / 0x34363248), yuv444p, 1920x1080, q=-1--1, 30 fps, 1k tbn, 30 tbc (default)
    Metadata:
      DURATION        : 00:00:01.000000000
      encoder         : Lavc58.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame=   30 fps=0.0 q=-1.0 Lsize=    1386kB time=00:00:00.96 bitrate=11729.7kbits/s speed=1.56x    
video:1385kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.068108%
[libx264 @ 0x560f40eab8c0] frame I:1     Avg QP: 0.00  size:431586
[libx264 @ 0x560f40eab8c0] frame P:29    Avg QP: 0.00  size: 34008
[libx264 @ 0x560f40eab8c0] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 0x560f40eab8c0] mb P  I16..4: 57.0%  0.0%  0.0%  P16..4:  0.1%  0.0%  0.0%  0.0%  0.0%    skip:42.8%
[libx264 @ 0x560f40eab8c0] coded y,u,v intra: 4.3% 0.3% 0.3% inter: 0.2% 0.0% 0.0%
[libx264 @ 0x560f40eab8c0] i16 v,h,dc,p: 98%  2%  0%  0%
[libx264 @ 0x560f40eab8c0] kb/s:11342.45
$ ffmpeg -i yuv.mkv -c:v ffv1 ffv1_yuv.mkv
ffmpeg version 4.2.2-1+b1 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9 (Debian 9.2.1-28)
  configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, matroska,webm, from 'yuv.mkv':
  Metadata:
    ENCODER         : Lavf58.29.100
  Duration: 00:00:01.00, start: 0.000000, bitrate: 11354 kb/s
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p(progressive), 1920x1080, 30 fps, 30 tbr, 1k tbn, 60 tbc (default)
    Metadata:
      ENCODER         : Lavc58.54.100 libx264
      DURATION        : 00:00:01.000000000
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> ffv1 (native))
Press [q] to stop, [?] for help
Output #0, matroska, to 'ffv1_yuv.mkv':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), yuv444p, 1920x1080, q=2-31, 200 kb/s, 30 fps, 1k tbn, 30 tbc (default)
    Metadata:
      DURATION        : 00:00:01.000000000
      encoder         : Lavc58.54.100 ffv1
frame=   30 fps=0.0 q=-0.0 Lsize=    8549kB time=00:00:00.96 bitrate=72348.4kbits/s speed=1.18x    
video:8548kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.012601%
$ ffmpeg -i yuv.mkv -c:v rawvideo -f rawvideo - 2>/dev/null | md5sum
2d5213499124e04ba1d87175b5f2317e  -
$ ffmpeg -i ffv1_yuv.mkv -c:v rawvideo -f rawvideo - 2>/dev/null | md5sum
2d5213499124e04ba1d87175b5f2317e  -

Hence it appears that FFV1 with bgr0 is for some reason a lossy operation. I have however not investigated what the actual differences between the video streams are. ffprobe -debug 1 confirms that the file uses colorspace: 1, i.e. JPEG2000_RCT.

Of course, it is entirely possible that this is only a problem on decoding or that the corruption is reversible, but pending deeper investigation, the best working assumption is that this is indeed data loss and therefore critical priority per doc/issue_tracker.txt.

Version: 7:4.2.2-1+b1 on Debian sid

Change History (3)

comment:1 by Carl Eugen Hoyos, 4 years ago

Keywords: ffv1 added
Priority: criticalnormal

Please test current FFmpeg git head, the only version supported on this bug tracker, and provide an input file that allows to reproduce.

comment:2 by Carl Eugen Hoyos, 4 years ago

You will have to compare the output with -pix_fmt gbrp or -pix_fmt rgb24, bgr0 by definition contains 25% data that will not be encoded and is not necessarily lossless.

comment:3 by JustAnotherArchivist, 4 years ago

Resolution: invalid
Status: newclosed

Interesting, thank you. Since x11grab produces bgr0 output, I assumed that using the same pix_fmt throughout should be lossless. Indeed, the fourth byte is the difference between the streams:

$ ffmpeg -i rgb.mkv -c:v rawvideo -f rawvideo -pix_fmt bgr0 - 2>/dev/null | xxd | head -1
00000000: f4f5 f6ff f4f5 f6ff f4f5 f6ff f4f5 f6ff  ................
$ ffmpeg -i ffv1.mkv -c:v rawvideo -f rawvideo -pix_fmt bgr0 - 2>/dev/null | xxd | head -1
00000000: f4f5 f600 f4f5 f600 f4f5 f600 f4f5 f600  ................

And with gbrp, the streams are identical:

$ ffmpeg -i rgb.mkv -c:v rawvideo -f rawvideo -pix_fmt gbrp - 2>/dev/null | md5sum
79058c74ef8d9ff27483828ac57c10fe  -
$ ffmpeg -i ffv1.mkv -c:v rawvideo -f rawvideo -pix_fmt gbrp - 2>/dev/null | md5sum
79058c74ef8d9ff27483828ac57c10fe  -

Sorry for the noise. I got identical streams with bgr0 with all other lossless codecs and settings I tried (x264, x265, vp9, huffyuv, rawvideo), so it seemed reasonable to assume that it's a stable colour encoding. Very confusing that the "0" actually means undefined, not NUL bytes.

Note: See TracTickets for help on using tickets.