ASS_YCbCrMatrix class abstract
Support for (xy-)VSFilter mangled colors
Generally, xy-VSFilter emulates the classic VSFilter behavior of rendering directly into the (usually YCbCr) video. Classic guliverkli(2)-VSFilter is hardcoded to use BT.601(TV) as target colorspace when converting the subtitle RGB color to the video colorspace. This led to odd results when other colorspaces were used, particular once those became more common with the rise of HDTV video: HDTV typically uses BT.709(TV), but VSFilter continued assuming BT.601(TV) for conversion.
This means classic vsfilter will mangle colors as follows:
screen_rgb = video_csp_to_rgb(rgb_to_bt601tv(ass_rgb))
where video_csp is the colorspace of the video with which the subtitle was muxed.
Subtitle authors worked around this issue by adjusting the color to look as intended after going through the mangling process. Still, this behaviour isn't great and also limits the color range. Yet, for backwards compatibility with existing files, the classic mangling must be preserved for existing files to not break the display of color-matched typesets created with older VSFilter versions. Thus, on iniative of xy-VSFilter/XYSubFilter a new explicit "YCbCr Matrix" header was introduced to allow new files to avoid this color mangling. However due to a limitation of VSFilter API, VSFilters don't actually know the real colorspace of the video they're rendering to, so the header wasn't created as a simple "Use ColourMangling: yes/no", but instead specifies exactly which colorspace to use for the initial conversion from the subtitle's RGB values. So we now got
screen_rgb = video_csp_to_rgb(rgb_to_ycbcr_header_csp(ass_rgb))
with rgb_to_ycbcr_header_csp defaulting to TV-range BT.601.
XySubFilter, whose API was planned during introduction of this header, is not affected by this VSFilter-API limitation, so for it and other renderers like libass an additional special value "None" was also added. "None" tells the renderer to directly use untouched RGB values without any conversion. The above mangling process with special value "None" to opt out of any colour mangling is the recommended default behaviour.
Keep in mind though, that xy-VSFilter cannot accurately implement this and will instead resort to a guessing the video colorspace based on resolution and then convert RGB to the guessed space. Also some versions of MPC-HC's Internal Subtitle Renderer don't (explicitly) implement "None", but use xy-VSFilter-like resolution-based guessing for unknown values or no header at all (which ofc also breaks old subtitles).
Aegisub's (the main application to produce ASS subtitle scripts) behaviour regarding colorspaces is unfortunately a bit confusing. As of time of writing there still is a config option to force BT.601(TV) in some active forks (which should not be used to author subs and serves at most as a tool to check how now ancient VSFilters would have rendered the subs), the automatically chosen colorspace may depend on the fork and the videoprovider used and furthermore Aegisub likes to override "YCbCr Matrix: None" with the autodetected space of a loaded video. Supposedly some Aegisub versions had an option that "tries not to mangle the colors". It was said that if the header is not set to BT.601(TV), the colors were supposed not to be mangled, even if the header was not set to "None".
In general, misinterpreting this header or not using it will lead to slightly different subtitle colors, which can matter if the subtitle attempts to match solid colored areas in the video. It is recommended to stick to XySubFilter-like behaviour described above. A highly motivated application may also expose options to users to emulate xy-VSFilter's resolution-depended guess or other (historic) mangling modes. Completly ignoring the color mangling is likely to give bad results.
Note that libass doesn't change colors based on this header. It absolutely can't do that, because the video colorspace is required in order to handle this as intended. API users must use the exposed information to perform color mangling as described above.
Constructors
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Constants
- YCBCR_BT601_PC → const int
- YCBCR_BT601_TV → const int
- YCBCR_BT709_PC → const int
- YCBCR_BT709_TV → const int
- YCBCR_DEFAULT → const int
- Header missing
- YCBCR_FCC_PC → const int
- YCBCR_FCC_TV → const int
- YCBCR_NONE → const int
- "None" special value
- YCBCR_SMPTE240M_PC → const int
- YCBCR_SMPTE240M_TV → const int
- YCBCR_UNKNOWN → const int
- Header could not be parsed correctly