[FFmpeg-trac] #9520(ffmpeg:new): Invalid pal8 -> gbrp conversion

FFmpeg trac at avcodec.org
Tue Nov 23 22:07:23 EET 2021

#9520: Invalid pal8 -> gbrp conversion
             Reporter:  Robin        |                    Owner:  (none)
                 Type:  defect       |                   Status:  new
             Priority:  normal       |                Component:  ffmpeg
              Version:  4.4.1        |               Resolution:
             Keywords:  pal8, gbrp,  |               Blocked By:
  pix_fmt                            |
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
Description changed by Robin:

Old description:

> Summary of the bug:
> ffmpeg is not correctly converting pal8 input to gbrp output. I
> discovered this when encoding optimized PNGs to UTVideo.
> Here is the first 30 first frames from Elephants Dream:
> https://www.mediafire.com/file/knisxsozg41001l/Elephants_Dream_First_30_Frames.7z/file
> The package contains both the original PNGs from Xiph and the optimized
> PNGs I created with oxipng. The original PNGs are all 24 bit. But the
> optimized ones are a mixed of 1bit, 8bit and 24bit.
> Copying and pasting my post from doom9 forums:
> https://forum.doom9.org/showthread.php?t=183452
> I tested the release builds and master branch from gyan and Btbn.
> How to reproduce:
> {{{
> 1. Encode the 30 frames to FFV1 and UTVideo:
> ffmpeg -i ED-30-xiph-source\%05d.png -c:v ffv1 ED-xiph_ffv1.mkv
> ffmpeg -i ED-30-xiph-source\%05d.png -c:v utvideo ED-xiph_utvideo.mkv
> ffmpeg -i ED-30-opt\%05d.png -pix_fmt bgr0 -c:v ffv1 ED-opt_ffv1.mkv
> ffmpeg -i ED-30-opt\%05d.png -c:v utvideo ED-opt_utvideo.mkv
> NOTE: The pix_fmt bgr0 command is necessary when encoding from the
> optimized files to prevent ffmpeg from encoding to greyscale since the
> first optimized PNG is 1-bit color. It is actually not necessary for
> UTvideo since it does support a grey or mono colorspace so will default
> to the appropriate pixel format.
> 2. Export all videos and PNGs to BMPs:
> ffmpeg -i ED-30-xiph-source\%05d.png BMP\ED-xiph-%02d.bmp
> ffmpeg -i ED-30-opt\%05d.png -pix_fmt bgr24 BMP\ED-opt-%02d.bmp
> ffmpeg -i ED-xiph_ffv1.mkv BMP\ED-xiph_ffv1-%02d.bmp
> ffmpeg -i ED-xiph_utvideo.mkv BMP\ED-xiph_utvideo-%02d.bmp
> ffmpeg -i ED-opt_ffv1.mkv BMP\ED-opt_ffv1-%02d.bmp
> ffmpeg -i ED-opt_utvideo.mkv BMP\ED_opt_utvideo-%02d.bmp
> 3. Perform checksum on all results.
> I find all BMPs have the same MD5 checksum except:
> ED_opt_utvideo-12.bmp 02a34fc1e347889d5546b547fa63e6af
> ED_opt_utvideo-13.bmp ca40ed9fc4acc827a4a77051433f0102
> ED_opt_utvideo-14.bmp e3666199f35234756dddac97b8e18488
> The above are sourced from the 8-bit optimized PNGs.
> The correct MD5 is as following:
> ED-xiph_utvideo-12.bmp ba5d92ca99726d837859b4b05795d317
> ED-xiph_utvideo-13.bmp 735ee7c8b493855480fd0f5847a66132
> ED-xiph_utvideo-14.bmp b509c3ac24e3543e1f59a7f1456e924d
> Which are sourced from the original Xiph PNGs that are all 24-bit.
> }}}
> Adding -pix_fmt to the source (before -i) did not fix the issue. Someone
> on doom9 found that specifying the conversion process to bgr0 (What FFV1
> uses) then to UTVideo's gbrp solves the problem:
> ffmpeg -i "PATH\ED-30-opt\%05d.png" -vf format=bgr0,format=gbrp -c:v
> utvideo ED-opt_bgr0_gbrp_utvideo.mkv
> Which means the pal8 input (which ED_opt_utvideo-12 though 14 are)
> conversion directly to gbrp has an issue. It is possible other output
> conversions may have errors as well.

New description:

 Summary of the bug:
 ffmpeg is not correctly converting pal8 input to gbrp output. I discovered
 this when encoding optimized PNGs to UTVideo.

 I have attached a .7z with two PNGs. One is original PNG from Elephants
 Dream Frame 13 in RGB24 and the other is optimized PNG in pal8.

 How to reproduce:
 1. Confirm both PNGs are identical:

 ffmpeg -i ref-rgb24.png ref-rgb24.bmp
 ffmpeg -i opt-pal8.png -vf format=bgr24 opt-pal8.bmp

 You will have to force ffmpeg to convert to BGR24 to match the reference
 colorspace output. MD5 of both outputs should match

 This means pal8 -> bgr24 conversion is correct and matches the rgb24 ->
 bgr24 conversion output.

 2. Force conversion to gbrp before final output:

 ffmpeg -i ref-rgb24.png -vf format=gbrp ref-rgb24.bmp
 ffmpeg -i opt-pal8.png -vf format=gbrp opt-pal8.bmp

 MD5s of output BMP will no longer match. ref-rgb24.bmp will match original
 BMP output from step 1 and opt-pal8.bmp output in this step will be

 3. Test alternate colorspace path:

 ffmpeg -i opt-pal8.png -vf format=bgr0 opt-pal8.bmp
 ffmpeg -i opt-pal8.png -vf format=bgr0,format=gbrp opt-pal8.bmp

 Both these produce the correct output. Meaning pal -> bgr0 and bgr0 ->
 gbrp are correct.
 Another way to confirm this is encoding to UTVideo which uses gbrp

 1. Encode frames to UTVideo:
 ffmpeg -i ref-rgb24.png -c:v utvideo ref-rgb24.mkv
 ffmpeg -i opt-pal8.png -c:v utvideo opt-pal8.mkv

 This encodes the frames to gbrp colorspace.

 2. Decode back to raw BMP:
 ffmpeg -i ref-rgb24.mkv ref-rgb24.bmp
 ffmpeg -i opt-pal8.mkv opt-pal8.bmp

 Checksums are different. ref-rgb24.bmp is correct.

 3. Test alternate colorspace path:
 ffmpeg -i opt-pal8.png -vf format=bgr0 -c:v utvideo opt-pal8.mkv
 ffmpeg -i opt-pal8.mkv opt-pal8.bmp

 Output BMP now has correct checksum.

 EDIT: Rewrote this whole ticket to simplify it.

Ticket URL: <https://trac.ffmpeg.org/ticket/9520#comment:3>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker

More information about the FFmpeg-trac mailing list