From ff6e3c025658a5fa1affd094f220b623e7e1b24b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 22:38:23 +0200 Subject: Adding upstream version 6.338.2. Signed-off-by: Daniel Baumann --- src/include/libplacebo/shaders/colorspace.h | 381 ++++++++++++++++++++++++++++ 1 file changed, 381 insertions(+) create mode 100644 src/include/libplacebo/shaders/colorspace.h (limited to 'src/include/libplacebo/shaders/colorspace.h') diff --git a/src/include/libplacebo/shaders/colorspace.h b/src/include/libplacebo/shaders/colorspace.h new file mode 100644 index 0000000..ead0958 --- /dev/null +++ b/src/include/libplacebo/shaders/colorspace.h @@ -0,0 +1,381 @@ +/* + * This file is part of libplacebo. + * + * libplacebo is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libplacebo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libplacebo. If not, see . + */ + +#ifndef LIBPLACEBO_SHADERS_COLORSPACE_H_ +#define LIBPLACEBO_SHADERS_COLORSPACE_H_ + +// Color space transformation shaders. These all input and output a color +// value (PL_SHADER_SIG_COLOR). + +#include +#include +#include +#include + +// For backwards compatibility +#include + +PL_API_BEGIN + +// Transform the input color, in its given representation, to ensure +// compatibility with the indicated alpha mode. Mutates `repr` to reflect the +// change. Note that this is a no-op if the input is PL_ALPHA_UNKNOWN. +PL_API void pl_shader_set_alpha(pl_shader sh, struct pl_color_repr *repr, + enum pl_alpha_mode mode); + +// Colorspace reshaping for PL_COLOR_SYSTEM_DOLBYVISION. Note that this is done +// automatically by `pl_shader_decode_color` for PL_COLOR_SYSTEM_DOLBYVISION. +PL_API void pl_shader_dovi_reshape(pl_shader sh, const struct pl_dovi_metadata *data); + +// Decode the color into normalized RGB, given a specified color_repr. This +// also takes care of additional pre- and post-conversions requires for the +// "special" color systems (XYZ, BT.2020-C, etc.). If `params` is left as NULL, +// it defaults to &pl_color_adjustment_neutral. +// +// Note: This function always returns PC-range RGB with independent alpha. +// It mutates the pl_color_repr to reflect the change. +// +// Note: For DCDM XYZ decoding output is linear +PL_API void pl_shader_decode_color(pl_shader sh, struct pl_color_repr *repr, + const struct pl_color_adjustment *params); + +// Encodes a color from normalized, PC-range, independent alpha RGB into a +// given representation. That is, this performs the inverse operation of +// `pl_shader_decode_color` (sans color adjustments). +// +// Note: For DCDM XYZ encoding input is expected to be linear +PL_API void pl_shader_encode_color(pl_shader sh, const struct pl_color_repr *repr); + +// Linearize (expand) `vec4 color`, given a specified color space. In essence, +// this corresponds to the ITU-R EOTF. +// +// Note: Unlike the ITU-R EOTF, it never includes the OOTF - even for systems +// where the EOTF includes the OOTF (such as HLG). +PL_API void pl_shader_linearize(pl_shader sh, const struct pl_color_space *csp); + +// Delinearize (compress), given a color space as output. This loosely +// corresponds to the inverse EOTF (not the OETF) in ITU-R terminology, again +// assuming a reference monitor. +PL_API void pl_shader_delinearize(pl_shader sh, const struct pl_color_space *csp); + +struct pl_sigmoid_params { + // The center (bias) of the sigmoid curve. Must be between 0.0 and 1.0. + // If left as NULL, defaults to 0.75 + float center; + + // The slope (steepness) of the sigmoid curve. Must be between 1.0 and 20.0. + // If left as NULL, defaults to 6.5. + float slope; +}; + +#define PL_SIGMOID_DEFAULTS \ + .center = 0.75, \ + .slope = 6.50, + +#define pl_sigmoid_params(...) (&(struct pl_sigmoid_params) { PL_SIGMOID_DEFAULTS __VA_ARGS__ }) +PL_API extern const struct pl_sigmoid_params pl_sigmoid_default_params; + +// Applies a sigmoidal color transform to all channels. This helps avoid +// ringing artifacts during upscaling by bringing the color information closer +// to neutral and away from the extremes. If `params` is NULL, it defaults to +// &pl_sigmoid_default_params. +// +// Warning: This function clamps the input to the interval [0,1]; and as such +// it should *NOT* be used on already-decoded high-dynamic range content. +PL_API void pl_shader_sigmoidize(pl_shader sh, const struct pl_sigmoid_params *params); + +// This performs the inverse operation to `pl_shader_sigmoidize`. +PL_API void pl_shader_unsigmoidize(pl_shader sh, const struct pl_sigmoid_params *params); + +struct pl_peak_detect_params { + // Smoothing coefficient for the detected values. This controls the time + // parameter (tau) of an IIR low pass filter. In other words, it represent + // the cutoff period (= 1 / cutoff frequency) in frames. Frequencies below + // this length will be suppressed. This helps block out annoying + // "sparkling" or "flickering" due to small variations in frame-to-frame + // brightness. If left as 0.0, this smoothing is completely disabled. + float smoothing_period; + + // In order to avoid reacting sluggishly on scene changes as a result of + // the low-pass filter, we disable it when the difference between the + // current frame brightness and the average frame brightness exceeds a + // given threshold difference. But rather than a single hard cutoff, which + // would lead to weird discontinuities on fades, we gradually disable it + // over a small window of brightness ranges. These parameters control the + // lower and upper bounds of this window, in units of 1% PQ. + // + // Setting either one of these to 0.0 disables this logic. + float scene_threshold_low; + float scene_threshold_high; + + // Which percentile of the input image brightness histogram to consider as + // the true peak of the scene. If this is set to 100 (or 0), the brightest + // pixel is measured. Otherwise, the top of the frequency distribution is + // progressively cut off. Setting this too low will cause clipping of very + // bright details, but can improve the dynamic brightness range of scenes + // with very bright isolated highlights. + // + // A recommended value is 99.995%, which is very conservative and should + // cause no major issues in typical content. + float percentile; + + // Allows the peak detection result to be delayed by up to a single frame, + // which can sometimes improve thoughput, at the cost of introducing the + // possibility of 1-frame flickers on transitions. Disabled by default. + bool allow_delayed; + + // --- Deprecated / removed fields + float overshoot_margin PL_DEPRECATED; + float minimum_peak PL_DEPRECATED; +}; + +#define PL_PEAK_DETECT_DEFAULTS \ + .smoothing_period = 20.0f, \ + .scene_threshold_low = 1.0f, \ + .scene_threshold_high = 3.0f, \ + .percentile = 100.0f, + +#define PL_PEAK_DETECT_HQ_DEFAULTS \ + PL_PEAK_DETECT_DEFAULTS \ + .percentile = 99.995f, + +#define pl_peak_detect_params(...) (&(struct pl_peak_detect_params) { PL_PEAK_DETECT_DEFAULTS __VA_ARGS__ }) +PL_API extern const struct pl_peak_detect_params pl_peak_detect_default_params; +PL_API extern const struct pl_peak_detect_params pl_peak_detect_high_quality_params; + +// This function can be used to measure the CLL and FALL of a video +// source automatically, using a compute shader. The measured values are +// smoothed automatically (depending on the parameters), so to keep track of +// the measured results over time, a tone mapping shader state object is used +// to hold the state. Returns false on failure initializing the tone mapping +// object, or if compute shaders are not supported. +// +// It's important that the same shader object is used for successive frames +// belonging to the same source. If the source changes (e.g. due to a file +// change or seek), the user should reset it with `pl_reset_detected_peak` (or +// destroy it and use a new state object). +// +// The parameter `csp` holds the representation of the color values that are +// the input to this function. (They must already be in decoded RGB form, i.e. +// alternate color representations are not supported) +PL_API bool pl_shader_detect_peak(pl_shader sh, struct pl_color_space csp, + pl_shader_obj *state, + const struct pl_peak_detect_params *params); + +// After dispatching the above shader, this function can be used to retrieve +// the detected dynamic HDR10+ metadata parameters. The other fields of +// `metadata` are not written to. Returns whether or not any values were +// written. If not, the values are left untouched, so this can be used to +// safely update `pl_hdr_metadata` values in-place. This function may or may +// not block, depending on the previous setting of `allow_delayed`. +PL_API bool pl_get_detected_hdr_metadata(const pl_shader_obj state, + struct pl_hdr_metadata *metadata); + +// After dispatching the above shader, this function *may* be used to read out +// the detected CLL and FALL directly (in PL_HDR_NORM units). If the shader +// has never been dispatched yet, i.e. no information is available, this will +// return false. +// +// Deprecated in favor of `pl_get_detected_hdr_metadata` +PL_DEPRECATED PL_API bool pl_get_detected_peak(const pl_shader_obj state, + float *out_cll, float *out_fall); + +// Resets the peak detection state in a given tone mapping state object. This +// is not equal to `pl_shader_obj_destroy`, because it does not destroy any +// state used by `pl_shader_tone_map`. +PL_API void pl_reset_detected_peak(pl_shader_obj state); + +// Feature map extraction (for pl_color_map_args.feature_map). The result +// of this shader should be downscaled / low-passed to the indicated kernel +// size before use. (This does not happen automatically) +PL_API void pl_shader_extract_features(pl_shader sh, struct pl_color_space csp); + +// Deprecated and unused. Libplacebo now always performs a variant of the old +// hybrid tone-mapping, mixing together the intensity (I) and per-channel (LMS) +// results. +enum pl_tone_map_mode { + PL_TONE_MAP_AUTO PL_DEPRECATED_ENUMERATOR, + PL_TONE_MAP_RGB PL_DEPRECATED_ENUMERATOR, + PL_TONE_MAP_MAX PL_DEPRECATED_ENUMERATOR, + PL_TONE_MAP_HYBRID PL_DEPRECATED_ENUMERATOR, + PL_TONE_MAP_LUMA PL_DEPRECATED_ENUMERATOR, + PL_TONE_MAP_MODE_COUNT, +}; + +// Deprecated by +enum pl_gamut_mode { + PL_GAMUT_CLIP PL_DEPRECATED_ENUMERATOR, // pl_gamut_map_clip + PL_GAMUT_WARN PL_DEPRECATED_ENUMERATOR, // pl_gamut_map_highlight + PL_GAMUT_DARKEN PL_DEPRECATED_ENUMERATOR, // pl_gamut_map_darken + PL_GAMUT_DESATURATE PL_DEPRECATED_ENUMERATOR, // pl_gamut_map_desaturate + PL_GAMUT_MODE_COUNT, +}; + +struct pl_color_map_params { + // --- Gamut mapping options + + // Gamut mapping function to use to handle out-of-gamut colors, including + // colors which are out-of-gamut as a consequence of tone mapping. + const struct pl_gamut_map_function *gamut_mapping; + + // Gamut mapping constants, for expert tuning. Leave as default otherwise. + struct pl_gamut_map_constants gamut_constants; + + // Gamut mapping 3DLUT size, for channels ICh. Defaults to {48, 32, 256} + int lut3d_size[3]; + + // Use higher quality, but slower, tricubic interpolation for gamut mapping + // 3DLUTs. May substantially improve the 3DLUT gamut mapping accuracy, in + // particular at smaller 3DLUT sizes. Shouldn't have much effect at the + // default size. + bool lut3d_tricubic; + + // If true, allows the gamut mapping function to expand the gamut, in + // cases where the target gamut exceeds that of the source. If false, + // the source gamut will never be enlarged, even when using a gamut + // mapping function capable of bidirectional mapping. + bool gamut_expansion; + + // --- Tone mapping options + + // Tone mapping function to use to handle out-of-range colors. + const struct pl_tone_map_function *tone_mapping_function; + + // Tone mapping constants, for expert tuning. Leave as default otherwise. + struct pl_tone_map_constants tone_constants; + + // If true, and supported by the given tone mapping function, libplacebo + // will perform inverse tone mapping to expand the dynamic range of a + // signal. libplacebo is not liable for any HDR-induced eye damage. + bool inverse_tone_mapping; + + // Data source to use when tone-mapping. Setting this to a specific + // value allows overriding the default metadata preference logic. + enum pl_hdr_metadata_type metadata; + + // Tone mapping LUT size. Defaults to 256. + int lut_size; + + // HDR contrast recovery strength. If set to a value above 0.0, the source + // image will be divided into high-frequency and low-frequency components, + // and a portion of the high-frequency image is added back onto the + // tone-mapped output. May cause excessive ringing artifacts for some HDR + // sources, but can improve the subjective sharpness and detail left over + // in the image after tone-mapping. + float contrast_recovery; + + // Contrast recovery lowpass kernel size. Defaults to 3.5. Increasing + // or decreasing this will affect the visual appearance substantially. + float contrast_smoothness; + + // --- Debugging options + + // Force the use of a full tone-mapping LUT even for functions that have + // faster pure GLSL replacements (e.g. clip, linear, saturation). + bool force_tone_mapping_lut; + + // Visualize the tone-mapping LUT and gamut mapping 3DLUT, in IPT space. + bool visualize_lut; + + // Controls where to draw the visualization, relative to the rendered + // video (dimensions 0-1). Optional, defaults to the full picture. + pl_rect2df visualize_rect; + + // Controls the rotation of the 3DLUT visualization. + float visualize_hue; // useful range [-pi, pi] + float visualize_theta; // useful range [0, pi/2] + + // Graphically highlight hard-clipped pixels during tone-mapping (i.e. + // pixels that exceed the claimed source luminance range). + bool show_clipping; + + // --- Deprecated fields + enum pl_tone_map_mode tone_mapping_mode PL_DEPRECATED; // removed + float tone_mapping_param PL_DEPRECATED; // see `tone_constants` + float tone_mapping_crosstalk PL_DEPRECATED; // now hard-coded as 0.04 + enum pl_rendering_intent intent PL_DEPRECATED; // see `gamut_mapping` + enum pl_gamut_mode gamut_mode PL_DEPRECATED; // see `gamut_mapping` + float hybrid_mix PL_DEPRECATED; // removed +}; + +#define PL_COLOR_MAP_DEFAULTS \ + .gamut_mapping = &pl_gamut_map_perceptual, \ + .tone_mapping_function = &pl_tone_map_spline, \ + .gamut_constants = { PL_GAMUT_MAP_CONSTANTS }, \ + .tone_constants = { PL_TONE_MAP_CONSTANTS }, \ + .metadata = PL_HDR_METADATA_ANY, \ + .lut3d_size = {48, 32, 256}, \ + .lut_size = 256, \ + .visualize_rect = {0, 0, 1, 1}, \ + .contrast_smoothness = 3.5f, + +#define PL_COLOR_MAP_HQ_DEFAULTS \ + PL_COLOR_MAP_DEFAULTS \ + .contrast_recovery = 0.30f, + +#define pl_color_map_params(...) (&(struct pl_color_map_params) { PL_COLOR_MAP_DEFAULTS __VA_ARGS__ }) +PL_API extern const struct pl_color_map_params pl_color_map_default_params; +PL_API extern const struct pl_color_map_params pl_color_map_high_quality_params; + +// Execution arguments for the `pl_shader_color_map_ex` call. Distinct from +// `pl_color_map_params` because it is filled by internally-provided execution +// metadata, instead of user-tunable aesthetic parameters. +struct pl_color_map_args { + // Input/output color space for the mapping. + struct pl_color_space src; + struct pl_color_space dst; + + // If true, the logic will assume the input has already been linearized by + // the caller (e.g. as part of a previous linear light scaling operation). + bool prelinearized; + + // Object to be used to store generated LUTs. Note that this is the same + // state object used by `pl_shader_detect_peak`, and if that function has + // been called on `state` prior to `pl_shader_color_map`, the detected + // values will be used to guide the tone mapping algorithm. If this is not + // provided, tone/gamut mapping are disabled. + pl_shader_obj *state; + + // Low-resolution intensity feature map, as generated by + // `pl_shader_extract_features`. Optional. No effect if + // `params->contrast_recovery` is disabled. + pl_tex feature_map; +}; + +#define pl_color_map_args(...) (&(struct pl_color_map_args) { __VA_ARGS__ }) + +// Maps `vec4 color` from one color space to another color space according +// to the parameters (described in greater depth above). If `params` is left +// as NULL, it defaults to `&pl_color_map_default_params` +PL_API void pl_shader_color_map_ex(pl_shader sh, + const struct pl_color_map_params *params, + const struct pl_color_map_args *args); + +// Backwards compatibility wrapper around `pl_shader_color_map_ex` +PL_API void pl_shader_color_map(pl_shader sh, const struct pl_color_map_params *params, + struct pl_color_space src, struct pl_color_space dst, + pl_shader_obj *state, bool prelinearized); + +// Applies a set of cone distortion parameters to `vec4 color` in a given color +// space. This can be used to simulate color blindness. See `pl_cone_params` +// for more information. +PL_API void pl_shader_cone_distort(pl_shader sh, struct pl_color_space csp, + const struct pl_cone_params *params); + +PL_API_END + +#endif // LIBPLACEBO_SHADERS_COLORSPACE_H_ -- cgit v1.2.3