pencil2d / pencil

Pencil2D is an easy, intuitive tool to make 2D hand-drawn animations. Pencil2D is open source and cross-platform.
http://pencil2d.org
GNU General Public License v2.0
1.45k stars 272 forks source link

Exported mp4 videos have distorted color #1366

Open scribblemaniac opened 4 years ago

scribblemaniac commented 4 years ago

Issue Summary

When exporting to the mp4 format, the resulting video may play back with slightly different colors than in Pencil2D due to differing standards for the RGB <-> YUV conversion.

Actual Results

Rec. 601 appears to always be used for the RGB -> YUV conversion required for the mp4 video format. No metadata is written to the video concerning this. This results in off-color videos when playing back with a player that assumes that Rec. 709 is being used, particularly with HD videos.

Expected Results

Since these standards were designed for television, it is a bit ambiguous how they should be applied to digital videos which don't always have clear divisions between SD, HD, and 4K videos. However the general behavior of video players is to use use Rec. 601 for videos below a certain height, width, or resolution, and Rec. 709 for everything else. Sometimes the version specified in the metadata is used if it is present, sometimes it is not. In VLC, Rec. 709 is use for videos with a height >= 720. Rec. 2020 is never used. So I would expect that we would follow the same rules, and that we would always write the relevant metadata for which standard was used to encode the data.

Steps to reproduce

  1. Change the line strCmd += QString(" -pix_fmt yuv420p"); in movieexporter.cpp to strCmd += QString(" -pix_fmt yuv444p"); then build and run. The issue occurs without doing this, but the test pattern needs this to clearly show the issue.
  2. Open this test project. This contains a chroma test page from: https://obsproject.com/forum/resources/obs-studio-color-space-color-format-color-range-settings-guide-test-charts.442/
  3. Export the test project.
  4. Note two things in the exported video when viewed at 1:1 zoom ratio. First, you should see a dark pink checkmark to the left of 4:4:4, if you do not, make sure you did step 1 correctly. Second, you should notice a pink tint on the "Wrong Decoding Matrix coefficients detection test". the pink tint indicates that the video was encoded with BT.601, but decoded with BT.709.

System Information

+ Operating System: Ubuntu 20.04
### Developer Notes Writing the metadata with ffmpeg uses the color_primaries, color_trc, and colorspace flags, see this question for examples https://video.stackexchange.com/questions/16840/ffmpeg-explicitly-tag-h-264-as-bt-601-rather-than-leaving-unspecified. Setting the actual standard used can be set with scale's out_color_matrix option, the colorspace filter, or the colormatrix filter. See https://forum.videohelp.com/threads/395345-ffmpeg-yuv-colorspace-is-BT-601-or-BT-709 and https://trac.ffmpeg.org/wiki/colorspace.
scribblemaniac commented 3 years ago

@ValZapod That is not sufficient. As mentioned in the Expected Results section, Rec. 709 is not always used. Even if you set the metadata flags for it, some video players ignore that and will select a video profile based on the video size. We need some logic to choose a standard that displays correctly on the broadest range of common players with any possible video resolution.

scribblemaniac commented 3 years ago

I recall that not being my experience last time I tested it, but perhaps things have changed since then. I am proposing to change the matrix based on the export size, not to change the export size based on the matrix. The export dialog in Pencil2D is designed to be simple, so adding an user option for the color matrix is way out of scope.