Converting RGB images into lossless video with avconv / ffmpeg

6,486

With the help of a ffmpeg contributor it was found out that both ffmpeg and libav create flawless lossless Quicktime files. The problem seems to be the graphic card driver displaying the videos wrongly (since GStream based players and VLC both display it wrongly, however VLC is exporting perfect PNGs of video frames). If you want to check if a video is really containing the frames pixel by pixel, try using

$ ffmpeg -i input.png -vcodec qtrle out.mov

$ ffmpeg -i input.png -f framecrc -
$ ffmpeg -i out.mov -f framecrc -

This will output frame data checksums.

For a visual comparison, convert the lossless video back to single frames and compare those.

Share:
6,486
despens
Author by

despens

Updated on September 18, 2022

Comments

  • despens
    despens almost 2 years

    I am trying to convert a series of PNG24 images containing a screen animation to a lossless video, so that every pixel is reproduced exactly as it was in the original. But avconv (and ffmpeg) both produce the same, unsatisfying results, which seem to stem from a colospace conversion going wrong.

    This is the version of avconv I am using:

    avconv version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers
      built on Apr  2 2013 17:02:36 with gcc 4.6.3
    

    Each of the images is 1280×800 pixels in size. They do not contain any photographic motives, but specially dithered patterns.

    I used the qtrle codec because apparently this is a lossless codec that works very much like animated GIFs or animated PNGs. However, during the conversion to video there seems to happen a color space conversion ("filter") that is messing with the pixels.

    This is the avconv output:

    $ avconv -f image2 -r 30 -i frames.png/wth-%08d.png -vcodec qtrle -pix_fmt rgb24 -t 15 qtrle-30fps-rgb.mov
    avconv version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers
      built on Apr  2 2013 17:02:36 with gcc 4.6.3
    Input #0, image2, from 'frames.png/wth-%08d.png':
      Duration: 00:11:17.96, start: 0.000000, bitrate: N/A
        Stream #0.0: Video: png, bgra, 1280x800, 30 fps, 30 tbr, 30 tbn, 30 tbc
    File 'qtrle-30fps-rgb.mov' already exists. Overwrite ? [y/N] y
    [buffer @ 0x740a00] w:1280 h:800 pixfmt:bgra
    [avsink @ 0x742ac0] auto-inserting filter 'auto-inserted scaler 0' between the filter 'src' and the filter 'out'
    [scale @ 0x743680] w:1280 h:800 fmt:bgra -> w:1280 h:800 fmt:rgb24 flags:0x4
    Output #0, mov, to 'qtrle-30fps-rgb.mov':
      Metadata:
        encoder         : Lavf53.21.1
        Stream #0.0: Video: qtrle, rgb24, 1280x800, q=2-31, 200 kb/s, 30 tbn, 30 tbc
    Stream mapping:
      Stream #0:0 -> #0:0 (png -> qtrle)
    Press ctrl-c to stop encoding
    frame=  450 fps= 22 q=0.0 Lsize=  126056kB time=15.00 bitrate=68843.4kbits/s    
    video:126052kB audio:0kB global headers:0kB muxing overhead 0.003441%
    

    This is an original PNG image file:

    enter image description here

    This is a screenshot of the video being replayed:

    Screenshot of the video being replayed

    Please note that you need to see these images in their original 1280×800 resolution to notice the differences.

    Here is a side-by-side comparison, with the left picture being the original and the right one the outcome after video encoding:

    enter image description here

    Is there any way I can produce a truly lossless, pixel-perfect video file from a series of PNGs?

    • slhck
      slhck about 11 years
      Interesting. Your input file shows as bgra, while for me (in ffmpeg) it shows as rgba. Anyway, can you try setting the output to -pix_fmt argb instead?
    • Admin
      Admin about 11 years
      I tried argb, the result looks exactly the same as before.
    • Admin
      Admin about 11 years
      Hi @slhck, starting from your comment I have tried to change the format of the PNGs so that no automatic filter is required. I used the -flatten +matte option in ImageMagick to get true RGB24 png files. The result was that no filter was 'auto inserted', but the result was still wrong. Now I wonder how to change the 'encoder' encoder : Lavf53.21.1?
    • slhck
      slhck about 11 years
      The encoder is basically what's built into avconv (or ffmpeg if you use FFmpeg). You can only change it by using a more recent version. To my knowledge Libav doesn't offer builds of avconv, so you'd have to build yourself. Or download a static build of ffmpeg from their download page. Please note the difference between Libav and FFmpeg: Who can tell me the difference and relation between ffmpeg, libav, and avconv
    • slhck
      slhck about 11 years
      That being said if you can reproduce this with a recent build, consider filing a bug report with FFmpeg or Libav if you have a strong feeling that the color conversion is not exact (even though it should be).
  • Peter Cordes
    Peter Cordes over 9 years
    depending on codecs, you may need to use -pix_fmt to crc / md5 the same arrangement of losslessly-decoded data. e.g. ffmpeg's RGB h.264 decoder outputs planar RGB, in a format ffmpeg calls gbrp.