To see a full screen version of this page goto here

Comparing YUV conversion approaches.

This is comparing different ways to do the YUV conversion. We are doing it in both 420p and 444p since 444p is a fairer binary image comparison. The takeaway should be to use the libswscale filter. The code to generate these files is here.



yuv422p10le encodes





YUV444p encodes (Chrome Only)






</div>

Reference PNG

Source PNG file

yuv422p10le encodes

Default Encode (terrible)

Basic ffmpeg conversion, no colorspace specified, ffmpeg assumes bt601 colorspace. This is a terrible filter, significant color changes from PNG file.

ffmpeg flags to add:

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -c:v libx264 -preset placebo -qp 1 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv422p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/basic.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-basic.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-basic.png"
Mean error = 0.265387
RMS error = 0.501056
Peak SNR = 6.00228
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

Colormatrix filter (close)

Using colormatrix filter. colormatrix only supports 8-bit per component images. Visually its getting pretty close.

ffmpeg flags to add: -sws_flags spline+accurate_rnd+full_chroma_int -vf "colormatrix=bt470bg:bt709"

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -sws_flags spline+accurate_rnd+full_chroma_int -vf "colormatrix=bt470bg:bt709" -c:v libx264 -preset placebo -qp 1 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv422p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/colormatrix.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-colormatrix.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-colormatrix.png"
Mean error = 0.251864
RMS error = 0.500034
Peak SNR = 6.02
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

Colorspace filter

Using colorspace filter, better quality filter, SIMD so faster too, can support 10-bit too. Visually pretty close to colormatrix, but slight improvement based on colormatrix values.

ffmpeg flags to add: -sws_flags spline+accurate_rnd+full_chroma_int -vf "colorspace=bt709:iall=bt601-6-625:fast=1"

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -sws_flags spline+accurate_rnd+full_chroma_int -vf "colorspace=bt709:iall=bt601-6-625:fast=1" -c:v libx264 -preset placebo -qp 1 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv422p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/colorspace.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-colorspace.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-colorspace.png"
Mean error = 0.251258
RMS error = 0.500027
Peak SNR = 6.02013
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

libswscale filter + flags (best)

Using the libswscale library. Seems similar to colorspace, but with image resizing, and levels built in. This also has a number of libswscale parameters. Visually this is close to the above two, but slight improvement based on colormatrix results.

ffmpeg flags to add: -sws_flags spline+accurate_rnd+full_chroma_int+full_chroma_inp -vf "scale=in_color_matrix=bt709:out_color_matrix=bt709"

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -sws_flags spline+accurate_rnd+full_chroma_int+full_chroma_inp -vf "scale=in_color_matrix=bt709:out_color_matrix=bt709" -c:v libx264 -preset placebo -qp 1 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv422p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/splinecolormatrix.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-splinecolormatrix.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-splinecolormatrix.png"
Mean error = 0.251215
RMS error = 0.500029
Peak SNR = 6.02009
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

YUV444p encodes (Chrome Only)

Default Encode (terrible)

Basic ffmpeg conversion, ffmpeg assumes bt601 colorspace, now at 444. Results look terrible.

ffmpeg flags to add:

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/basic444.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-basic444.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-basic444.png"
Mean error = 0.265202
RMS error = 0.501036
Peak SNR = 6.00262
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

Colormatrix filter (close)

Using colormatrix filter. colormatrix only supports 8-bit per component images. Visually pretty close, but still off.

ffmpeg flags to add: -sws_flags spline+accurate_rnd+full_chroma_int -vf "colormatrix=bt470bg:bt709"

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -sws_flags spline+accurate_rnd+full_chroma_int -vf "colormatrix=bt470bg:bt709" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/spline444colormatrix2.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444colormatrix2.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444colormatrix2.png"
Mean error = 0.251596
RMS error = 0.500007
Peak SNR = 6.02048
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

Colorspace filter

Using colorspace filter, better quality filter, SIMD so faster too, can support 10-bit too. Visually slight differences, but getting closer.

ffmpeg flags to add: -sws_flags spline+accurate_rnd+full_chroma_int -vf "colorspace=bt709:iall=bt601-6-625:fast=1"

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -sws_flags spline+accurate_rnd+full_chroma_int -vf "colorspace=bt709:iall=bt601-6-625:fast=1" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/spline444colorspace.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444colorspace.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444colorspace.png"
Mean error = 0.250951
RMS error = 0.500002
Peak SNR = 6.02056
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

libswscale filter + flags (Match)

Using the libswscale library. Seems similar to colorspace, but with image resizing, and levels built in. This also has a number of libswscale parameters. Looking at the oiio difference, this is the first one that has an identical result to the input image.

ffmpeg flags to add: -sws_flags spline+accurate_rnd+full_chroma_int+full_chroma_inp -vf "scale=in_color_matrix=bt709:out_color_matrix=bt709"

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -sws_flags spline+accurate_rnd+full_chroma_int+full_chroma_inp -vf "scale=in_color_matrix=bt709:out_color_matrix=bt709" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p10le -qscale:v 1 -color_range 1 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/spline444out_color_matrix.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444out_color_matrix.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444out_color_matrix.png"
Mean error = 0.250917
RMS error = 0.500002
Peak SNR = 6.02056
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!

libswscale filter + flags full-range (Match)

Using the libswscale library. Seems similar to colorspace, but with image resizing, and levels built in. This also has a number of libswscale parameters. Looking at the oiio difference, this is the first one that has an identical result to the input image.

ffmpeg flags to add: -sws_flags spline+accurate_rnd+full_chroma_int+full_chroma_inp -vf "scale=in_range=full:in_color_matrix=bt709:out_range=full:out_color_matrix=bt709"

Full creation commandline:
ffmpeg -y -r 1 -i ../sourceimages/chip-chart-1080-noicc.png -sws_flags spline+accurate_rnd+full_chroma_int+full_chroma_inp -vf "scale=in_range=full:in_color_matrix=bt709:out_range=full:out_color_matrix=bt709" -c:v libx264 -preset placebo -qp 0 -x264-params "keyint=15:no-deblock=1" -pix_fmt yuv444p10le -qscale:v 1 -color_range 2 -colorspace 1 -color_primaries 1 -color_trc 13 ./chip-chart-yuvconvert/spline444out_color_matrixfull.mp4

OIIO idiff output

idiff -o ./chip-chart-yuvconvert/chip-chart-1080-noiccdiff.png ../sourceimages/chip-chart-1080-noicc.png ./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444out_color_matrixfull.png
b'Comparing "../sourceimages/chip-chart-1080-noicc.png" and "./chip-chart-yuvconvert/chip-chart-1080-noicc-spline444out_color_matrixfull.png"
Mean error = 0.250915
RMS error = 0.500002
Peak SNR = 6.02056
Max error = 1 @ (0, 0, A) values are 0, 0, 0 vs 0, 0, 0, 1
2073600 pixels (100%) over 1e-06
2073600 pixels (100%) over 1e-06
FAILURE
'ERROR!


Copyright © 2022 ORI Contributors. Distributed under a CC BY 4.0 license.