How CINELERRA-GG works

Decoding/playback:
Video is decoded to internal representation (look at Settings /Format/Color model). Internal format is unpacked as 3 color values + one alpha value every pixel. CINELERRA-GG has 6 internal pixel formats (RGB(A) 8-bit; YUV(A) 8-bit and RGB(A)_FLOAT 32-bit (see Color Model in Video attributes). The program will configure the frame buffer for your resulting video to be able to hold data in that color model. Then, for each plugin, it will pick the variant of the algorithm coded for that model. CINELERRA-GG automatically converts the source file to the set color model (in a buffer, the original is not touched!). Even if the input color model matches what we set in Settings/Format/Color model, there will always be a first conversion because CINELERRA-GG works internally (in the buffer) at 32-bit in RGB. For playback CINELERRA-GG has to convert each frame to the format acceptable by the output device, i.e. sRGB 8-bit. In practice, the decoded file follows two separate paths: conversion to FLOAT for all internal calculations in the temporary (including other conversions for plugins, etc.) and simultaneously the result in the temporary is converted to 8-bit sRGB for on-screen display. See also Automatic "Best Model" Media Load. To review, a temporary is a single frame of video in memory where graphics processing takes place. CINELERRA-GG use X11 and X11 is RGB only and it is used to draw the refresh frame. So single step is always drawn in RGB. Continuous playback on the other hand can also be YUV for efficiency reasons.
Color range:
One problem with the YUV color model is the YUV color range. This can create a visible effect of a switch in color in the Compositor, usually shown as grayish versus over-bright. The cause of the issue is that X11 is RGB only and it is used to draw the refresh frame. So single step is always drawn in RGB. To make a YUV frame into RGB, a color model transfer function is used. The math equations are based on Color_space and Color_range. In this case, color_range is the cause of the grayish offset. The YUV MPEG color range (limited or TV) is 16..235 for Y, 16..240 for UV, and the color range used by YUV JPEG color range (full or HDTV) is 0 to 255. The cause is that 16-16-16 is seen as pure black in MPEG, but as gray in JPEG and all playback will come out brighter and more grayish. This can be fixed by forcing appropriate conversions via the ColorSpace plugin. See Color Space and Color Range Affecting Playback
Plugins:
On the timeline all plugins see the frames only in internal pixel format and modify this as needed (temporary). Some effects work differently depending on colorspace: sometimes pixel values are converted to float, sometimes to 8-bit for an effect. In addition playback single step and plugins cause the render to be in the session color model, while continuous playback with no plugins tries to use the file’s best color model for the display (for speed). As mentioned, each plugin we add converts and uses the color information in its own way. Some limit the gamut and depth of color by clipping (i.e. Histogram); others convert and reconvert color spaces for their convenience; others introduce artifacts and posterization; etc. For example, the Chroma Key (HSV) plugin converts any signal to HSV for its operation. If we want to better control and target this color management in CINELERRA-GG, we can take advantage of its internal ffmpeg engine: there is an optional feature that can be used via .opts lines from the ffmpeg decoded files. This is via the video_filter=colormatrix=...ffmpeg plugin. There may be other good plugins (lut3d...) that can also accomplish a desired color transform. This .opts feature affects the file colorspace on a file by file basis, although in principle it should be possible to setup a histogram plugin or any of the F_lut* plugins to remap the colortable, either by table or interpolation.
Conversion:
Any conversion is done with approximate mathematical calculations and always involves a loss of data, more or less visible, because you always have to interpolate an exact value when mapping it into the other color space. Obviously, when we use floating point numbers to represent values, these losses become small and close to negligible. So the choice comes down to either keeping the source color model even while processing or else converting to FLOAT, which in addition to leading to fewer errors should also minimize the number of conversions, being congruous with the program's internal one. The use of FLOAT, however, takes more system resources than the streamlined YUV. Color conversions are mathematical operations; for example to make a YUV frame into RGB, a color model matrix function is used. The math equations are based on color_space and color_range. Since the majority of sources are YUV, this conversion is very common and it is important to set these parameters to optimize playback speed and correct color representation.
Encoding:
Finally, the encoding converts to colorspace required by the codec.

The CINELERRA-GG Community, 2021
https://www.cinelerra-gg.org