JuliaIO / VideoIO.jl

Reading and writing of video files in Julia via ffmpeg
https://juliaio.github.io/VideoIO.jl/stable
Other
126 stars 53 forks source link

How input color range is mapped onto encoded output depends on whether input is RGB or Gray #283

Closed galenlynch closed 3 years ago

galenlynch commented 3 years ago

Currently, VideoIO's encoding seems to be geared to taking normal Julia arrays and then trying to generate a video that will play on most players, with sensible defaults.

This strategy can be seen with RGB input arrays: given an array of RGB triplets that are stored with three UInt8 samples, VideoIO will change the RGB color into a YCbCr color with the Rec. 601 range (luma between 16 and 235) that matches the default ffmpeg color range, and is also the most widely supported. Furthermore, it downsamples the chroma to allow YUV420P encoding, which once again is the most widely supported video format. Both of these steps make sense from the perspective of making videos that look good and work on most players, even if it is at the expense of fidelity.

In contrast, Gray input arrays are not automatically converted to the default input range of FFMPEG h264 videos (16-235). Unless the user passes the encoder option of "color_range" => "2", then any values outside of the 16-235 range ("MPEG" or "limited" range in FFMPEG's terms) are simply clipped, causing the output video to look blown out.

I get the sense VideoIO is often used by people who have some arrays and just want to make a video, rather than people who are familiar with the ins and outs of codecs. In this case, I doubt they will limit their input data to the proper range. Even if they were aware of this potential hurdle, it is hard to tell what input range VideoIO expects without inspecting the code. At the very least, the default scaling of Gray arrays: "full range" input to "full range" pixel data, differs from the default scaling of RGB arrays: "full range" input to "limited" pixel data.