mirror of https://github.com/mpv-player/mpv
csputils: replace mp_colorspace with pl_color_space
This commit is contained in:
parent
9dd1a13747
commit
66e451f4e6
|
@ -36,6 +36,8 @@
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavcodec/version.h>
|
#include <libavcodec/version.h>
|
||||||
|
|
||||||
|
#include <libplacebo/utils/libav.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if HAVE_ZLIB
|
#if HAVE_ZLIB
|
||||||
|
@ -108,7 +110,8 @@ typedef struct mkv_track {
|
||||||
double v_frate;
|
double v_frate;
|
||||||
uint32_t colorspace;
|
uint32_t colorspace;
|
||||||
int stereo_mode;
|
int stereo_mode;
|
||||||
struct mp_colorspace color;
|
struct pl_color_repr repr;
|
||||||
|
struct pl_color_space color;
|
||||||
uint32_t v_crop_top, v_crop_left, v_crop_right, v_crop_bottom;
|
uint32_t v_crop_top, v_crop_left, v_crop_right, v_crop_bottom;
|
||||||
float v_projection_pose_roll;
|
float v_projection_pose_roll;
|
||||||
bool v_projection_pose_roll_set;
|
bool v_projection_pose_roll_set;
|
||||||
|
@ -573,24 +576,24 @@ static void parse_trackcolour(struct demuxer *demuxer, struct mkv_track *track,
|
||||||
// 23001-8:2013/DCOR1, which is the same order used by libavutil/pixfmt.h,
|
// 23001-8:2013/DCOR1, which is the same order used by libavutil/pixfmt.h,
|
||||||
// so we can just re-use our avcol_ conversion functions.
|
// so we can just re-use our avcol_ conversion functions.
|
||||||
if (colour->n_matrix_coefficients) {
|
if (colour->n_matrix_coefficients) {
|
||||||
track->color.space = avcol_spc_to_mp_csp(colour->matrix_coefficients);
|
track->repr.sys = pl_system_from_av(colour->matrix_coefficients);
|
||||||
MP_DBG(demuxer, "| + Matrix: %s\n",
|
MP_DBG(demuxer, "| + Matrix: %s\n",
|
||||||
m_opt_choice_str(mp_csp_names, track->color.space));
|
m_opt_choice_str(pl_csp_names, track->repr.sys));
|
||||||
}
|
}
|
||||||
if (colour->n_primaries) {
|
if (colour->n_primaries) {
|
||||||
track->color.primaries = avcol_pri_to_mp_csp_prim(colour->primaries);
|
track->color.primaries = pl_primaries_from_av(colour->primaries);
|
||||||
MP_DBG(demuxer, "| + Primaries: %s\n",
|
MP_DBG(demuxer, "| + Primaries: %s\n",
|
||||||
m_opt_choice_str(mp_csp_prim_names, track->color.primaries));
|
m_opt_choice_str(pl_csp_prim_names, track->color.primaries));
|
||||||
}
|
}
|
||||||
if (colour->n_transfer_characteristics) {
|
if (colour->n_transfer_characteristics) {
|
||||||
track->color.gamma = avcol_trc_to_mp_csp_trc(colour->transfer_characteristics);
|
track->color.transfer = pl_transfer_from_av(colour->transfer_characteristics);
|
||||||
MP_DBG(demuxer, "| + Gamma: %s\n",
|
MP_DBG(demuxer, "| + Gamma: %s\n",
|
||||||
m_opt_choice_str(mp_csp_trc_names, track->color.gamma));
|
m_opt_choice_str(pl_csp_trc_names, track->color.transfer));
|
||||||
}
|
}
|
||||||
if (colour->n_range) {
|
if (colour->n_range) {
|
||||||
track->color.levels = avcol_range_to_mp_csp_levels(colour->range);
|
track->repr.levels = pl_levels_from_av(colour->range);
|
||||||
MP_DBG(demuxer, "| + Levels: %s\n",
|
MP_DBG(demuxer, "| + Levels: %s\n",
|
||||||
m_opt_choice_str(mp_csp_levels_names, track->color.levels));
|
m_opt_choice_str(pl_csp_levels_names, track->repr.levels));
|
||||||
}
|
}
|
||||||
if (colour->n_max_cll) {
|
if (colour->n_max_cll) {
|
||||||
track->color.hdr.max_cll = colour->max_cll;
|
track->color.hdr.max_cll = colour->max_cll;
|
||||||
|
|
|
@ -105,8 +105,9 @@ struct mp_codec_params {
|
||||||
int disp_w, disp_h; // display size
|
int disp_w, disp_h; // display size
|
||||||
int rotate; // intended display rotation, in degrees, [0, 359]
|
int rotate; // intended display rotation, in degrees, [0, 359]
|
||||||
int stereo_mode; // mp_stereo3d_mode (0 if none/unknown)
|
int stereo_mode; // mp_stereo3d_mode (0 if none/unknown)
|
||||||
struct mp_colorspace color; // colorspace info where available
|
struct pl_color_space color; // colorspace info where available
|
||||||
struct mp_rect crop; // crop to be applied
|
struct pl_color_repr repr; // color representaion info where available
|
||||||
|
struct mp_rect crop; // crop to be applied
|
||||||
|
|
||||||
// STREAM_VIDEO + STREAM_AUDIO
|
// STREAM_VIDEO + STREAM_AUDIO
|
||||||
int bits_per_coded_sample;
|
int bits_per_coded_sample;
|
||||||
|
|
|
@ -618,7 +618,8 @@ static void fix_image_params(struct priv *p,
|
||||||
m.rotate = (m.rotate + opts->video_rotate) % 360;
|
m.rotate = (m.rotate + opts->video_rotate) % 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_colorspace_merge(&m.color, &c->color);
|
pl_color_space_merge(&m.color, &c->color);
|
||||||
|
pl_color_repr_merge(&m.repr, &c->repr);
|
||||||
|
|
||||||
// Guess missing colorspace fields from metadata. This guarantees all
|
// Guess missing colorspace fields from metadata. This guarantees all
|
||||||
// fields are at least set to legal values afterwards.
|
// fields are at least set to legal values afterwards.
|
||||||
|
|
|
@ -2341,16 +2341,16 @@ static int property_imgparams(const struct mp_image_params *p, int action, void
|
||||||
{"sar", SUB_PROP_FLOAT(p->w / (double)p->h)},
|
{"sar", SUB_PROP_FLOAT(p->w / (double)p->h)},
|
||||||
{"sar-name", SUB_PROP_STR(sar_name), .unavailable = !sar_name},
|
{"sar-name", SUB_PROP_STR(sar_name), .unavailable = !sar_name},
|
||||||
{"colormatrix",
|
{"colormatrix",
|
||||||
SUB_PROP_STR(m_opt_choice_str(mp_csp_names, p->color.space))},
|
SUB_PROP_STR(m_opt_choice_str(pl_csp_names, p->repr.sys))},
|
||||||
{"colorlevels",
|
{"colorlevels",
|
||||||
SUB_PROP_STR(m_opt_choice_str(mp_csp_levels_names, p->color.levels))},
|
SUB_PROP_STR(m_opt_choice_str(pl_csp_levels_names, p->repr.levels))},
|
||||||
{"primaries",
|
{"primaries",
|
||||||
SUB_PROP_STR(m_opt_choice_str(mp_csp_prim_names, p->color.primaries))},
|
SUB_PROP_STR(m_opt_choice_str(pl_csp_prim_names, p->color.primaries))},
|
||||||
{"gamma",
|
{"gamma",
|
||||||
SUB_PROP_STR(m_opt_choice_str(mp_csp_trc_names, p->color.gamma))},
|
SUB_PROP_STR(m_opt_choice_str(pl_csp_trc_names, p->color.transfer))},
|
||||||
{"sig-peak", SUB_PROP_FLOAT(p->color.hdr.max_luma / MP_REF_WHITE)},
|
{"sig-peak", SUB_PROP_FLOAT(p->color.hdr.max_luma / MP_REF_WHITE)},
|
||||||
{"light",
|
{"light",
|
||||||
SUB_PROP_STR(m_opt_choice_str(mp_csp_light_names, p->color.light))},
|
SUB_PROP_STR(m_opt_choice_str(mp_csp_light_names, p->light))},
|
||||||
{"chroma-location",
|
{"chroma-location",
|
||||||
SUB_PROP_STR(m_opt_choice_str(mp_chroma_names, p->chroma_location))},
|
SUB_PROP_STR(m_opt_choice_str(mp_chroma_names, p->chroma_location))},
|
||||||
{"stereo-in",
|
{"stereo-in",
|
||||||
|
|
|
@ -546,7 +546,7 @@ static bool reinit_to_video(struct mp_draw_sub_cache *p)
|
||||||
mp_get_regular_imgfmt(&vfdesc, mp_repack_get_format_dst(p->video_to_f32));
|
mp_get_regular_imgfmt(&vfdesc, mp_repack_get_format_dst(p->video_to_f32));
|
||||||
assert(vfdesc.num_planes); // must have succeeded
|
assert(vfdesc.num_planes); // must have succeeded
|
||||||
|
|
||||||
if (params->color.space == MP_CSP_RGB && vfdesc.num_planes >= 3) {
|
if (params->repr.sys == PL_COLOR_SYSTEM_RGB && vfdesc.num_planes >= 3) {
|
||||||
use_shortcut = true;
|
use_shortcut = true;
|
||||||
|
|
||||||
if (vfdesc.component_type == MP_COMPONENT_TYPE_UINT &&
|
if (vfdesc.component_type == MP_COMPONENT_TYPE_UINT &&
|
||||||
|
@ -724,7 +724,7 @@ static bool reinit_to_video(struct mp_draw_sub_cache *p)
|
||||||
p->alpha_overlay->stride[0] = p->video_overlay->stride[aplane];
|
p->alpha_overlay->stride[0] = p->video_overlay->stride[aplane];
|
||||||
|
|
||||||
// Full range gray always has the same range as alpha.
|
// Full range gray always has the same range as alpha.
|
||||||
p->alpha_overlay->params.color.levels = MP_CSP_LEVELS_PC;
|
p->alpha_overlay->params.repr.levels = PL_COLOR_LEVELS_FULL;
|
||||||
mp_image_params_guess_csp(&p->alpha_overlay->params);
|
mp_image_params_guess_csp(&p->alpha_overlay->params);
|
||||||
|
|
||||||
p->calpha_overlay =
|
p->calpha_overlay =
|
||||||
|
|
66
sub/sd_ass.c
66
sub/sd_ass.c
|
@ -888,27 +888,27 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
|
||||||
{
|
{
|
||||||
struct mp_subtitle_opts *opts = sd->opts;
|
struct mp_subtitle_opts *opts = sd->opts;
|
||||||
struct sd_ass_priv *ctx = sd->priv;
|
struct sd_ass_priv *ctx = sd->priv;
|
||||||
enum mp_csp csp = 0;
|
enum pl_color_system csp = 0;
|
||||||
enum mp_csp_levels levels = 0;
|
enum pl_color_levels levels = 0;
|
||||||
if (opts->ass_vsfilter_color_compat == 0) // "no"
|
if (opts->ass_vsfilter_color_compat == 0) // "no"
|
||||||
return;
|
return;
|
||||||
bool force_601 = opts->ass_vsfilter_color_compat == 3;
|
bool force_601 = opts->ass_vsfilter_color_compat == 3;
|
||||||
ASS_Track *track = ctx->ass_track;
|
ASS_Track *track = ctx->ass_track;
|
||||||
static const int ass_csp[] = {
|
static const int ass_csp[] = {
|
||||||
[YCBCR_BT601_TV] = MP_CSP_BT_601,
|
[YCBCR_BT601_TV] = PL_COLOR_SYSTEM_BT_601,
|
||||||
[YCBCR_BT601_PC] = MP_CSP_BT_601,
|
[YCBCR_BT601_PC] = PL_COLOR_SYSTEM_BT_601,
|
||||||
[YCBCR_BT709_TV] = MP_CSP_BT_709,
|
[YCBCR_BT709_TV] = PL_COLOR_SYSTEM_BT_709,
|
||||||
[YCBCR_BT709_PC] = MP_CSP_BT_709,
|
[YCBCR_BT709_PC] = PL_COLOR_SYSTEM_BT_709,
|
||||||
[YCBCR_SMPTE240M_TV] = MP_CSP_SMPTE_240M,
|
[YCBCR_SMPTE240M_TV] = PL_COLOR_SYSTEM_SMPTE_240M,
|
||||||
[YCBCR_SMPTE240M_PC] = MP_CSP_SMPTE_240M,
|
[YCBCR_SMPTE240M_PC] = PL_COLOR_SYSTEM_SMPTE_240M,
|
||||||
};
|
};
|
||||||
static const int ass_levels[] = {
|
static const int ass_levels[] = {
|
||||||
[YCBCR_BT601_TV] = MP_CSP_LEVELS_TV,
|
[YCBCR_BT601_TV] = PL_COLOR_LEVELS_LIMITED,
|
||||||
[YCBCR_BT601_PC] = MP_CSP_LEVELS_PC,
|
[YCBCR_BT601_PC] = PL_COLOR_LEVELS_FULL,
|
||||||
[YCBCR_BT709_TV] = MP_CSP_LEVELS_TV,
|
[YCBCR_BT709_TV] = PL_COLOR_LEVELS_LIMITED,
|
||||||
[YCBCR_BT709_PC] = MP_CSP_LEVELS_PC,
|
[YCBCR_BT709_PC] = PL_COLOR_LEVELS_FULL,
|
||||||
[YCBCR_SMPTE240M_TV] = MP_CSP_LEVELS_TV,
|
[YCBCR_SMPTE240M_TV] = PL_COLOR_LEVELS_LIMITED,
|
||||||
[YCBCR_SMPTE240M_PC] = MP_CSP_LEVELS_PC,
|
[YCBCR_SMPTE240M_PC] = PL_COLOR_LEVELS_FULL,
|
||||||
};
|
};
|
||||||
int trackcsp = track->YCbCrMatrix;
|
int trackcsp = track->YCbCrMatrix;
|
||||||
if (force_601)
|
if (force_601)
|
||||||
|
@ -921,8 +921,8 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
|
||||||
if (trackcsp < sizeof(ass_levels) / sizeof(ass_levels[0]))
|
if (trackcsp < sizeof(ass_levels) / sizeof(ass_levels[0]))
|
||||||
levels = ass_levels[trackcsp];
|
levels = ass_levels[trackcsp];
|
||||||
if (trackcsp == YCBCR_DEFAULT) {
|
if (trackcsp == YCBCR_DEFAULT) {
|
||||||
csp = MP_CSP_BT_601;
|
csp = PL_COLOR_SYSTEM_BT_601;
|
||||||
levels = MP_CSP_LEVELS_TV;
|
levels = PL_COLOR_LEVELS_LIMITED;
|
||||||
}
|
}
|
||||||
// Unknown colorspace (either YCBCR_UNKNOWN, or a valid value unknown to us)
|
// Unknown colorspace (either YCBCR_UNKNOWN, or a valid value unknown to us)
|
||||||
if (!csp || !levels)
|
if (!csp || !levels)
|
||||||
|
@ -931,42 +931,42 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
|
||||||
struct mp_image_params params = ctx->video_params;
|
struct mp_image_params params = ctx->video_params;
|
||||||
|
|
||||||
if (force_601) {
|
if (force_601) {
|
||||||
params.color = (struct mp_colorspace){
|
params.repr = (struct pl_color_repr){
|
||||||
.space = MP_CSP_BT_709,
|
.sys = PL_COLOR_SYSTEM_BT_709,
|
||||||
.levels = MP_CSP_LEVELS_TV,
|
.levels = PL_COLOR_LEVELS_LIMITED,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((csp == params.color.space && levels == params.color.levels) ||
|
if ((csp == params.repr.sys && levels == params.repr.levels) ||
|
||||||
params.color.space == MP_CSP_RGB) // Even VSFilter doesn't mangle on RGB video
|
params.repr.sys == PL_COLOR_SYSTEM_RGB) // Even VSFilter doesn't mangle on RGB video
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool basic_conv = params.color.space == MP_CSP_BT_709 &&
|
bool basic_conv = params.repr.sys == PL_COLOR_SYSTEM_BT_709 &&
|
||||||
params.color.levels == MP_CSP_LEVELS_TV &&
|
params.repr.levels == PL_COLOR_LEVELS_LIMITED &&
|
||||||
csp == MP_CSP_BT_601 &&
|
csp == PL_COLOR_SYSTEM_BT_601 &&
|
||||||
levels == MP_CSP_LEVELS_TV;
|
levels == PL_COLOR_LEVELS_LIMITED;
|
||||||
|
|
||||||
// With "basic", only do as much as needed for basic compatibility.
|
// With "basic", only do as much as needed for basic compatibility.
|
||||||
if (opts->ass_vsfilter_color_compat == 1 && !basic_conv)
|
if (opts->ass_vsfilter_color_compat == 1 && !basic_conv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (params.color.space != ctx->last_params.color.space ||
|
if (params.repr.sys != ctx->last_params.repr.sys ||
|
||||||
params.color.levels != ctx->last_params.color.levels)
|
params.repr.levels != ctx->last_params.repr.levels)
|
||||||
{
|
{
|
||||||
int msgl = basic_conv ? MSGL_V : MSGL_WARN;
|
int msgl = basic_conv ? MSGL_V : MSGL_WARN;
|
||||||
ctx->last_params = params;
|
ctx->last_params = params;
|
||||||
MP_MSG(sd, msgl, "mangling colors like vsfilter: "
|
MP_MSG(sd, msgl, "mangling colors like vsfilter: "
|
||||||
"RGB -> %s %s -> %s %s -> RGB\n",
|
"RGB -> %s %s -> %s %s -> RGB\n",
|
||||||
m_opt_choice_str(mp_csp_names, csp),
|
m_opt_choice_str(pl_csp_names, csp),
|
||||||
m_opt_choice_str(mp_csp_levels_names, levels),
|
m_opt_choice_str(pl_csp_levels_names, levels),
|
||||||
m_opt_choice_str(mp_csp_names, params.color.space),
|
m_opt_choice_str(pl_csp_names, params.repr.sys),
|
||||||
m_opt_choice_str(mp_csp_names, params.color.levels));
|
m_opt_choice_str(pl_csp_names, params.repr.levels));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conversion that VSFilter would use
|
// Conversion that VSFilter would use
|
||||||
struct mp_csp_params vs_params = MP_CSP_PARAMS_DEFAULTS;
|
struct mp_csp_params vs_params = MP_CSP_PARAMS_DEFAULTS;
|
||||||
vs_params.color.space = csp;
|
vs_params.repr.sys = csp;
|
||||||
vs_params.color.levels = levels;
|
vs_params.repr.levels = levels;
|
||||||
struct mp_cmat vs_yuv2rgb, vs_rgb2yuv;
|
struct mp_cmat vs_yuv2rgb, vs_rgb2yuv;
|
||||||
mp_get_csp_matrix(&vs_params, &vs_yuv2rgb);
|
mp_get_csp_matrix(&vs_params, &vs_yuv2rgb);
|
||||||
mp_invert_cmat(&vs_rgb2yuv, &vs_yuv2rgb);
|
mp_invert_cmat(&vs_rgb2yuv, &vs_yuv2rgb);
|
||||||
|
|
|
@ -40,7 +40,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
int fcsp = mp_imgfmt_get_forced_csp(mpfmt);
|
int fcsp = mp_imgfmt_get_forced_csp(mpfmt);
|
||||||
if (fcsp)
|
if (fcsp)
|
||||||
fprintf(f, "fcsp=%s ", m_opt_choice_str(mp_csp_names, fcsp));
|
fprintf(f, "fcsp=%s ", m_opt_choice_str(pl_csp_names, fcsp));
|
||||||
fprintf(f, "ctype=%s\n", comp_type(mp_imgfmt_get_component_type(mpfmt)));
|
fprintf(f, "ctype=%s\n", comp_type(mp_imgfmt_get_component_type(mpfmt)));
|
||||||
|
|
||||||
struct mp_imgfmt_desc d = mp_imgfmt_get_desc(mpfmt);
|
struct mp_imgfmt_desc d = mp_imgfmt_get_desc(mpfmt);
|
||||||
|
|
|
@ -326,8 +326,8 @@ static int try_repack(FILE *f, int imgfmt, int flags, int not_if_fmt)
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_float_repack(int imgfmt, enum mp_csp csp,
|
static void check_float_repack(int imgfmt, enum pl_color_system csp,
|
||||||
enum mp_csp_levels levels)
|
enum pl_color_levels levels)
|
||||||
{
|
{
|
||||||
imgfmt = UNFUCK(imgfmt);
|
imgfmt = UNFUCK(imgfmt);
|
||||||
|
|
||||||
|
@ -349,12 +349,12 @@ static void check_float_repack(int imgfmt, enum mp_csp csp,
|
||||||
struct mp_image *src = mp_image_alloc(imgfmt, w, 1);
|
struct mp_image *src = mp_image_alloc(imgfmt, w, 1);
|
||||||
assert(src);
|
assert(src);
|
||||||
|
|
||||||
src->params.color.space = csp;
|
src->params.repr.sys = csp;
|
||||||
src->params.color.levels = levels;
|
src->params.repr.levels = levels;
|
||||||
mp_image_params_guess_csp(&src->params);
|
mp_image_params_guess_csp(&src->params);
|
||||||
// mpv may not allow all combinations
|
// mpv may not allow all combinations
|
||||||
assert(src->params.color.space == csp);
|
assert(src->params.repr.sys == csp);
|
||||||
assert(src->params.color.levels == levels);
|
assert(src->params.repr.levels == levels);
|
||||||
|
|
||||||
for (int p = 0; p < src->num_planes; p++) {
|
for (int p = 0; p < src->num_planes; p++) {
|
||||||
int val = 0;
|
int val = 0;
|
||||||
|
@ -384,6 +384,8 @@ static void check_float_repack(int imgfmt, enum mp_csp csp,
|
||||||
|
|
||||||
z_f->params.color = r_f->params.color = z_i->params.color =
|
z_f->params.color = r_f->params.color = z_i->params.color =
|
||||||
r_i->params.color = src->params.color;
|
r_i->params.color = src->params.color;
|
||||||
|
z_f->params.repr = r_f->params.repr = z_i->params.repr =
|
||||||
|
r_i->params.repr = src->params.repr;
|
||||||
|
|
||||||
// The idea is to use zimg to cross-check conversion.
|
// The idea is to use zimg to cross-check conversion.
|
||||||
struct mp_sws_context *s = mp_sws_alloc(NULL);
|
struct mp_sws_context *s = mp_sws_alloc(NULL);
|
||||||
|
@ -503,15 +505,15 @@ int main(int argc, char *argv[])
|
||||||
assert_text_files_equal(refdir, outdir, "repack.txt",
|
assert_text_files_equal(refdir, outdir, "repack.txt",
|
||||||
"This can fail if FFmpeg/libswscale adds or removes pixfmts.");
|
"This can fail if FFmpeg/libswscale adds or removes pixfmts.");
|
||||||
|
|
||||||
check_float_repack(-AV_PIX_FMT_GBRAP, MP_CSP_RGB, MP_CSP_LEVELS_PC);
|
check_float_repack(-AV_PIX_FMT_GBRAP, PL_COLOR_SYSTEM_RGB, PL_COLOR_LEVELS_FULL);
|
||||||
check_float_repack(-AV_PIX_FMT_GBRAP10, MP_CSP_RGB, MP_CSP_LEVELS_PC);
|
check_float_repack(-AV_PIX_FMT_GBRAP10, PL_COLOR_SYSTEM_RGB, PL_COLOR_LEVELS_FULL);
|
||||||
check_float_repack(-AV_PIX_FMT_GBRAP16, MP_CSP_RGB, MP_CSP_LEVELS_PC);
|
check_float_repack(-AV_PIX_FMT_GBRAP16, PL_COLOR_SYSTEM_RGB, PL_COLOR_LEVELS_FULL);
|
||||||
check_float_repack(-AV_PIX_FMT_YUVA444P, MP_CSP_BT_709, MP_CSP_LEVELS_PC);
|
check_float_repack(-AV_PIX_FMT_YUVA444P, PL_COLOR_SYSTEM_BT_709, PL_COLOR_LEVELS_FULL);
|
||||||
check_float_repack(-AV_PIX_FMT_YUVA444P, MP_CSP_BT_709, MP_CSP_LEVELS_TV);
|
check_float_repack(-AV_PIX_FMT_YUVA444P, PL_COLOR_SYSTEM_BT_709, PL_COLOR_LEVELS_LIMITED);
|
||||||
check_float_repack(-AV_PIX_FMT_YUVA444P10, MP_CSP_BT_709, MP_CSP_LEVELS_PC);
|
check_float_repack(-AV_PIX_FMT_YUVA444P10, PL_COLOR_SYSTEM_BT_709, PL_COLOR_LEVELS_FULL);
|
||||||
check_float_repack(-AV_PIX_FMT_YUVA444P10, MP_CSP_BT_709, MP_CSP_LEVELS_TV);
|
check_float_repack(-AV_PIX_FMT_YUVA444P10, PL_COLOR_SYSTEM_BT_709, PL_COLOR_LEVELS_LIMITED);
|
||||||
check_float_repack(-AV_PIX_FMT_YUVA444P16, MP_CSP_BT_709, MP_CSP_LEVELS_PC);
|
check_float_repack(-AV_PIX_FMT_YUVA444P16, PL_COLOR_SYSTEM_BT_709, PL_COLOR_LEVELS_FULL);
|
||||||
check_float_repack(-AV_PIX_FMT_YUVA444P16, MP_CSP_BT_709, MP_CSP_LEVELS_TV);
|
check_float_repack(-AV_PIX_FMT_YUVA444P16, PL_COLOR_SYSTEM_BT_709, PL_COLOR_LEVELS_LIMITED);
|
||||||
|
|
||||||
// Determine the list of possible draw_bmp input formats. Do this here
|
// Determine the list of possible draw_bmp input formats. Do this here
|
||||||
// because it mostly depends on repack and imgformat stuff.
|
// because it mostly depends on repack and imgformat stuff.
|
||||||
|
|
|
@ -10,7 +10,7 @@ static struct mp_image *gen_repack_test_img(int w, int h, int bytes, bool rgb,
|
||||||
struct mp_regular_imgfmt planar_desc = {
|
struct mp_regular_imgfmt planar_desc = {
|
||||||
.component_type = MP_COMPONENT_TYPE_UINT,
|
.component_type = MP_COMPONENT_TYPE_UINT,
|
||||||
.component_size = bytes,
|
.component_size = bytes,
|
||||||
.forced_csp = rgb ? MP_CSP_RGB : 0,
|
.forced_csp = rgb ? PL_COLOR_SYSTEM_RGB : 0,
|
||||||
.num_planes = alpha ? 4 : 3,
|
.num_planes = alpha ? 4 : 3,
|
||||||
.planes = {
|
.planes = {
|
||||||
{1, {rgb ? 2 : 1}},
|
{1, {rgb ? 2 : 1}},
|
||||||
|
@ -129,7 +129,7 @@ void repack_test_run(struct scale_test *stest)
|
||||||
if (!mp_get_regular_imgfmt(&rdesc, ofmt))
|
if (!mp_get_regular_imgfmt(&rdesc, ofmt))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (rdesc.num_planes > 1 || rdesc.forced_csp != MP_CSP_RGB)
|
if (rdesc.num_planes > 1 || rdesc.forced_csp != PL_COLOR_SYSTEM_RGB)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct mp_image *test_img = NULL;
|
struct mp_image *test_img = NULL;
|
||||||
|
|
369
video/csputils.c
369
video/csputils.c
|
@ -32,66 +32,66 @@
|
||||||
#include "options/m_config.h"
|
#include "options/m_config.h"
|
||||||
#include "options/m_option.h"
|
#include "options/m_option.h"
|
||||||
|
|
||||||
const struct m_opt_choice_alternatives mp_csp_names[] = {
|
const struct m_opt_choice_alternatives pl_csp_names[] = {
|
||||||
{"auto", MP_CSP_AUTO},
|
{"auto", PL_COLOR_SYSTEM_UNKNOWN},
|
||||||
{"bt.601", MP_CSP_BT_601},
|
{"bt.601", PL_COLOR_SYSTEM_BT_601},
|
||||||
{"bt.709", MP_CSP_BT_709},
|
{"bt.709", PL_COLOR_SYSTEM_BT_709},
|
||||||
{"smpte-240m", MP_CSP_SMPTE_240M},
|
{"smpte-240m", PL_COLOR_SYSTEM_SMPTE_240M},
|
||||||
{"bt.2020-ncl", MP_CSP_BT_2020_NC},
|
{"bt.2020-ncl", PL_COLOR_SYSTEM_BT_2020_NC},
|
||||||
{"bt.2020-cl", MP_CSP_BT_2020_C},
|
{"bt.2020-cl", PL_COLOR_SYSTEM_BT_2020_C},
|
||||||
{"rgb", MP_CSP_RGB},
|
{"rgb", PL_COLOR_SYSTEM_RGB},
|
||||||
{"xyz", MP_CSP_XYZ},
|
{"xyz", PL_COLOR_SYSTEM_XYZ},
|
||||||
{"ycgco", MP_CSP_YCGCO},
|
{"ycgco", PL_COLOR_SYSTEM_YCGCO},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct m_opt_choice_alternatives mp_csp_levels_names[] = {
|
const struct m_opt_choice_alternatives pl_csp_levels_names[] = {
|
||||||
{"auto", MP_CSP_LEVELS_AUTO},
|
{"auto", PL_COLOR_LEVELS_UNKNOWN},
|
||||||
{"limited", MP_CSP_LEVELS_TV},
|
{"limited", PL_COLOR_LEVELS_LIMITED},
|
||||||
{"full", MP_CSP_LEVELS_PC},
|
{"full", PL_COLOR_LEVELS_FULL},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct m_opt_choice_alternatives mp_csp_prim_names[] = {
|
const struct m_opt_choice_alternatives pl_csp_prim_names[] = {
|
||||||
{"auto", MP_CSP_PRIM_AUTO},
|
{"auto", PL_COLOR_PRIM_UNKNOWN},
|
||||||
{"bt.601-525", MP_CSP_PRIM_BT_601_525},
|
{"bt.601-525", PL_COLOR_PRIM_BT_601_525},
|
||||||
{"bt.601-625", MP_CSP_PRIM_BT_601_625},
|
{"bt.601-625", PL_COLOR_PRIM_BT_601_625},
|
||||||
{"bt.709", MP_CSP_PRIM_BT_709},
|
{"bt.709", PL_COLOR_PRIM_BT_709},
|
||||||
{"bt.2020", MP_CSP_PRIM_BT_2020},
|
{"bt.2020", PL_COLOR_PRIM_BT_2020},
|
||||||
{"bt.470m", MP_CSP_PRIM_BT_470M},
|
{"bt.470m", PL_COLOR_PRIM_BT_470M},
|
||||||
{"apple", MP_CSP_PRIM_APPLE},
|
{"apple", PL_COLOR_PRIM_APPLE},
|
||||||
{"adobe", MP_CSP_PRIM_ADOBE},
|
{"adobe", PL_COLOR_PRIM_ADOBE},
|
||||||
{"prophoto", MP_CSP_PRIM_PRO_PHOTO},
|
{"prophoto", PL_COLOR_PRIM_PRO_PHOTO},
|
||||||
{"cie1931", MP_CSP_PRIM_CIE_1931},
|
{"cie1931", PL_COLOR_PRIM_CIE_1931},
|
||||||
{"dci-p3", MP_CSP_PRIM_DCI_P3},
|
{"dci-p3", PL_COLOR_PRIM_DCI_P3},
|
||||||
{"display-p3", MP_CSP_PRIM_DISPLAY_P3},
|
{"display-p3", PL_COLOR_PRIM_DISPLAY_P3},
|
||||||
{"v-gamut", MP_CSP_PRIM_V_GAMUT},
|
{"v-gamut", PL_COLOR_PRIM_V_GAMUT},
|
||||||
{"s-gamut", MP_CSP_PRIM_S_GAMUT},
|
{"s-gamut", PL_COLOR_PRIM_S_GAMUT},
|
||||||
{"ebu3213", MP_CSP_PRIM_EBU_3213},
|
{"ebu3213", PL_COLOR_PRIM_EBU_3213},
|
||||||
{"film-c", MP_CSP_PRIM_FILM_C},
|
{"film-c", PL_COLOR_PRIM_FILM_C},
|
||||||
{"aces-ap0", MP_CSP_PRIM_ACES_AP0},
|
{"aces-ap0", PL_COLOR_PRIM_ACES_AP0},
|
||||||
{"aces-ap1", MP_CSP_PRIM_ACES_AP1},
|
{"aces-ap1", PL_COLOR_PRIM_ACES_AP1},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct m_opt_choice_alternatives mp_csp_trc_names[] = {
|
const struct m_opt_choice_alternatives pl_csp_trc_names[] = {
|
||||||
{"auto", MP_CSP_TRC_AUTO},
|
{"auto", PL_COLOR_TRC_UNKNOWN},
|
||||||
{"bt.1886", MP_CSP_TRC_BT_1886},
|
{"bt.1886", PL_COLOR_TRC_BT_1886},
|
||||||
{"srgb", MP_CSP_TRC_SRGB},
|
{"srgb", PL_COLOR_TRC_SRGB},
|
||||||
{"linear", MP_CSP_TRC_LINEAR},
|
{"linear", PL_COLOR_TRC_LINEAR},
|
||||||
{"gamma1.8", MP_CSP_TRC_GAMMA18},
|
{"gamma1.8", PL_COLOR_TRC_GAMMA18},
|
||||||
{"gamma2.0", MP_CSP_TRC_GAMMA20},
|
{"gamma2.0", PL_COLOR_TRC_GAMMA20},
|
||||||
{"gamma2.2", MP_CSP_TRC_GAMMA22},
|
{"gamma2.2", PL_COLOR_TRC_GAMMA22},
|
||||||
{"gamma2.4", MP_CSP_TRC_GAMMA24},
|
{"gamma2.4", PL_COLOR_TRC_GAMMA24},
|
||||||
{"gamma2.6", MP_CSP_TRC_GAMMA26},
|
{"gamma2.6", PL_COLOR_TRC_GAMMA26},
|
||||||
{"gamma2.8", MP_CSP_TRC_GAMMA28},
|
{"gamma2.8", PL_COLOR_TRC_GAMMA28},
|
||||||
{"prophoto", MP_CSP_TRC_PRO_PHOTO},
|
{"prophoto", PL_COLOR_TRC_PRO_PHOTO},
|
||||||
{"pq", MP_CSP_TRC_PQ},
|
{"pq", PL_COLOR_TRC_PQ},
|
||||||
{"hlg", MP_CSP_TRC_HLG},
|
{"hlg", PL_COLOR_TRC_HLG},
|
||||||
{"v-log", MP_CSP_TRC_V_LOG},
|
{"v-log", PL_COLOR_TRC_V_LOG},
|
||||||
{"s-log1", MP_CSP_TRC_S_LOG1},
|
{"s-log1", PL_COLOR_TRC_S_LOG1},
|
||||||
{"s-log2", MP_CSP_TRC_S_LOG2},
|
{"s-log2", PL_COLOR_TRC_S_LOG2},
|
||||||
{"st428", MP_CSP_TRC_ST428},
|
{"st428", PL_COLOR_TRC_ST428},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,21 +119,6 @@ const struct m_opt_choice_alternatives mp_alpha_names[] = {
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
void mp_colorspace_merge(struct mp_colorspace *orig, struct mp_colorspace *new)
|
|
||||||
{
|
|
||||||
if (!orig->space)
|
|
||||||
orig->space = new->space;
|
|
||||||
if (!orig->levels)
|
|
||||||
orig->levels = new->levels;
|
|
||||||
if (!orig->primaries)
|
|
||||||
orig->primaries = new->primaries;
|
|
||||||
if (!orig->gamma)
|
|
||||||
orig->gamma = new->gamma;
|
|
||||||
if (!orig->light)
|
|
||||||
orig->light = new->light;
|
|
||||||
pl_hdr_metadata_merge(&orig->hdr, &new->hdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The short name _must_ match with what vf_stereo3d accepts (if supported).
|
// The short name _must_ match with what vf_stereo3d accepts (if supported).
|
||||||
// The long name in comments is closer to the Matroska spec (StereoMode element).
|
// The long name in comments is closer to the Matroska spec (StereoMode element).
|
||||||
// The numeric index matches the Matroska StereoMode value. If you add entries
|
// The numeric index matches the Matroska StereoMode value. If you add entries
|
||||||
|
@ -158,139 +143,27 @@ const struct m_opt_choice_alternatives mp_stereo3d_names[] = {
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mp_csp avcol_spc_to_mp_csp(int avcolorspace)
|
enum pl_color_system mp_csp_guess_colorspace(int width, int height)
|
||||||
{
|
{
|
||||||
switch (avcolorspace) {
|
return width >= 1280 || height > 576 ? PL_COLOR_SYSTEM_BT_709 : PL_COLOR_SYSTEM_BT_601;
|
||||||
case AVCOL_SPC_BT709: return MP_CSP_BT_709;
|
|
||||||
case AVCOL_SPC_BT470BG: return MP_CSP_BT_601;
|
|
||||||
case AVCOL_SPC_BT2020_NCL: return MP_CSP_BT_2020_NC;
|
|
||||||
case AVCOL_SPC_BT2020_CL: return MP_CSP_BT_2020_C;
|
|
||||||
case AVCOL_SPC_SMPTE170M: return MP_CSP_BT_601;
|
|
||||||
case AVCOL_SPC_SMPTE240M: return MP_CSP_SMPTE_240M;
|
|
||||||
case AVCOL_SPC_RGB: return MP_CSP_RGB;
|
|
||||||
case AVCOL_SPC_YCOCG: return MP_CSP_YCGCO;
|
|
||||||
default: return MP_CSP_AUTO;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum mp_csp_levels avcol_range_to_mp_csp_levels(int avrange)
|
enum pl_color_primaries mp_csp_guess_primaries(int width, int height)
|
||||||
{
|
|
||||||
switch (avrange) {
|
|
||||||
case AVCOL_RANGE_MPEG: return MP_CSP_LEVELS_TV;
|
|
||||||
case AVCOL_RANGE_JPEG: return MP_CSP_LEVELS_PC;
|
|
||||||
default: return MP_CSP_LEVELS_AUTO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp_prim avcol_pri_to_mp_csp_prim(int avpri)
|
|
||||||
{
|
|
||||||
switch (avpri) {
|
|
||||||
case AVCOL_PRI_SMPTE240M: // Same as below
|
|
||||||
case AVCOL_PRI_SMPTE170M: return MP_CSP_PRIM_BT_601_525;
|
|
||||||
case AVCOL_PRI_BT470BG: return MP_CSP_PRIM_BT_601_625;
|
|
||||||
case AVCOL_PRI_BT709: return MP_CSP_PRIM_BT_709;
|
|
||||||
case AVCOL_PRI_BT2020: return MP_CSP_PRIM_BT_2020;
|
|
||||||
case AVCOL_PRI_BT470M: return MP_CSP_PRIM_BT_470M;
|
|
||||||
case AVCOL_PRI_SMPTE431: return MP_CSP_PRIM_DCI_P3;
|
|
||||||
case AVCOL_PRI_SMPTE432: return MP_CSP_PRIM_DISPLAY_P3;
|
|
||||||
default: return MP_CSP_PRIM_AUTO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp_trc avcol_trc_to_mp_csp_trc(int avtrc)
|
|
||||||
{
|
|
||||||
switch (avtrc) {
|
|
||||||
case AVCOL_TRC_BT709:
|
|
||||||
case AVCOL_TRC_SMPTE170M:
|
|
||||||
case AVCOL_TRC_SMPTE240M:
|
|
||||||
case AVCOL_TRC_BT1361_ECG:
|
|
||||||
case AVCOL_TRC_BT2020_10:
|
|
||||||
case AVCOL_TRC_BT2020_12: return MP_CSP_TRC_BT_1886;
|
|
||||||
case AVCOL_TRC_IEC61966_2_1: return MP_CSP_TRC_SRGB;
|
|
||||||
case AVCOL_TRC_LINEAR: return MP_CSP_TRC_LINEAR;
|
|
||||||
case AVCOL_TRC_GAMMA22: return MP_CSP_TRC_GAMMA22;
|
|
||||||
case AVCOL_TRC_GAMMA28: return MP_CSP_TRC_GAMMA28;
|
|
||||||
case AVCOL_TRC_SMPTEST2084: return MP_CSP_TRC_PQ;
|
|
||||||
case AVCOL_TRC_ARIB_STD_B67: return MP_CSP_TRC_HLG;
|
|
||||||
case AVCOL_TRC_SMPTE428: return MP_CSP_TRC_ST428;
|
|
||||||
default: return MP_CSP_TRC_AUTO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mp_csp_to_avcol_spc(enum mp_csp colorspace)
|
|
||||||
{
|
|
||||||
switch (colorspace) {
|
|
||||||
case MP_CSP_BT_709: return AVCOL_SPC_BT709;
|
|
||||||
case MP_CSP_BT_601: return AVCOL_SPC_BT470BG;
|
|
||||||
case MP_CSP_BT_2020_NC: return AVCOL_SPC_BT2020_NCL;
|
|
||||||
case MP_CSP_BT_2020_C: return AVCOL_SPC_BT2020_CL;
|
|
||||||
case MP_CSP_SMPTE_240M: return AVCOL_SPC_SMPTE240M;
|
|
||||||
case MP_CSP_RGB: return AVCOL_SPC_RGB;
|
|
||||||
case MP_CSP_YCGCO: return AVCOL_SPC_YCOCG;
|
|
||||||
default: return AVCOL_SPC_UNSPECIFIED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mp_csp_levels_to_avcol_range(enum mp_csp_levels range)
|
|
||||||
{
|
|
||||||
switch (range) {
|
|
||||||
case MP_CSP_LEVELS_TV: return AVCOL_RANGE_MPEG;
|
|
||||||
case MP_CSP_LEVELS_PC: return AVCOL_RANGE_JPEG;
|
|
||||||
default: return AVCOL_RANGE_UNSPECIFIED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mp_csp_prim_to_avcol_pri(enum mp_csp_prim prim)
|
|
||||||
{
|
|
||||||
switch (prim) {
|
|
||||||
case MP_CSP_PRIM_BT_601_525: return AVCOL_PRI_SMPTE170M;
|
|
||||||
case MP_CSP_PRIM_BT_601_625: return AVCOL_PRI_BT470BG;
|
|
||||||
case MP_CSP_PRIM_BT_709: return AVCOL_PRI_BT709;
|
|
||||||
case MP_CSP_PRIM_BT_2020: return AVCOL_PRI_BT2020;
|
|
||||||
case MP_CSP_PRIM_BT_470M: return AVCOL_PRI_BT470M;
|
|
||||||
case MP_CSP_PRIM_DCI_P3: return AVCOL_PRI_SMPTE431;
|
|
||||||
case MP_CSP_PRIM_DISPLAY_P3: return AVCOL_PRI_SMPTE432;
|
|
||||||
default: return AVCOL_PRI_UNSPECIFIED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mp_csp_trc_to_avcol_trc(enum mp_csp_trc trc)
|
|
||||||
{
|
|
||||||
switch (trc) {
|
|
||||||
// We just call it BT.1886 since we're decoding, but it's still BT.709
|
|
||||||
case MP_CSP_TRC_BT_1886: return AVCOL_TRC_BT709;
|
|
||||||
case MP_CSP_TRC_SRGB: return AVCOL_TRC_IEC61966_2_1;
|
|
||||||
case MP_CSP_TRC_LINEAR: return AVCOL_TRC_LINEAR;
|
|
||||||
case MP_CSP_TRC_GAMMA22: return AVCOL_TRC_GAMMA22;
|
|
||||||
case MP_CSP_TRC_GAMMA28: return AVCOL_TRC_GAMMA28;
|
|
||||||
case MP_CSP_TRC_PQ: return AVCOL_TRC_SMPTEST2084;
|
|
||||||
case MP_CSP_TRC_HLG: return AVCOL_TRC_ARIB_STD_B67;
|
|
||||||
case MP_CSP_TRC_ST428: return AVCOL_TRC_SMPTE428;
|
|
||||||
default: return AVCOL_TRC_UNSPECIFIED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp mp_csp_guess_colorspace(int width, int height)
|
|
||||||
{
|
|
||||||
return width >= 1280 || height > 576 ? MP_CSP_BT_709 : MP_CSP_BT_601;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp_prim mp_csp_guess_primaries(int width, int height)
|
|
||||||
{
|
{
|
||||||
// HD content
|
// HD content
|
||||||
if (width >= 1280 || height > 576)
|
if (width >= 1280 || height > 576)
|
||||||
return MP_CSP_PRIM_BT_709;
|
return PL_COLOR_PRIM_BT_709;
|
||||||
|
|
||||||
switch (height) {
|
switch (height) {
|
||||||
case 576: // Typical PAL content, including anamorphic/squared
|
case 576: // Typical PAL content, including anamorphic/squared
|
||||||
return MP_CSP_PRIM_BT_601_625;
|
return PL_COLOR_PRIM_BT_601_625;
|
||||||
|
|
||||||
case 480: // Typical NTSC content, including squared
|
case 480: // Typical NTSC content, including squared
|
||||||
case 486: // NTSC Pro or anamorphic NTSC
|
case 486: // NTSC Pro or anamorphic NTSC
|
||||||
return MP_CSP_PRIM_BT_601_525;
|
return PL_COLOR_PRIM_BT_601_525;
|
||||||
|
|
||||||
default: // No good metric, just pick BT.709 to minimize damage
|
default: // No good metric, just pick BT.709 to minimize damage
|
||||||
return MP_CSP_PRIM_BT_709;
|
return PL_COLOR_PRIM_BT_709;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +242,7 @@ static void mp_mul_matrix3x3(float a[3][3], float b[3][3])
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the primaries associated with a certain mp_csp_primaries val
|
// return the primaries associated with a certain mp_csp_primaries val
|
||||||
struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
struct mp_csp_primaries mp_get_csp_primaries(enum pl_color_primaries spc)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Values from: ITU-R Recommendations BT.470-6, BT.601-7, BT.709-5, BT.2020-0
|
Values from: ITU-R Recommendations BT.470-6, BT.601-7, BT.709-5, BT.2020-0
|
||||||
|
@ -391,21 +264,21 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
e = {1.0/3.0, 1.0/3.0};
|
e = {1.0/3.0, 1.0/3.0};
|
||||||
|
|
||||||
switch (spc) {
|
switch (spc) {
|
||||||
case MP_CSP_PRIM_BT_470M:
|
case PL_COLOR_PRIM_BT_470M:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.670, 0.330},
|
.red = {0.670, 0.330},
|
||||||
.green = {0.210, 0.710},
|
.green = {0.210, 0.710},
|
||||||
.blue = {0.140, 0.080},
|
.blue = {0.140, 0.080},
|
||||||
.white = c
|
.white = c
|
||||||
};
|
};
|
||||||
case MP_CSP_PRIM_BT_601_525:
|
case PL_COLOR_PRIM_BT_601_525:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.630, 0.340},
|
.red = {0.630, 0.340},
|
||||||
.green = {0.310, 0.595},
|
.green = {0.310, 0.595},
|
||||||
.blue = {0.155, 0.070},
|
.blue = {0.155, 0.070},
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
case MP_CSP_PRIM_BT_601_625:
|
case PL_COLOR_PRIM_BT_601_625:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.640, 0.330},
|
.red = {0.640, 0.330},
|
||||||
.green = {0.290, 0.600},
|
.green = {0.290, 0.600},
|
||||||
|
@ -414,43 +287,43 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
};
|
};
|
||||||
// This is the default assumption if no colorspace information could
|
// This is the default assumption if no colorspace information could
|
||||||
// be determined, eg. for files which have no video channel.
|
// be determined, eg. for files which have no video channel.
|
||||||
case MP_CSP_PRIM_AUTO:
|
case PL_COLOR_PRIM_UNKNOWN:
|
||||||
case MP_CSP_PRIM_BT_709:
|
case PL_COLOR_PRIM_BT_709:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.640, 0.330},
|
.red = {0.640, 0.330},
|
||||||
.green = {0.300, 0.600},
|
.green = {0.300, 0.600},
|
||||||
.blue = {0.150, 0.060},
|
.blue = {0.150, 0.060},
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
case MP_CSP_PRIM_BT_2020:
|
case PL_COLOR_PRIM_BT_2020:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.708, 0.292},
|
.red = {0.708, 0.292},
|
||||||
.green = {0.170, 0.797},
|
.green = {0.170, 0.797},
|
||||||
.blue = {0.131, 0.046},
|
.blue = {0.131, 0.046},
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
case MP_CSP_PRIM_APPLE:
|
case PL_COLOR_PRIM_APPLE:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.625, 0.340},
|
.red = {0.625, 0.340},
|
||||||
.green = {0.280, 0.595},
|
.green = {0.280, 0.595},
|
||||||
.blue = {0.115, 0.070},
|
.blue = {0.115, 0.070},
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
case MP_CSP_PRIM_ADOBE:
|
case PL_COLOR_PRIM_ADOBE:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.640, 0.330},
|
.red = {0.640, 0.330},
|
||||||
.green = {0.210, 0.710},
|
.green = {0.210, 0.710},
|
||||||
.blue = {0.150, 0.060},
|
.blue = {0.150, 0.060},
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
case MP_CSP_PRIM_PRO_PHOTO:
|
case PL_COLOR_PRIM_PRO_PHOTO:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.7347, 0.2653},
|
.red = {0.7347, 0.2653},
|
||||||
.green = {0.1596, 0.8404},
|
.green = {0.1596, 0.8404},
|
||||||
.blue = {0.0366, 0.0001},
|
.blue = {0.0366, 0.0001},
|
||||||
.white = d50
|
.white = d50
|
||||||
};
|
};
|
||||||
case MP_CSP_PRIM_CIE_1931:
|
case PL_COLOR_PRIM_CIE_1931:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.7347, 0.2653},
|
.red = {0.7347, 0.2653},
|
||||||
.green = {0.2738, 0.7174},
|
.green = {0.2738, 0.7174},
|
||||||
|
@ -458,16 +331,16 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
.white = e
|
.white = e
|
||||||
};
|
};
|
||||||
// From SMPTE RP 431-2 and 432-1
|
// From SMPTE RP 431-2 and 432-1
|
||||||
case MP_CSP_PRIM_DCI_P3:
|
case PL_COLOR_PRIM_DCI_P3:
|
||||||
case MP_CSP_PRIM_DISPLAY_P3:
|
case PL_COLOR_PRIM_DISPLAY_P3:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.680, 0.320},
|
.red = {0.680, 0.320},
|
||||||
.green = {0.265, 0.690},
|
.green = {0.265, 0.690},
|
||||||
.blue = {0.150, 0.060},
|
.blue = {0.150, 0.060},
|
||||||
.white = spc == MP_CSP_PRIM_DCI_P3 ? dci : d65
|
.white = spc == PL_COLOR_PRIM_DCI_P3 ? dci : d65
|
||||||
};
|
};
|
||||||
// From Panasonic VARICAM reference manual
|
// From Panasonic VARICAM reference manual
|
||||||
case MP_CSP_PRIM_V_GAMUT:
|
case PL_COLOR_PRIM_V_GAMUT:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.730, 0.280},
|
.red = {0.730, 0.280},
|
||||||
.green = {0.165, 0.840},
|
.green = {0.165, 0.840},
|
||||||
|
@ -475,7 +348,7 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
// From Sony S-Log reference manual
|
// From Sony S-Log reference manual
|
||||||
case MP_CSP_PRIM_S_GAMUT:
|
case PL_COLOR_PRIM_S_GAMUT:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.730, 0.280},
|
.red = {0.730, 0.280},
|
||||||
.green = {0.140, 0.855},
|
.green = {0.140, 0.855},
|
||||||
|
@ -483,7 +356,7 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
// from EBU Tech. 3213-E
|
// from EBU Tech. 3213-E
|
||||||
case MP_CSP_PRIM_EBU_3213:
|
case PL_COLOR_PRIM_EBU_3213:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.630, 0.340},
|
.red = {0.630, 0.340},
|
||||||
.green = {0.295, 0.605},
|
.green = {0.295, 0.605},
|
||||||
|
@ -491,7 +364,7 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
.white = d65
|
.white = d65
|
||||||
};
|
};
|
||||||
// From H.273, traditional film with Illuminant C
|
// From H.273, traditional film with Illuminant C
|
||||||
case MP_CSP_PRIM_FILM_C:
|
case PL_COLOR_PRIM_FILM_C:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.681, 0.319},
|
.red = {0.681, 0.319},
|
||||||
.green = {0.243, 0.692},
|
.green = {0.243, 0.692},
|
||||||
|
@ -499,7 +372,7 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
.white = c
|
.white = c
|
||||||
};
|
};
|
||||||
// From libplacebo source code
|
// From libplacebo source code
|
||||||
case MP_CSP_PRIM_ACES_AP0:
|
case PL_COLOR_PRIM_ACES_AP0:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.7347, 0.2653},
|
.red = {0.7347, 0.2653},
|
||||||
.green = {0.0000, 1.0000},
|
.green = {0.0000, 1.0000},
|
||||||
|
@ -507,7 +380,7 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
.white = {0.32168, 0.33767},
|
.white = {0.32168, 0.33767},
|
||||||
};
|
};
|
||||||
// From libplacebo source code
|
// From libplacebo source code
|
||||||
case MP_CSP_PRIM_ACES_AP1:
|
case PL_COLOR_PRIM_ACES_AP1:
|
||||||
return (struct mp_csp_primaries) {
|
return (struct mp_csp_primaries) {
|
||||||
.red = {0.713, 0.293},
|
.red = {0.713, 0.293},
|
||||||
.green = {0.165, 0.830},
|
.green = {0.165, 0.830},
|
||||||
|
@ -522,20 +395,20 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc)
|
||||||
// Get the nominal peak for a given colorspace, relative to the reference white
|
// Get the nominal peak for a given colorspace, relative to the reference white
|
||||||
// level. In other words, this returns the brightest encodable value that can
|
// level. In other words, this returns the brightest encodable value that can
|
||||||
// be represented by a given transfer curve.
|
// be represented by a given transfer curve.
|
||||||
float mp_trc_nom_peak(enum mp_csp_trc trc)
|
float mp_trc_nom_peak(enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
switch (trc) {
|
switch (trc) {
|
||||||
case MP_CSP_TRC_PQ: return 10000.0 / MP_REF_WHITE;
|
case PL_COLOR_TRC_PQ: return 10000.0 / MP_REF_WHITE;
|
||||||
case MP_CSP_TRC_HLG: return 12.0 / MP_REF_WHITE_HLG;
|
case PL_COLOR_TRC_HLG: return 12.0 / MP_REF_WHITE_HLG;
|
||||||
case MP_CSP_TRC_V_LOG: return 46.0855;
|
case PL_COLOR_TRC_V_LOG: return 46.0855;
|
||||||
case MP_CSP_TRC_S_LOG1: return 6.52;
|
case PL_COLOR_TRC_S_LOG1: return 6.52;
|
||||||
case MP_CSP_TRC_S_LOG2: return 9.212;
|
case PL_COLOR_TRC_S_LOG2: return 9.212;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mp_trc_is_hdr(enum mp_csp_trc trc)
|
bool mp_trc_is_hdr(enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
return mp_trc_nom_peak(trc) > 1.0;
|
return mp_trc_nom_peak(trc) > 1.0;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +533,7 @@ static void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params,
|
||||||
enum mp_render_intent intent, struct mp_cmat *m)
|
enum mp_render_intent intent, struct mp_cmat *m)
|
||||||
{
|
{
|
||||||
// Convert to DCI-P3
|
// Convert to DCI-P3
|
||||||
struct mp_csp_primaries prim = mp_get_csp_primaries(MP_CSP_PRIM_DCI_P3);
|
struct mp_csp_primaries prim = mp_get_csp_primaries(PL_COLOR_PRIM_DCI_P3);
|
||||||
float brightness = params->brightness;
|
float brightness = params->brightness;
|
||||||
mp_get_rgb2xyz_matrix(prim, m->m);
|
mp_get_rgb2xyz_matrix(prim, m->m);
|
||||||
mp_invert_matrix3x3(m->m);
|
mp_invert_matrix3x3(m->m);
|
||||||
|
@ -685,7 +558,7 @@ static void mp_get_xyz2rgb_coeffs(struct mp_csp_params *params,
|
||||||
// Get multiplication factor required if image data is fit within the LSBs of a
|
// Get multiplication factor required if image data is fit within the LSBs of a
|
||||||
// higher smaller bit depth fixed-point texture data.
|
// higher smaller bit depth fixed-point texture data.
|
||||||
// This is broken. Use mp_get_csp_uint_mul().
|
// This is broken. Use mp_get_csp_uint_mul().
|
||||||
double mp_get_csp_mul(enum mp_csp csp, int input_bits, int texture_bits)
|
double mp_get_csp_mul(enum pl_color_system csp, int input_bits, int texture_bits)
|
||||||
{
|
{
|
||||||
assert(texture_bits >= input_bits);
|
assert(texture_bits >= input_bits);
|
||||||
|
|
||||||
|
@ -694,10 +567,10 @@ double mp_get_csp_mul(enum mp_csp csp, int input_bits, int texture_bits)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// RGB always uses the full range available.
|
// RGB always uses the full range available.
|
||||||
if (csp == MP_CSP_RGB)
|
if (csp == PL_COLOR_SYSTEM_RGB)
|
||||||
return ((1LL << input_bits) - 1.) / ((1LL << texture_bits) - 1.);
|
return ((1LL << input_bits) - 1.) / ((1LL << texture_bits) - 1.);
|
||||||
|
|
||||||
if (csp == MP_CSP_XYZ)
|
if (csp == PL_COLOR_SYSTEM_XYZ)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// High bit depth YUV uses a range shifted from 8 bit.
|
// High bit depth YUV uses a range shifted from 8 bit.
|
||||||
|
@ -716,24 +589,24 @@ double mp_get_csp_mul(enum mp_csp csp, int input_bits, int texture_bits)
|
||||||
// bits: number of significant bits, e.g. 10 for yuv420p10, 16 for p010
|
// bits: number of significant bits, e.g. 10 for yuv420p10, 16 for p010
|
||||||
// out_m: returns factor to multiply the uint number with
|
// out_m: returns factor to multiply the uint number with
|
||||||
// out_o: returns offset to add after multiplication
|
// out_o: returns offset to add after multiplication
|
||||||
void mp_get_csp_uint_mul(enum mp_csp csp, enum mp_csp_levels levels,
|
void mp_get_csp_uint_mul(enum pl_color_system csp, enum pl_color_levels levels,
|
||||||
int bits, int component, double *out_m, double *out_o)
|
int bits, int component, double *out_m, double *out_o)
|
||||||
{
|
{
|
||||||
uint16_t i_min = 0;
|
uint16_t i_min = 0;
|
||||||
uint16_t i_max = (1u << bits) - 1;
|
uint16_t i_max = (1u << bits) - 1;
|
||||||
double f_min = 0; // min. float value
|
double f_min = 0; // min. float value
|
||||||
|
|
||||||
if (csp != MP_CSP_RGB && component != 4) {
|
if (csp != PL_COLOR_SYSTEM_RGB && component != 4) {
|
||||||
if (component == 2 || component == 3) {
|
if (component == 2 || component == 3) {
|
||||||
f_min = (1u << (bits - 1)) / -(double)i_max; // force center => 0
|
f_min = (1u << (bits - 1)) / -(double)i_max; // force center => 0
|
||||||
|
|
||||||
if (levels != MP_CSP_LEVELS_PC && bits >= 8) {
|
if (levels != PL_COLOR_LEVELS_FULL && bits >= 8) {
|
||||||
i_min = 16 << (bits - 8); // => -0.5
|
i_min = 16 << (bits - 8); // => -0.5
|
||||||
i_max = 240 << (bits - 8); // => 0.5
|
i_max = 240 << (bits - 8); // => 0.5
|
||||||
f_min = -0.5;
|
f_min = -0.5;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (levels != MP_CSP_LEVELS_PC && bits >= 8) {
|
if (levels != PL_COLOR_LEVELS_FULL && bits >= 8) {
|
||||||
i_min = 16 << (bits - 8); // => 0
|
i_min = 16 << (bits - 8); // => 0
|
||||||
i_max = 235 << (bits - 8); // => 1
|
i_max = 235 << (bits - 8); // => 1
|
||||||
}
|
}
|
||||||
|
@ -778,19 +651,19 @@ static void luma_coeffs(struct mp_cmat *mat, float lr, float lg, float lb)
|
||||||
// get the coefficients of the yuv -> rgb conversion matrix
|
// get the coefficients of the yuv -> rgb conversion matrix
|
||||||
void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
|
void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
|
||||||
{
|
{
|
||||||
enum mp_csp colorspace = params->color.space;
|
enum pl_color_system colorspace = params->repr.sys;
|
||||||
if (colorspace <= MP_CSP_AUTO || colorspace >= MP_CSP_COUNT)
|
if (colorspace <= PL_COLOR_SYSTEM_UNKNOWN || colorspace >= PL_COLOR_SYSTEM_COUNT)
|
||||||
colorspace = MP_CSP_BT_601;
|
colorspace = PL_COLOR_SYSTEM_BT_601;
|
||||||
enum mp_csp_levels levels_in = params->color.levels;
|
enum pl_color_levels levels_in = params->repr.levels;
|
||||||
if (levels_in <= MP_CSP_LEVELS_AUTO || levels_in >= MP_CSP_LEVELS_COUNT)
|
if (levels_in <= PL_COLOR_LEVELS_UNKNOWN || levels_in >= PL_COLOR_LEVELS_COUNT)
|
||||||
levels_in = MP_CSP_LEVELS_TV;
|
levels_in = PL_COLOR_LEVELS_LIMITED;
|
||||||
|
|
||||||
switch (colorspace) {
|
switch (colorspace) {
|
||||||
case MP_CSP_BT_601: luma_coeffs(m, 0.299, 0.587, 0.114 ); break;
|
case PL_COLOR_SYSTEM_BT_601: luma_coeffs(m, 0.299, 0.587, 0.114 ); break;
|
||||||
case MP_CSP_BT_709: luma_coeffs(m, 0.2126, 0.7152, 0.0722); break;
|
case PL_COLOR_SYSTEM_BT_709: luma_coeffs(m, 0.2126, 0.7152, 0.0722); break;
|
||||||
case MP_CSP_SMPTE_240M: luma_coeffs(m, 0.2122, 0.7013, 0.0865); break;
|
case PL_COLOR_SYSTEM_SMPTE_240M: luma_coeffs(m, 0.2122, 0.7013, 0.0865); break;
|
||||||
case MP_CSP_BT_2020_NC: luma_coeffs(m, 0.2627, 0.6780, 0.0593); break;
|
case PL_COLOR_SYSTEM_BT_2020_NC: luma_coeffs(m, 0.2627, 0.6780, 0.0593); break;
|
||||||
case MP_CSP_BT_2020_C: {
|
case PL_COLOR_SYSTEM_BT_2020_C: {
|
||||||
// Note: This outputs into the [-0.5,0.5] range for chroma information.
|
// Note: This outputs into the [-0.5,0.5] range for chroma information.
|
||||||
// If this clips on any VO, a constant 0.5 coefficient can be added
|
// If this clips on any VO, a constant 0.5 coefficient can be added
|
||||||
// to the chroma channels to normalize them into [0,1]. This is not
|
// to the chroma channels to normalize them into [0,1]. This is not
|
||||||
|
@ -798,12 +671,12 @@ void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
|
||||||
*m = (struct mp_cmat){{{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}};
|
*m = (struct mp_cmat){{{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MP_CSP_RGB: {
|
case PL_COLOR_SYSTEM_RGB: {
|
||||||
*m = (struct mp_cmat){{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}};
|
*m = (struct mp_cmat){{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}};
|
||||||
levels_in = -1;
|
levels_in = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MP_CSP_XYZ: {
|
case PL_COLOR_SYSTEM_XYZ: {
|
||||||
// The vo should probably not be using a matrix generated by this
|
// The vo should probably not be using a matrix generated by this
|
||||||
// function for XYZ sources, but if it does, let's just convert it to
|
// function for XYZ sources, but if it does, let's just convert it to
|
||||||
// an equivalent RGB space based on the colorimetry metadata it
|
// an equivalent RGB space based on the colorimetry metadata it
|
||||||
|
@ -813,7 +686,7 @@ void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
|
||||||
levels_in = -1;
|
levels_in = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MP_CSP_YCGCO: {
|
case PL_COLOR_SYSTEM_YCGCO: {
|
||||||
*m = (struct mp_cmat) {
|
*m = (struct mp_cmat) {
|
||||||
{{1, -1, 1},
|
{{1, -1, 1},
|
||||||
{1, 1, 0},
|
{1, 1, 0},
|
||||||
|
@ -828,8 +701,8 @@ void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
|
||||||
if (params->is_float)
|
if (params->is_float)
|
||||||
levels_in = -1;
|
levels_in = -1;
|
||||||
|
|
||||||
if ((colorspace == MP_CSP_BT_601 || colorspace == MP_CSP_BT_709 ||
|
if ((colorspace == PL_COLOR_SYSTEM_BT_601 || colorspace == PL_COLOR_SYSTEM_BT_709 ||
|
||||||
colorspace == MP_CSP_SMPTE_240M || colorspace == MP_CSP_BT_2020_NC))
|
colorspace == PL_COLOR_SYSTEM_SMPTE_240M || colorspace == PL_COLOR_SYSTEM_BT_2020_NC))
|
||||||
{
|
{
|
||||||
// Hue is equivalent to rotating input [U, V] subvector around the origin.
|
// Hue is equivalent to rotating input [U, V] subvector around the origin.
|
||||||
// Saturation scales [U, V].
|
// Saturation scales [U, V].
|
||||||
|
@ -855,23 +728,23 @@ void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *m)
|
||||||
anyfull = { 0*s, 255*s, 255*s/2, 0 }, // cmax picked to make cmul=ymul
|
anyfull = { 0*s, 255*s, 255*s/2, 0 }, // cmax picked to make cmul=ymul
|
||||||
yuvlev;
|
yuvlev;
|
||||||
switch (levels_in) {
|
switch (levels_in) {
|
||||||
case MP_CSP_LEVELS_TV: yuvlev = yuvlim; break;
|
case PL_COLOR_LEVELS_LIMITED: yuvlev = yuvlim; break;
|
||||||
case MP_CSP_LEVELS_PC: yuvlev = yuvfull; break;
|
case PL_COLOR_LEVELS_FULL: yuvlev = yuvfull; break;
|
||||||
case -1: yuvlev = anyfull; break;
|
case -1: yuvlev = anyfull; break;
|
||||||
default:
|
default:
|
||||||
MP_ASSERT_UNREACHABLE();
|
MP_ASSERT_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
int levels_out = params->levels_out;
|
int levels_out = params->levels_out;
|
||||||
if (levels_out <= MP_CSP_LEVELS_AUTO || levels_out >= MP_CSP_LEVELS_COUNT)
|
if (levels_out <= PL_COLOR_LEVELS_UNKNOWN || levels_out >= PL_COLOR_LEVELS_COUNT)
|
||||||
levels_out = MP_CSP_LEVELS_PC;
|
levels_out = PL_COLOR_LEVELS_FULL;
|
||||||
struct rgblevels { double min, max; }
|
struct rgblevels { double min, max; }
|
||||||
rgblim = { 16/255., 235/255. },
|
rgblim = { 16/255., 235/255. },
|
||||||
rgbfull = { 0, 1 },
|
rgbfull = { 0, 1 },
|
||||||
rgblev;
|
rgblev;
|
||||||
switch (levels_out) {
|
switch (levels_out) {
|
||||||
case MP_CSP_LEVELS_TV: rgblev = rgblim; break;
|
case PL_COLOR_LEVELS_LIMITED: rgblev = rgblim; break;
|
||||||
case MP_CSP_LEVELS_PC: rgblev = rgbfull; break;
|
case PL_COLOR_LEVELS_FULL: rgblev = rgbfull; break;
|
||||||
default:
|
default:
|
||||||
MP_ASSERT_UNREACHABLE();
|
MP_ASSERT_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -904,16 +777,6 @@ void mp_csp_set_image_params(struct mp_csp_params *params,
|
||||||
params->color = p.color;
|
params->color = p.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2)
|
|
||||||
{
|
|
||||||
return c1.space == c2.space &&
|
|
||||||
c1.levels == c2.levels &&
|
|
||||||
c1.primaries == c2.primaries &&
|
|
||||||
c1.gamma == c2.gamma &&
|
|
||||||
c1.light == c2.light &&
|
|
||||||
pl_hdr_metadata_equal(&c1.hdr, &c2.hdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp_equalizer_param {
|
enum mp_csp_equalizer_param {
|
||||||
MP_CSP_EQ_BRIGHTNESS,
|
MP_CSP_EQ_BRIGHTNESS,
|
||||||
MP_CSP_EQ_CONTRAST,
|
MP_CSP_EQ_CONTRAST,
|
||||||
|
@ -946,7 +809,7 @@ const struct m_sub_options mp_csp_equalizer_conf = {
|
||||||
{"gamma", OPT_FLOAT(values[MP_CSP_EQ_GAMMA]),
|
{"gamma", OPT_FLOAT(values[MP_CSP_EQ_GAMMA]),
|
||||||
M_RANGE(-100, 100)},
|
M_RANGE(-100, 100)},
|
||||||
{"video-output-levels",
|
{"video-output-levels",
|
||||||
OPT_CHOICE_C(output_levels, mp_csp_levels_names)},
|
OPT_CHOICE_C(output_levels, pl_csp_levels_names)},
|
||||||
{0}
|
{0}
|
||||||
},
|
},
|
||||||
.size = sizeof(struct mp_csp_equalizer_opts),
|
.size = sizeof(struct mp_csp_equalizer_opts),
|
||||||
|
|
122
video/csputils.h
122
video/csputils.h
|
@ -30,76 +30,10 @@
|
||||||
* nonzero at vf/vo level.
|
* nonzero at vf/vo level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum mp_csp {
|
extern const struct m_opt_choice_alternatives pl_csp_names[];
|
||||||
MP_CSP_AUTO,
|
extern const struct m_opt_choice_alternatives pl_csp_levels_names[];
|
||||||
MP_CSP_BT_601,
|
extern const struct m_opt_choice_alternatives pl_csp_prim_names[];
|
||||||
MP_CSP_BT_709,
|
extern const struct m_opt_choice_alternatives pl_csp_trc_names[];
|
||||||
MP_CSP_SMPTE_240M,
|
|
||||||
MP_CSP_BT_2020_NC,
|
|
||||||
MP_CSP_BT_2020_C,
|
|
||||||
MP_CSP_RGB,
|
|
||||||
MP_CSP_XYZ,
|
|
||||||
MP_CSP_YCGCO,
|
|
||||||
MP_CSP_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct m_opt_choice_alternatives mp_csp_names[];
|
|
||||||
|
|
||||||
enum mp_csp_levels {
|
|
||||||
MP_CSP_LEVELS_AUTO,
|
|
||||||
MP_CSP_LEVELS_TV,
|
|
||||||
MP_CSP_LEVELS_PC,
|
|
||||||
MP_CSP_LEVELS_COUNT,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct m_opt_choice_alternatives mp_csp_levels_names[];
|
|
||||||
|
|
||||||
enum mp_csp_prim {
|
|
||||||
MP_CSP_PRIM_AUTO,
|
|
||||||
MP_CSP_PRIM_BT_601_525,
|
|
||||||
MP_CSP_PRIM_BT_601_625,
|
|
||||||
MP_CSP_PRIM_BT_709,
|
|
||||||
MP_CSP_PRIM_BT_2020,
|
|
||||||
MP_CSP_PRIM_BT_470M,
|
|
||||||
MP_CSP_PRIM_APPLE,
|
|
||||||
MP_CSP_PRIM_ADOBE,
|
|
||||||
MP_CSP_PRIM_PRO_PHOTO,
|
|
||||||
MP_CSP_PRIM_CIE_1931,
|
|
||||||
MP_CSP_PRIM_DCI_P3,
|
|
||||||
MP_CSP_PRIM_DISPLAY_P3,
|
|
||||||
MP_CSP_PRIM_V_GAMUT,
|
|
||||||
MP_CSP_PRIM_S_GAMUT,
|
|
||||||
MP_CSP_PRIM_EBU_3213,
|
|
||||||
MP_CSP_PRIM_FILM_C,
|
|
||||||
MP_CSP_PRIM_ACES_AP0,
|
|
||||||
MP_CSP_PRIM_ACES_AP1,
|
|
||||||
MP_CSP_PRIM_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct m_opt_choice_alternatives mp_csp_prim_names[];
|
|
||||||
|
|
||||||
enum mp_csp_trc {
|
|
||||||
MP_CSP_TRC_AUTO,
|
|
||||||
MP_CSP_TRC_BT_1886,
|
|
||||||
MP_CSP_TRC_SRGB,
|
|
||||||
MP_CSP_TRC_LINEAR,
|
|
||||||
MP_CSP_TRC_GAMMA18,
|
|
||||||
MP_CSP_TRC_GAMMA20,
|
|
||||||
MP_CSP_TRC_GAMMA22,
|
|
||||||
MP_CSP_TRC_GAMMA24,
|
|
||||||
MP_CSP_TRC_GAMMA26,
|
|
||||||
MP_CSP_TRC_GAMMA28,
|
|
||||||
MP_CSP_TRC_PRO_PHOTO,
|
|
||||||
MP_CSP_TRC_PQ,
|
|
||||||
MP_CSP_TRC_HLG,
|
|
||||||
MP_CSP_TRC_V_LOG,
|
|
||||||
MP_CSP_TRC_S_LOG1,
|
|
||||||
MP_CSP_TRC_S_LOG2,
|
|
||||||
MP_CSP_TRC_ST428,
|
|
||||||
MP_CSP_TRC_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct m_opt_choice_alternatives mp_csp_trc_names[];
|
|
||||||
|
|
||||||
enum mp_csp_light {
|
enum mp_csp_light {
|
||||||
MP_CSP_LIGHT_AUTO,
|
MP_CSP_LIGHT_AUTO,
|
||||||
|
@ -141,15 +75,6 @@ extern const struct m_opt_choice_alternatives mp_stereo3d_names[];
|
||||||
#define MP_STEREO3D_NAME_DEF(x, def) \
|
#define MP_STEREO3D_NAME_DEF(x, def) \
|
||||||
(MP_STEREO3D_NAME(x) ? MP_STEREO3D_NAME(x) : (def))
|
(MP_STEREO3D_NAME(x) ? MP_STEREO3D_NAME(x) : (def))
|
||||||
|
|
||||||
struct mp_colorspace {
|
|
||||||
enum mp_csp space;
|
|
||||||
enum mp_csp_levels levels;
|
|
||||||
enum mp_csp_prim primaries;
|
|
||||||
enum mp_csp_trc gamma;
|
|
||||||
enum mp_csp_light light;
|
|
||||||
struct pl_hdr_metadata hdr;
|
|
||||||
};
|
|
||||||
|
|
||||||
// For many colorspace conversions, in particular those involving HDR, an
|
// For many colorspace conversions, in particular those involving HDR, an
|
||||||
// implicit reference white level is needed. Since this magic constant shows up
|
// implicit reference white level is needed. Since this magic constant shows up
|
||||||
// a lot, give it an explicit name. The value of 203 cd/m² comes from ITU-R
|
// a lot, give it an explicit name. The value of 203 cd/m² comes from ITU-R
|
||||||
|
@ -158,12 +83,10 @@ struct mp_colorspace {
|
||||||
#define MP_REF_WHITE 203.0
|
#define MP_REF_WHITE 203.0
|
||||||
#define MP_REF_WHITE_HLG 3.17955
|
#define MP_REF_WHITE_HLG 3.17955
|
||||||
|
|
||||||
// Replaces unknown values in the first struct by those of the second struct
|
|
||||||
void mp_colorspace_merge(struct mp_colorspace *orig, struct mp_colorspace *new);
|
|
||||||
|
|
||||||
struct mp_csp_params {
|
struct mp_csp_params {
|
||||||
struct mp_colorspace color; // input colorspace
|
struct pl_color_repr repr;
|
||||||
enum mp_csp_levels levels_out; // output device
|
struct pl_color_space color;
|
||||||
|
enum pl_color_levels levels_out; // output device
|
||||||
float brightness;
|
float brightness;
|
||||||
float contrast;
|
float contrast;
|
||||||
float hue;
|
float hue;
|
||||||
|
@ -179,9 +102,8 @@ struct mp_csp_params {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MP_CSP_PARAMS_DEFAULTS { \
|
#define MP_CSP_PARAMS_DEFAULTS { \
|
||||||
.color = { .space = MP_CSP_BT_601, \
|
.repr = pl_color_repr_sdtv, \
|
||||||
.levels = MP_CSP_LEVELS_TV }, \
|
.levels_out = PL_COLOR_LEVELS_FULL, \
|
||||||
.levels_out = MP_CSP_LEVELS_PC, \
|
|
||||||
.brightness = 0, .contrast = 1, .hue = 0, .saturation = 1, \
|
.brightness = 0, .contrast = 1, .hue = 0, .saturation = 1, \
|
||||||
.gamma = 1, .texture_bits = 8, .input_bits = 8}
|
.gamma = 1, .texture_bits = 8, .input_bits = 8}
|
||||||
|
|
||||||
|
@ -189,8 +111,6 @@ struct mp_image_params;
|
||||||
void mp_csp_set_image_params(struct mp_csp_params *params,
|
void mp_csp_set_image_params(struct mp_csp_params *params,
|
||||||
const struct mp_image_params *imgparams);
|
const struct mp_image_params *imgparams);
|
||||||
|
|
||||||
bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2);
|
|
||||||
|
|
||||||
enum mp_chroma_location {
|
enum mp_chroma_location {
|
||||||
MP_CHROMA_AUTO,
|
MP_CHROMA_AUTO,
|
||||||
MP_CHROMA_TOPLEFT, // uhd
|
MP_CHROMA_TOPLEFT, // uhd
|
||||||
|
@ -234,26 +154,16 @@ struct mp_csp_primaries {
|
||||||
struct mp_csp_col_xy red, green, blue, white;
|
struct mp_csp_col_xy red, green, blue, white;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mp_csp avcol_spc_to_mp_csp(int avcolorspace);
|
enum pl_color_system mp_csp_guess_colorspace(int width, int height);
|
||||||
enum mp_csp_levels avcol_range_to_mp_csp_levels(int avrange);
|
enum pl_color_primaries mp_csp_guess_primaries(int width, int height);
|
||||||
enum mp_csp_prim avcol_pri_to_mp_csp_prim(int avpri);
|
|
||||||
enum mp_csp_trc avcol_trc_to_mp_csp_trc(int avtrc);
|
|
||||||
|
|
||||||
int mp_csp_to_avcol_spc(enum mp_csp colorspace);
|
|
||||||
int mp_csp_levels_to_avcol_range(enum mp_csp_levels range);
|
|
||||||
int mp_csp_prim_to_avcol_pri(enum mp_csp_prim prim);
|
|
||||||
int mp_csp_trc_to_avcol_trc(enum mp_csp_trc trc);
|
|
||||||
|
|
||||||
enum mp_csp mp_csp_guess_colorspace(int width, int height);
|
|
||||||
enum mp_csp_prim mp_csp_guess_primaries(int width, int height);
|
|
||||||
|
|
||||||
enum mp_chroma_location avchroma_location_to_mp(int avloc);
|
enum mp_chroma_location avchroma_location_to_mp(int avloc);
|
||||||
int mp_chroma_location_to_av(enum mp_chroma_location mploc);
|
int mp_chroma_location_to_av(enum mp_chroma_location mploc);
|
||||||
void mp_get_chroma_location(enum mp_chroma_location loc, int *x, int *y);
|
void mp_get_chroma_location(enum mp_chroma_location loc, int *x, int *y);
|
||||||
|
|
||||||
struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim csp);
|
struct mp_csp_primaries mp_get_csp_primaries(enum pl_color_primaries csp);
|
||||||
float mp_trc_nom_peak(enum mp_csp_trc trc);
|
float mp_trc_nom_peak(enum pl_color_transfer trc);
|
||||||
bool mp_trc_is_hdr(enum mp_csp_trc trc);
|
bool mp_trc_is_hdr(enum pl_color_transfer trc);
|
||||||
|
|
||||||
/* Color conversion matrix: RGB = m * YUV + c
|
/* Color conversion matrix: RGB = m * YUV + c
|
||||||
* m is in row-major matrix, with m[row][col], e.g.:
|
* m is in row-major matrix, with m[row][col], e.g.:
|
||||||
|
@ -277,8 +187,8 @@ void mp_get_rgb2xyz_matrix(struct mp_csp_primaries space, float m[3][3]);
|
||||||
void mp_get_cms_matrix(struct mp_csp_primaries src, struct mp_csp_primaries dest,
|
void mp_get_cms_matrix(struct mp_csp_primaries src, struct mp_csp_primaries dest,
|
||||||
enum mp_render_intent intent, float cms_matrix[3][3]);
|
enum mp_render_intent intent, float cms_matrix[3][3]);
|
||||||
|
|
||||||
double mp_get_csp_mul(enum mp_csp csp, int input_bits, int texture_bits);
|
double mp_get_csp_mul(enum pl_color_system csp, int input_bits, int texture_bits);
|
||||||
void mp_get_csp_uint_mul(enum mp_csp csp, enum mp_csp_levels levels,
|
void mp_get_csp_uint_mul(enum pl_color_system csp, enum pl_color_levels levels,
|
||||||
int bits, int component, double *out_m, double *out_o);
|
int bits, int component, double *out_m, double *out_o);
|
||||||
void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *out);
|
void mp_get_csp_matrix(struct mp_csp_params *params, struct mp_cmat *out);
|
||||||
|
|
||||||
|
|
|
@ -210,8 +210,8 @@ static int recreate_video_proc(struct mp_filter *vf)
|
||||||
FALSE, 0);
|
FALSE, 0);
|
||||||
|
|
||||||
D3D11_VIDEO_PROCESSOR_COLOR_SPACE csp = {
|
D3D11_VIDEO_PROCESSOR_COLOR_SPACE csp = {
|
||||||
.YCbCr_Matrix = p->params.color.space != MP_CSP_BT_601,
|
.YCbCr_Matrix = p->params.repr.sys != PL_COLOR_SYSTEM_BT_601,
|
||||||
.Nominal_Range = p->params.color.levels == MP_CSP_LEVELS_TV ? 1 : 2,
|
.Nominal_Range = p->params.repr.levels == PL_COLOR_LEVELS_LIMITED ? 1 : 2,
|
||||||
};
|
};
|
||||||
ID3D11VideoContext_VideoProcessorSetStreamColorSpace(p->video_ctx,
|
ID3D11VideoContext_VideoProcessorSetStreamColorSpace(p->video_ctx,
|
||||||
p->video_proc,
|
p->video_proc,
|
||||||
|
|
|
@ -104,7 +104,7 @@ static void f_process(struct mp_filter *f)
|
||||||
// "portable" across source video.
|
// "portable" across source video.
|
||||||
p->scaled->params.color = mpi->params.color;
|
p->scaled->params.color = mpi->params.color;
|
||||||
// Make output always full range; no reason to lose precision.
|
// Make output always full range; no reason to lose precision.
|
||||||
p->scaled->params.color.levels = MP_CSP_LEVELS_PC;
|
p->scaled->params.repr.levels = PL_COLOR_LEVELS_FULL;
|
||||||
|
|
||||||
if (!mp_zimg_convert(p->zimg, p->scaled, mpi)) {
|
if (!mp_zimg_convert(p->zimg, p->scaled, mpi)) {
|
||||||
if (!p->fallback_warning) {
|
if (!p->fallback_warning) {
|
||||||
|
|
|
@ -65,26 +65,26 @@ static void set_params(struct vf_format_opts *p, struct mp_image_params *out,
|
||||||
bool set_size)
|
bool set_size)
|
||||||
{
|
{
|
||||||
if (p->colormatrix)
|
if (p->colormatrix)
|
||||||
out->color.space = p->colormatrix;
|
out->repr.sys = p->colormatrix;
|
||||||
if (p->colorlevels)
|
if (p->colorlevels)
|
||||||
out->color.levels = p->colorlevels;
|
out->repr.levels = p->colorlevels;
|
||||||
if (p->primaries)
|
if (p->primaries)
|
||||||
out->color.primaries = p->primaries;
|
out->color.primaries = p->primaries;
|
||||||
if (p->gamma) {
|
if (p->gamma) {
|
||||||
enum mp_csp_trc in_gamma = p->gamma;
|
enum pl_color_transfer in_gamma = p->gamma;
|
||||||
out->color.gamma = p->gamma;
|
out->color.transfer = p->gamma;
|
||||||
if (in_gamma != out->color.gamma) {
|
if (in_gamma != out->color.transfer) {
|
||||||
// When changing the gamma function explicitly, also reset stuff
|
// When changing the gamma function explicitly, also reset stuff
|
||||||
// related to the gamma function since that information will almost
|
// related to the gamma function since that information will almost
|
||||||
// surely be false now and have to be re-inferred
|
// surely be false now and have to be re-inferred
|
||||||
out->color.hdr = (struct pl_hdr_metadata){0};
|
out->color.hdr = (struct pl_hdr_metadata){0};
|
||||||
out->color.light = MP_CSP_LIGHT_AUTO;
|
out->light = MP_CSP_LIGHT_AUTO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p->sig_peak)
|
if (p->sig_peak)
|
||||||
out->color.hdr = (struct pl_hdr_metadata){ .max_luma = p->sig_peak * MP_REF_WHITE };
|
out->color.hdr = (struct pl_hdr_metadata){ .max_luma = p->sig_peak * MP_REF_WHITE };
|
||||||
if (p->light)
|
if (p->light)
|
||||||
out->color.light = p->light;
|
out->light = p->light;
|
||||||
if (p->chroma_location)
|
if (p->chroma_location)
|
||||||
out->chroma_location = p->chroma_location;
|
out->chroma_location = p->chroma_location;
|
||||||
if (p->stereo_in)
|
if (p->stereo_in)
|
||||||
|
@ -122,10 +122,10 @@ static void vf_format_process(struct mp_filter *f)
|
||||||
int outfmt = priv->opts->fmt;
|
int outfmt = priv->opts->fmt;
|
||||||
|
|
||||||
// If we convert from RGB to YUV, default to limited range.
|
// If we convert from RGB to YUV, default to limited range.
|
||||||
if (mp_imgfmt_get_forced_csp(img->imgfmt) == MP_CSP_RGB &&
|
if (mp_imgfmt_get_forced_csp(img->imgfmt) == PL_COLOR_SYSTEM_RGB &&
|
||||||
outfmt && mp_imgfmt_get_forced_csp(outfmt) == MP_CSP_AUTO)
|
outfmt && mp_imgfmt_get_forced_csp(outfmt) == PL_COLOR_SYSTEM_UNKNOWN)
|
||||||
{
|
{
|
||||||
par.color.levels = MP_CSP_LEVELS_TV;
|
par.repr.levels = PL_COLOR_LEVELS_LIMITED;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_params(priv->opts, &par, true);
|
set_params(priv->opts, &par, true);
|
||||||
|
@ -204,10 +204,10 @@ static struct mp_filter *vf_format_create(struct mp_filter *parent, void *option
|
||||||
#define OPT_BASE_STRUCT struct vf_format_opts
|
#define OPT_BASE_STRUCT struct vf_format_opts
|
||||||
static const m_option_t vf_opts_fields[] = {
|
static const m_option_t vf_opts_fields[] = {
|
||||||
{"fmt", OPT_IMAGEFORMAT(fmt)},
|
{"fmt", OPT_IMAGEFORMAT(fmt)},
|
||||||
{"colormatrix", OPT_CHOICE_C(colormatrix, mp_csp_names)},
|
{"colormatrix", OPT_CHOICE_C(colormatrix, pl_csp_names)},
|
||||||
{"colorlevels", OPT_CHOICE_C(colorlevels, mp_csp_levels_names)},
|
{"colorlevels", OPT_CHOICE_C(colorlevels, pl_csp_levels_names)},
|
||||||
{"primaries", OPT_CHOICE_C(primaries, mp_csp_prim_names)},
|
{"primaries", OPT_CHOICE_C(primaries, pl_csp_prim_names)},
|
||||||
{"gamma", OPT_CHOICE_C(gamma, mp_csp_trc_names)},
|
{"gamma", OPT_CHOICE_C(gamma, pl_csp_trc_names)},
|
||||||
{"sig-peak", OPT_FLOAT(sig_peak)},
|
{"sig-peak", OPT_FLOAT(sig_peak)},
|
||||||
{"light", OPT_CHOICE_C(light, mp_csp_light_names)},
|
{"light", OPT_CHOICE_C(light, mp_csp_light_names)},
|
||||||
{"chroma-location", OPT_CHOICE_C(chroma_location, mp_chroma_names)},
|
{"chroma-location", OPT_CHOICE_C(chroma_location, mp_chroma_names)},
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <libavutil/rational.h>
|
#include <libavutil/rational.h>
|
||||||
#include <libavutil/cpu.h>
|
#include <libavutil/cpu.h>
|
||||||
|
#include <libplacebo/utils/libav.h>
|
||||||
|
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
#include "filters/f_autoconvert.h"
|
#include "filters/f_autoconvert.h"
|
||||||
|
@ -184,13 +185,13 @@ static void copy_mp_to_vs_frame_props_map(struct priv *p, VSMap *map,
|
||||||
struct mp_image_params *params = &img->params;
|
struct mp_image_params *params = &img->params;
|
||||||
p->vsapi->propSetInt(map, "_SARNum", params->p_w, 0);
|
p->vsapi->propSetInt(map, "_SARNum", params->p_w, 0);
|
||||||
p->vsapi->propSetInt(map, "_SARDen", params->p_h, 0);
|
p->vsapi->propSetInt(map, "_SARDen", params->p_h, 0);
|
||||||
if (params->color.levels) {
|
if (params->repr.levels) {
|
||||||
p->vsapi->propSetInt(map, "_ColorRange",
|
p->vsapi->propSetInt(map, "_ColorRange",
|
||||||
params->color.levels == MP_CSP_LEVELS_TV, 0);
|
params->repr.levels == PL_COLOR_LEVELS_LIMITED, 0);
|
||||||
}
|
}
|
||||||
// The docs explicitly say it uses libavcodec values.
|
// The docs explicitly say it uses libavcodec values.
|
||||||
p->vsapi->propSetInt(map, "_ColorSpace",
|
p->vsapi->propSetInt(map, "_ColorSpace",
|
||||||
mp_csp_to_avcol_spc(params->color.space), 0);
|
pl_system_to_av(params->repr.sys), 0);
|
||||||
if (params->chroma_location) {
|
if (params->chroma_location) {
|
||||||
p->vsapi->propSetInt(map, "_ChromaLocation",
|
p->vsapi->propSetInt(map, "_ChromaLocation",
|
||||||
params->chroma_location == MP_CHROMA_CENTER, 0);
|
params->chroma_location == MP_CHROMA_CENTER, 0);
|
||||||
|
|
|
@ -208,7 +208,7 @@ static struct mp_image *render(struct mp_filter *vf)
|
||||||
|
|
||||||
mp_image_copy_attributes(img, in);
|
mp_image_copy_attributes(img, in);
|
||||||
|
|
||||||
unsigned int flags = va_get_colorspace_flag(p->params.color.space);
|
unsigned int flags = va_get_colorspace_flag(p->params.repr.sys);
|
||||||
if (!mp_refqueue_should_deint(p->queue)) {
|
if (!mp_refqueue_should_deint(p->queue)) {
|
||||||
flags |= VA_FRAME_PICTURE;
|
flags |= VA_FRAME_PICTURE;
|
||||||
} else if (mp_refqueue_is_top_field(p->queue)) {
|
} else if (mp_refqueue_is_top_field(p->queue)) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <libavutil/mem.h>
|
#include <libavutil/mem.h>
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <libavutil/pixdesc.h>
|
#include <libavutil/pixdesc.h>
|
||||||
|
#include <libplacebo/utils/libav.h>
|
||||||
|
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -135,16 +136,16 @@ static void prepare_avframe(AVFrame *pic, AVCodecContext *avctx,
|
||||||
pic->width = avctx->width;
|
pic->width = avctx->width;
|
||||||
pic->height = avctx->height;
|
pic->height = avctx->height;
|
||||||
avctx->color_range = pic->color_range =
|
avctx->color_range = pic->color_range =
|
||||||
mp_csp_levels_to_avcol_range(image->params.color.levels);
|
pl_levels_to_av(image->params.repr.levels);
|
||||||
|
|
||||||
if (!tag_csp)
|
if (!tag_csp)
|
||||||
return;
|
return;
|
||||||
avctx->color_primaries = pic->color_primaries =
|
avctx->color_primaries = pic->color_primaries =
|
||||||
mp_csp_prim_to_avcol_pri(image->params.color.primaries);
|
pl_primaries_to_av(image->params.color.primaries);
|
||||||
avctx->color_trc = pic->color_trc =
|
avctx->color_trc = pic->color_trc =
|
||||||
mp_csp_trc_to_avcol_trc(image->params.color.gamma);
|
pl_transfer_to_av(image->params.color.transfer);
|
||||||
avctx->colorspace = pic->colorspace =
|
avctx->colorspace = pic->colorspace =
|
||||||
mp_csp_to_avcol_spc(image->params.color.space);
|
pl_system_to_av(image->params.repr.sys);
|
||||||
avctx->chroma_sample_location = pic->chroma_location =
|
avctx->chroma_sample_location = pic->chroma_location =
|
||||||
mp_chroma_location_to_av(image->params.chroma_location);
|
mp_chroma_location_to_av(image->params.chroma_location);
|
||||||
mp_dbg(log, "mapped color params:\n"
|
mp_dbg(log, "mapped color params:\n"
|
||||||
|
@ -193,7 +194,7 @@ static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, const ch
|
||||||
avctx->pix_fmt = imgfmt2pixfmt(image->imgfmt);
|
avctx->pix_fmt = imgfmt2pixfmt(image->imgfmt);
|
||||||
if (codec->id == AV_CODEC_ID_MJPEG) {
|
if (codec->id == AV_CODEC_ID_MJPEG) {
|
||||||
// Annoying deprecated garbage for the jpg encoder.
|
// Annoying deprecated garbage for the jpg encoder.
|
||||||
if (image->params.color.levels == MP_CSP_LEVELS_PC)
|
if (image->params.repr.levels == PL_COLOR_LEVELS_FULL)
|
||||||
avctx->pix_fmt = replace_j_format(avctx->pix_fmt);
|
avctx->pix_fmt = replace_j_format(avctx->pix_fmt);
|
||||||
}
|
}
|
||||||
if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
|
if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
|
||||||
|
@ -614,7 +615,7 @@ int image_writer_format_from_ext(const char *ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mp_image *convert_image(struct mp_image *image, int destfmt,
|
static struct mp_image *convert_image(struct mp_image *image, int destfmt,
|
||||||
enum mp_csp_levels yuv_levels,
|
enum pl_color_levels yuv_levels,
|
||||||
const struct image_writer_opts *opts,
|
const struct image_writer_opts *opts,
|
||||||
struct mpv_global *global,
|
struct mpv_global *global,
|
||||||
struct mp_log *log)
|
struct mp_log *log)
|
||||||
|
@ -629,6 +630,7 @@ static struct mp_image *convert_image(struct mp_image *image, int destfmt,
|
||||||
.p_w = 1,
|
.p_w = 1,
|
||||||
.p_h = 1,
|
.p_h = 1,
|
||||||
.color = image->params.color,
|
.color = image->params.color,
|
||||||
|
.repr = image->params.repr,
|
||||||
.chroma_location = image->params.chroma_location,
|
.chroma_location = image->params.chroma_location,
|
||||||
.crop = {0, 0, d_w, d_h},
|
.crop = {0, 0, d_w, d_h},
|
||||||
};
|
};
|
||||||
|
@ -636,13 +638,13 @@ static struct mp_image *convert_image(struct mp_image *image, int destfmt,
|
||||||
|
|
||||||
if (!image_writer_flexible_csp(opts)) {
|
if (!image_writer_flexible_csp(opts)) {
|
||||||
// If our format can't tag csps, set something sane
|
// If our format can't tag csps, set something sane
|
||||||
p.color.primaries = MP_CSP_PRIM_BT_709;
|
p.color.primaries = PL_COLOR_PRIM_BT_709;
|
||||||
p.color.gamma = MP_CSP_TRC_AUTO;
|
p.color.transfer = PL_COLOR_TRC_UNKNOWN;
|
||||||
p.color.light = MP_CSP_LIGHT_DISPLAY;
|
p.light = MP_CSP_LIGHT_DISPLAY;
|
||||||
p.color.hdr = (struct pl_hdr_metadata){0};
|
p.color.hdr = (struct pl_hdr_metadata){0};
|
||||||
if (p.color.space != MP_CSP_RGB) {
|
if (p.repr.sys != PL_COLOR_SYSTEM_RGB) {
|
||||||
p.color.levels = yuv_levels;
|
p.repr.levels = yuv_levels;
|
||||||
p.color.space = MP_CSP_BT_601;
|
p.repr.sys = PL_COLOR_SYSTEM_BT_601;
|
||||||
p.chroma_location = MP_CHROMA_CENTER;
|
p.chroma_location = MP_CHROMA_CENTER;
|
||||||
}
|
}
|
||||||
mp_image_params_guess_csp(&p);
|
mp_image_params_guess_csp(&p);
|
||||||
|
@ -731,11 +733,11 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts,
|
||||||
if (!destfmt)
|
if (!destfmt)
|
||||||
destfmt = get_target_format(&ctx);
|
destfmt = get_target_format(&ctx);
|
||||||
|
|
||||||
enum mp_csp_levels levels; // Ignored if destfmt is a RGB format
|
enum pl_color_levels levels; // Ignored if destfmt is a RGB format
|
||||||
if (opts->format == AV_CODEC_ID_WEBP) {
|
if (opts->format == AV_CODEC_ID_WEBP) {
|
||||||
levels = MP_CSP_LEVELS_TV;
|
levels = PL_COLOR_LEVELS_LIMITED;
|
||||||
} else {
|
} else {
|
||||||
levels = MP_CSP_LEVELS_PC;
|
levels = PL_COLOR_LEVELS_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mp_image *dst = convert_image(image, destfmt, levels, opts, global, log);
|
struct mp_image *dst = convert_image(image, destfmt, levels, opts, global, log);
|
||||||
|
|
|
@ -664,18 +664,18 @@ static bool validate_regular_imgfmt(const struct mp_regular_imgfmt *fmt)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mp_csp get_forced_csp_from_flags(int flags)
|
static enum pl_color_system get_forced_csp_from_flags(int flags)
|
||||||
{
|
{
|
||||||
if (flags & MP_IMGFLAG_COLOR_XYZ)
|
if (flags & MP_IMGFLAG_COLOR_XYZ)
|
||||||
return MP_CSP_XYZ;
|
return PL_COLOR_SYSTEM_XYZ;
|
||||||
|
|
||||||
if (flags & MP_IMGFLAG_COLOR_RGB)
|
if (flags & MP_IMGFLAG_COLOR_RGB)
|
||||||
return MP_CSP_RGB;
|
return PL_COLOR_SYSTEM_RGB;
|
||||||
|
|
||||||
return MP_CSP_AUTO;
|
return PL_COLOR_SYSTEM_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum mp_csp mp_imgfmt_get_forced_csp(int imgfmt)
|
enum pl_color_system mp_imgfmt_get_forced_csp(int imgfmt)
|
||||||
{
|
{
|
||||||
return get_forced_csp_from_flags(mp_imgfmt_get_desc(imgfmt).flags);
|
return get_forced_csp_from_flags(mp_imgfmt_get_desc(imgfmt).flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,9 +155,9 @@ int mp_imgfmt_desc_get_num_comps(struct mp_imgfmt_desc *desc);
|
||||||
// luma pixel. luma_offsets[0] == mp_imgfmt_desc.comps[0].offset.
|
// luma pixel. luma_offsets[0] == mp_imgfmt_desc.comps[0].offset.
|
||||||
bool mp_imgfmt_get_packed_yuv_locations(int imgfmt, uint8_t *luma_offsets);
|
bool mp_imgfmt_get_packed_yuv_locations(int imgfmt, uint8_t *luma_offsets);
|
||||||
|
|
||||||
// MP_CSP_AUTO for YUV, MP_CSP_RGB or MP_CSP_XYZ otherwise.
|
// PL_COLOR_SYSTEM_UNKNOWN for YUV, PL_COLOR_SYSTEM_RGB or PL_COLOR_SYSTEM_XYZ otherwise.
|
||||||
// (Because IMGFMT/AV_PIX_FMT conflate format and csp for RGB and XYZ.)
|
// (Because IMGFMT/AV_PIX_FMT conflate format and csp for RGB and XYZ.)
|
||||||
enum mp_csp mp_imgfmt_get_forced_csp(int imgfmt);
|
enum pl_color_system mp_imgfmt_get_forced_csp(int imgfmt);
|
||||||
|
|
||||||
enum mp_component_type {
|
enum mp_component_type {
|
||||||
MP_COMPONENT_TYPE_UNKNOWN = 0,
|
MP_COMPONENT_TYPE_UNKNOWN = 0,
|
||||||
|
@ -184,7 +184,7 @@ struct mp_regular_imgfmt {
|
||||||
// See mp_imgfmt_get_forced_csp(). Normally code should use
|
// See mp_imgfmt_get_forced_csp(). Normally code should use
|
||||||
// mp_image_params.colors. This field is only needed to map the format
|
// mp_image_params.colors. This field is only needed to map the format
|
||||||
// unambiguously to FFmpeg formats.
|
// unambiguously to FFmpeg formats.
|
||||||
enum mp_csp forced_csp;
|
enum pl_color_system forced_csp;
|
||||||
|
|
||||||
// Size of each component in bytes.
|
// Size of each component in bytes.
|
||||||
uint8_t component_size;
|
uint8_t component_size;
|
||||||
|
|
157
video/mp_image.c
157
video/mp_image.c
|
@ -491,7 +491,7 @@ void mp_image_copy(struct mp_image *dst, struct mp_image *src)
|
||||||
memcpy(dst->planes[1], src->planes[1], AVPALETTE_SIZE);
|
memcpy(dst->planes[1], src->planes[1], AVPALETTE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mp_csp mp_image_params_get_forced_csp(struct mp_image_params *params)
|
static enum pl_color_system mp_image_params_get_forced_csp(struct mp_image_params *params)
|
||||||
{
|
{
|
||||||
int imgfmt = params->hw_subfmt ? params->hw_subfmt : params->imgfmt;
|
int imgfmt = params->hw_subfmt ? params->hw_subfmt : params->imgfmt;
|
||||||
return mp_imgfmt_get_forced_csp(imgfmt);
|
return mp_imgfmt_get_forced_csp(imgfmt);
|
||||||
|
@ -520,15 +520,17 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
|
||||||
dst->params.p_w = src->params.p_w;
|
dst->params.p_w = src->params.p_w;
|
||||||
dst->params.p_h = src->params.p_h;
|
dst->params.p_h = src->params.p_h;
|
||||||
dst->params.color = src->params.color;
|
dst->params.color = src->params.color;
|
||||||
|
dst->params.repr = src->params.repr;
|
||||||
|
dst->params.light = src->params.light;
|
||||||
dst->params.chroma_location = src->params.chroma_location;
|
dst->params.chroma_location = src->params.chroma_location;
|
||||||
dst->params.alpha = src->params.alpha;
|
dst->params.alpha = src->params.alpha;
|
||||||
dst->params.crop = src->params.crop;
|
dst->params.crop = src->params.crop;
|
||||||
dst->nominal_fps = src->nominal_fps;
|
dst->nominal_fps = src->nominal_fps;
|
||||||
|
|
||||||
// ensure colorspace consistency
|
// ensure colorspace consistency
|
||||||
enum mp_csp dst_forced_csp = mp_image_params_get_forced_csp(&dst->params);
|
enum pl_color_system dst_forced_csp = mp_image_params_get_forced_csp(&dst->params);
|
||||||
if (mp_image_params_get_forced_csp(&src->params) != dst_forced_csp) {
|
if (mp_image_params_get_forced_csp(&src->params) != dst_forced_csp) {
|
||||||
dst->params.color.space = dst_forced_csp != MP_CSP_AUTO ?
|
dst->params.repr.sys = dst_forced_csp != PL_COLOR_SYSTEM_UNKNOWN ?
|
||||||
dst_forced_csp :
|
dst_forced_csp :
|
||||||
mp_csp_guess_colorspace(src->w, src->h);
|
mp_csp_guess_colorspace(src->w, src->h);
|
||||||
}
|
}
|
||||||
|
@ -668,8 +670,8 @@ void mp_image_clear(struct mp_image *img, int x0, int y0, int x1, int y1)
|
||||||
plane_size[cd->plane] = plane_bits / 8u;
|
plane_size[cd->plane] = plane_bits / 8u;
|
||||||
int depth = cd->size + MPMIN(cd->pad, 0);
|
int depth = cd->size + MPMIN(cd->pad, 0);
|
||||||
double m, o;
|
double m, o;
|
||||||
mp_get_csp_uint_mul(area.params.color.space,
|
mp_get_csp_uint_mul(area.params.repr.sys,
|
||||||
area.params.color.levels,
|
area.params.repr.levels,
|
||||||
depth, c + 1, &m, &o);
|
depth, c + 1, &m, &o);
|
||||||
uint64_t val = MPCLAMP(lrint((0 - o) / m), 0, 1ull << depth);
|
uint64_t val = MPCLAMP(lrint((0 - o) / m), 0, 1ull << depth);
|
||||||
plane_clear_i[cd->plane] |= val << cd->offset;
|
plane_clear_i[cd->plane] |= val << cd->offset;
|
||||||
|
@ -771,11 +773,11 @@ char *mp_image_params_to_str_buf(char *b, size_t bs,
|
||||||
if (p->hw_subfmt)
|
if (p->hw_subfmt)
|
||||||
mp_snprintf_cat(b, bs, "[%s]", mp_imgfmt_to_name(p->hw_subfmt));
|
mp_snprintf_cat(b, bs, "[%s]", mp_imgfmt_to_name(p->hw_subfmt));
|
||||||
mp_snprintf_cat(b, bs, " %s/%s/%s/%s/%s",
|
mp_snprintf_cat(b, bs, " %s/%s/%s/%s/%s",
|
||||||
m_opt_choice_str(mp_csp_names, p->color.space),
|
m_opt_choice_str(pl_csp_names, p->repr.sys),
|
||||||
m_opt_choice_str(mp_csp_prim_names, p->color.primaries),
|
m_opt_choice_str(pl_csp_prim_names, p->color.primaries),
|
||||||
m_opt_choice_str(mp_csp_trc_names, p->color.gamma),
|
m_opt_choice_str(pl_csp_trc_names, p->color.transfer),
|
||||||
m_opt_choice_str(mp_csp_levels_names, p->color.levels),
|
m_opt_choice_str(pl_csp_levels_names, p->repr.levels),
|
||||||
m_opt_choice_str(mp_csp_light_names, p->color.light));
|
m_opt_choice_str(mp_csp_light_names, p->light));
|
||||||
mp_snprintf_cat(b, bs, " CL=%s",
|
mp_snprintf_cat(b, bs, " CL=%s",
|
||||||
m_opt_choice_str(mp_chroma_names, p->chroma_location));
|
m_opt_choice_str(mp_chroma_names, p->chroma_location));
|
||||||
if (mp_image_crop_valid(p)) {
|
if (mp_image_crop_valid(p)) {
|
||||||
|
@ -834,7 +836,9 @@ bool mp_image_params_equal(const struct mp_image_params *p1,
|
||||||
p1->w == p2->w && p1->h == p2->h &&
|
p1->w == p2->w && p1->h == p2->h &&
|
||||||
p1->p_w == p2->p_w && p1->p_h == p2->p_h &&
|
p1->p_w == p2->p_w && p1->p_h == p2->p_h &&
|
||||||
p1->force_window == p2->force_window &&
|
p1->force_window == p2->force_window &&
|
||||||
mp_colorspace_equal(p1->color, p2->color) &&
|
pl_color_space_equal(&p1->color, &p2->color) &&
|
||||||
|
pl_color_repr_equal(&p1->repr, &p2->repr) &&
|
||||||
|
p1->light == p2->light &&
|
||||||
p1->chroma_location == p2->chroma_location &&
|
p1->chroma_location == p2->chroma_location &&
|
||||||
p1->rotate == p2->rotate &&
|
p1->rotate == p2->rotate &&
|
||||||
p1->stereo3d == p2->stereo3d &&
|
p1->stereo3d == p2->stereo3d &&
|
||||||
|
@ -852,11 +856,11 @@ void mp_image_set_attributes(struct mp_image *image,
|
||||||
nparams.w = image->w;
|
nparams.w = image->w;
|
||||||
nparams.h = image->h;
|
nparams.h = image->h;
|
||||||
if (nparams.imgfmt != params->imgfmt)
|
if (nparams.imgfmt != params->imgfmt)
|
||||||
nparams.color = (struct mp_colorspace){0};
|
nparams.color = (struct pl_color_space){0};
|
||||||
mp_image_set_params(image, &nparams);
|
mp_image_set_params(image, &nparams);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mp_csp_levels infer_levels(enum mp_imgfmt imgfmt)
|
static enum pl_color_levels infer_levels(enum mp_imgfmt imgfmt)
|
||||||
{
|
{
|
||||||
switch (imgfmt2pixfmt(imgfmt)) {
|
switch (imgfmt2pixfmt(imgfmt)) {
|
||||||
case AV_PIX_FMT_YUVJ420P:
|
case AV_PIX_FMT_YUVJ420P:
|
||||||
|
@ -878,9 +882,9 @@ static enum mp_csp_levels infer_levels(enum mp_imgfmt imgfmt)
|
||||||
case AV_PIX_FMT_GRAY16BE:
|
case AV_PIX_FMT_GRAY16BE:
|
||||||
case AV_PIX_FMT_YA16BE:
|
case AV_PIX_FMT_YA16BE:
|
||||||
case AV_PIX_FMT_YA16LE:
|
case AV_PIX_FMT_YA16LE:
|
||||||
return MP_CSP_LEVELS_PC;
|
return PL_COLOR_LEVELS_FULL;
|
||||||
default:
|
default:
|
||||||
return MP_CSP_LEVELS_TV;
|
return PL_COLOR_LEVELS_LIMITED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -889,100 +893,100 @@ static enum mp_csp_levels infer_levels(enum mp_imgfmt imgfmt)
|
||||||
// the colorspace as implied by the pixel format.
|
// the colorspace as implied by the pixel format.
|
||||||
void mp_image_params_guess_csp(struct mp_image_params *params)
|
void mp_image_params_guess_csp(struct mp_image_params *params)
|
||||||
{
|
{
|
||||||
enum mp_csp forced_csp = mp_image_params_get_forced_csp(params);
|
enum pl_color_system forced_csp = mp_image_params_get_forced_csp(params);
|
||||||
if (forced_csp == MP_CSP_AUTO) { // YUV/other
|
if (forced_csp == PL_COLOR_SYSTEM_UNKNOWN) { // YUV/other
|
||||||
if (params->color.space != MP_CSP_BT_601 &&
|
if (params->repr.sys != PL_COLOR_SYSTEM_BT_601 &&
|
||||||
params->color.space != MP_CSP_BT_709 &&
|
params->repr.sys != PL_COLOR_SYSTEM_BT_709 &&
|
||||||
params->color.space != MP_CSP_BT_2020_NC &&
|
params->repr.sys != PL_COLOR_SYSTEM_BT_2020_NC &&
|
||||||
params->color.space != MP_CSP_BT_2020_C &&
|
params->repr.sys != PL_COLOR_SYSTEM_BT_2020_C &&
|
||||||
params->color.space != MP_CSP_SMPTE_240M &&
|
params->repr.sys != PL_COLOR_SYSTEM_SMPTE_240M &&
|
||||||
params->color.space != MP_CSP_YCGCO)
|
params->repr.sys != PL_COLOR_SYSTEM_YCGCO)
|
||||||
{
|
{
|
||||||
// Makes no sense, so guess instead
|
// Makes no sense, so guess instead
|
||||||
// YCGCO should be separate, but libavcodec disagrees
|
// YCGCO should be separate, but libavcodec disagrees
|
||||||
params->color.space = MP_CSP_AUTO;
|
params->repr.sys = PL_COLOR_SYSTEM_UNKNOWN;
|
||||||
}
|
}
|
||||||
if (params->color.space == MP_CSP_AUTO)
|
if (params->repr.sys == PL_COLOR_SYSTEM_UNKNOWN)
|
||||||
params->color.space = mp_csp_guess_colorspace(params->w, params->h);
|
params->repr.sys = mp_csp_guess_colorspace(params->w, params->h);
|
||||||
if (params->color.levels == MP_CSP_LEVELS_AUTO) {
|
if (params->repr.levels == PL_COLOR_LEVELS_UNKNOWN) {
|
||||||
if (params->color.gamma == MP_CSP_TRC_V_LOG) {
|
if (params->color.transfer == PL_COLOR_TRC_V_LOG) {
|
||||||
params->color.levels = MP_CSP_LEVELS_PC;
|
params->repr.levels = PL_COLOR_LEVELS_FULL;
|
||||||
} else {
|
} else {
|
||||||
params->color.levels = infer_levels(params->imgfmt);
|
params->repr.levels = infer_levels(params->imgfmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (params->color.primaries == MP_CSP_PRIM_AUTO) {
|
if (params->color.primaries == PL_COLOR_PRIM_UNKNOWN) {
|
||||||
// Guess based on the colormatrix as a first priority
|
// Guess based on the colormatrix as a first priority
|
||||||
if (params->color.space == MP_CSP_BT_2020_NC ||
|
if (params->repr.sys == PL_COLOR_SYSTEM_BT_2020_NC ||
|
||||||
params->color.space == MP_CSP_BT_2020_C) {
|
params->repr.sys == PL_COLOR_SYSTEM_BT_2020_C) {
|
||||||
params->color.primaries = MP_CSP_PRIM_BT_2020;
|
params->color.primaries = PL_COLOR_PRIM_BT_2020;
|
||||||
} else if (params->color.space == MP_CSP_BT_709) {
|
} else if (params->repr.sys == PL_COLOR_SYSTEM_BT_709) {
|
||||||
params->color.primaries = MP_CSP_PRIM_BT_709;
|
params->color.primaries = PL_COLOR_PRIM_BT_709;
|
||||||
} else {
|
} else {
|
||||||
// Ambiguous colormatrix for BT.601, guess based on res
|
// Ambiguous colormatrix for BT.601, guess based on res
|
||||||
params->color.primaries = mp_csp_guess_primaries(params->w, params->h);
|
params->color.primaries = mp_csp_guess_primaries(params->w, params->h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (params->color.gamma == MP_CSP_TRC_AUTO)
|
if (params->color.transfer == PL_COLOR_TRC_UNKNOWN)
|
||||||
params->color.gamma = MP_CSP_TRC_BT_1886;
|
params->color.transfer = PL_COLOR_TRC_BT_1886;
|
||||||
} else if (forced_csp == MP_CSP_RGB) {
|
} else if (forced_csp == PL_COLOR_SYSTEM_RGB) {
|
||||||
params->color.space = MP_CSP_RGB;
|
params->repr.sys = PL_COLOR_SYSTEM_RGB;
|
||||||
params->color.levels = MP_CSP_LEVELS_PC;
|
params->repr.levels = PL_COLOR_LEVELS_FULL;
|
||||||
|
|
||||||
// The majority of RGB content is either sRGB or (rarely) some other
|
// The majority of RGB content is either sRGB or (rarely) some other
|
||||||
// color space which we don't even handle, like AdobeRGB or
|
// color space which we don't even handle, like AdobeRGB or
|
||||||
// ProPhotoRGB. The only reasonable thing we can do is assume it's
|
// ProPhotoRGB. The only reasonable thing we can do is assume it's
|
||||||
// sRGB and hope for the best, which should usually just work out fine.
|
// sRGB and hope for the best, which should usually just work out fine.
|
||||||
// Note: sRGB primaries = BT.709 primaries
|
// Note: sRGB primaries = BT.709 primaries
|
||||||
if (params->color.primaries == MP_CSP_PRIM_AUTO)
|
if (params->color.primaries == PL_COLOR_PRIM_UNKNOWN)
|
||||||
params->color.primaries = MP_CSP_PRIM_BT_709;
|
params->color.primaries = PL_COLOR_PRIM_BT_709;
|
||||||
if (params->color.gamma == MP_CSP_TRC_AUTO)
|
if (params->color.transfer == PL_COLOR_TRC_UNKNOWN)
|
||||||
params->color.gamma = MP_CSP_TRC_SRGB;
|
params->color.transfer = PL_COLOR_TRC_SRGB;
|
||||||
} else if (forced_csp == MP_CSP_XYZ) {
|
} else if (forced_csp == PL_COLOR_SYSTEM_XYZ) {
|
||||||
params->color.space = MP_CSP_XYZ;
|
params->repr.sys = PL_COLOR_SYSTEM_XYZ;
|
||||||
params->color.levels = MP_CSP_LEVELS_PC;
|
params->repr.levels = PL_COLOR_LEVELS_FULL;
|
||||||
// Force gamma to ST428 as this is the only correct for DCDM X'Y'Z'
|
// Force gamma to ST428 as this is the only correct for DCDM X'Y'Z'
|
||||||
params->color.gamma = MP_CSP_TRC_ST428;
|
params->color.transfer = PL_COLOR_TRC_ST428;
|
||||||
// Don't care about primaries, they shouldn't be used, or if anything
|
// Don't care about primaries, they shouldn't be used, or if anything
|
||||||
// MP_CSP_PRIM_ST428 should be defined.
|
// MP_CSP_PRIM_ST428 should be defined.
|
||||||
} else {
|
} else {
|
||||||
// We have no clue.
|
// We have no clue.
|
||||||
params->color.space = MP_CSP_AUTO;
|
params->repr.sys = PL_COLOR_SYSTEM_UNKNOWN;
|
||||||
params->color.levels = MP_CSP_LEVELS_AUTO;
|
params->repr.levels = PL_COLOR_LEVELS_UNKNOWN;
|
||||||
params->color.primaries = MP_CSP_PRIM_AUTO;
|
params->color.primaries = PL_COLOR_PRIM_UNKNOWN;
|
||||||
params->color.gamma = MP_CSP_TRC_AUTO;
|
params->color.transfer = PL_COLOR_TRC_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!params->color.hdr.max_luma) {
|
if (!params->color.hdr.max_luma) {
|
||||||
if (params->color.gamma == MP_CSP_TRC_HLG) {
|
if (params->color.transfer == PL_COLOR_TRC_HLG) {
|
||||||
params->color.hdr.max_luma = 1000; // reference display
|
params->color.hdr.max_luma = 1000; // reference display
|
||||||
} else {
|
} else {
|
||||||
// If the signal peak is unknown, we're forced to pick the TRC's
|
// If the signal peak is unknown, we're forced to pick the TRC's
|
||||||
// nominal range as the signal peak to prevent clipping
|
// nominal range as the signal peak to prevent clipping
|
||||||
params->color.hdr.max_luma = mp_trc_nom_peak(params->color.gamma) * MP_REF_WHITE;
|
params->color.hdr.max_luma = mp_trc_nom_peak(params->color.transfer) * MP_REF_WHITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mp_trc_is_hdr(params->color.gamma)) {
|
if (!mp_trc_is_hdr(params->color.transfer)) {
|
||||||
// Some clips have leftover HDR metadata after conversion to SDR, so to
|
// Some clips have leftover HDR metadata after conversion to SDR, so to
|
||||||
// avoid blowing up the tone mapping code, strip/sanitize it
|
// avoid blowing up the tone mapping code, strip/sanitize it
|
||||||
params->color.hdr = pl_hdr_metadata_empty;
|
params->color.hdr = pl_hdr_metadata_empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->chroma_location == MP_CHROMA_AUTO) {
|
if (params->chroma_location == MP_CHROMA_AUTO) {
|
||||||
if (params->color.levels == MP_CSP_LEVELS_TV)
|
if (params->repr.levels == PL_COLOR_LEVELS_LIMITED)
|
||||||
params->chroma_location = MP_CHROMA_LEFT;
|
params->chroma_location = MP_CHROMA_LEFT;
|
||||||
if (params->color.levels == MP_CSP_LEVELS_PC)
|
if (params->repr.levels == PL_COLOR_LEVELS_FULL)
|
||||||
params->chroma_location = MP_CHROMA_CENTER;
|
params->chroma_location = MP_CHROMA_CENTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->color.light == MP_CSP_LIGHT_AUTO) {
|
if (params->light == MP_CSP_LIGHT_AUTO) {
|
||||||
// HLG is always scene-referred (using its own OOTF), everything else
|
// HLG is always scene-referred (using its own OOTF), everything else
|
||||||
// we assume is display-referred by default.
|
// we assume is display-referred by default.
|
||||||
if (params->color.gamma == MP_CSP_TRC_HLG) {
|
if (params->color.transfer == PL_COLOR_TRC_HLG) {
|
||||||
params->color.light = MP_CSP_LIGHT_SCENE_HLG;
|
params->light = MP_CSP_LIGHT_SCENE_HLG;
|
||||||
} else {
|
} else {
|
||||||
params->color.light = MP_CSP_LIGHT_DISPLAY;
|
params->light = MP_CSP_LIGHT_DISPLAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1031,11 +1035,14 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
|
||||||
if (src->repeat_pict == 1)
|
if (src->repeat_pict == 1)
|
||||||
dst->fields |= MP_IMGFIELD_REPEAT_FIRST;
|
dst->fields |= MP_IMGFIELD_REPEAT_FIRST;
|
||||||
|
|
||||||
dst->params.color = (struct mp_colorspace){
|
dst->params.repr = (struct pl_color_repr){
|
||||||
.space = avcol_spc_to_mp_csp(src->colorspace),
|
.sys = pl_system_from_av(src->colorspace),
|
||||||
.levels = avcol_range_to_mp_csp_levels(src->color_range),
|
.levels = pl_levels_from_av(src->color_range),
|
||||||
.primaries = avcol_pri_to_mp_csp_prim(src->color_primaries),
|
};
|
||||||
.gamma = avcol_trc_to_mp_csp_trc(src->color_trc),
|
|
||||||
|
dst->params.color = (struct pl_color_space){
|
||||||
|
.primaries = pl_primaries_from_av(src->color_primaries),
|
||||||
|
.transfer = pl_transfer_from_av(src->color_trc),
|
||||||
};
|
};
|
||||||
|
|
||||||
dst->params.chroma_location = avchroma_location_to_mp(src->chroma_location);
|
dst->params.chroma_location = avchroma_location_to_mp(src->chroma_location);
|
||||||
|
@ -1044,7 +1051,7 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
|
||||||
struct mp_image_params *p = (void *)src->opaque_ref->data;
|
struct mp_image_params *p = (void *)src->opaque_ref->data;
|
||||||
dst->params.stereo3d = p->stereo3d;
|
dst->params.stereo3d = p->stereo3d;
|
||||||
// Might be incorrect if colorspace changes.
|
// Might be incorrect if colorspace changes.
|
||||||
dst->params.color.light = p->color.light;
|
dst->params.light = p->light;
|
||||||
dst->params.alpha = p->alpha;
|
dst->params.alpha = p->alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1161,11 +1168,11 @@ struct AVFrame *mp_image_to_av_frame(struct mp_image *src)
|
||||||
if (src->fields & MP_IMGFIELD_REPEAT_FIRST)
|
if (src->fields & MP_IMGFIELD_REPEAT_FIRST)
|
||||||
dst->repeat_pict = 1;
|
dst->repeat_pict = 1;
|
||||||
|
|
||||||
dst->colorspace = mp_csp_to_avcol_spc(src->params.color.space);
|
dst->colorspace = pl_system_to_av(src->params.repr.sys);
|
||||||
dst->color_range = mp_csp_levels_to_avcol_range(src->params.color.levels);
|
dst->color_range = pl_levels_to_av(src->params.repr.levels);
|
||||||
dst->color_primaries =
|
dst->color_primaries =
|
||||||
mp_csp_prim_to_avcol_pri(src->params.color.primaries);
|
pl_primaries_to_av(src->params.color.primaries);
|
||||||
dst->color_trc = mp_csp_trc_to_avcol_trc(src->params.color.gamma);
|
dst->color_trc = pl_transfer_to_av(src->params.color.transfer);
|
||||||
|
|
||||||
dst->chroma_location = mp_chroma_location_to_av(src->params.chroma_location);
|
dst->chroma_location = mp_chroma_location_to_av(src->params.chroma_location);
|
||||||
|
|
||||||
|
@ -1181,11 +1188,7 @@ struct AVFrame *mp_image_to_av_frame(struct mp_image *src)
|
||||||
new_ref->icc_profile = NULL;
|
new_ref->icc_profile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pl_avframe_set_color(dst, (struct pl_color_space){
|
pl_avframe_set_color(dst, src->params.color);
|
||||||
.primaries = mp_prim_to_pl(src->params.color.primaries),
|
|
||||||
.transfer = mp_trc_to_pl(src->params.color.gamma),
|
|
||||||
.hdr = src->params.color.hdr,
|
|
||||||
});
|
|
||||||
|
|
||||||
{
|
{
|
||||||
AVFrameSideData *sd = av_frame_new_side_data(dst,
|
AVFrameSideData *sd = av_frame_new_side_data(dst,
|
||||||
|
|
|
@ -47,7 +47,9 @@ struct mp_image_params {
|
||||||
int w, h; // image dimensions
|
int w, h; // image dimensions
|
||||||
int p_w, p_h; // define pixel aspect ratio (undefined: 0/0)
|
int p_w, p_h; // define pixel aspect ratio (undefined: 0/0)
|
||||||
bool force_window; // fake image created by handle_force_window
|
bool force_window; // fake image created by handle_force_window
|
||||||
struct mp_colorspace color;
|
struct pl_color_space color;
|
||||||
|
struct pl_color_repr repr;
|
||||||
|
enum mp_csp_light light;
|
||||||
enum mp_chroma_location chroma_location;
|
enum mp_chroma_location chroma_location;
|
||||||
// The image should be rotated clockwise (0-359 degrees).
|
// The image should be rotated clockwise (0-359 degrees).
|
||||||
int rotate;
|
int rotate;
|
||||||
|
|
|
@ -96,7 +96,7 @@ struct priv {
|
||||||
struct ra_tex *backbuffer;
|
struct ra_tex *backbuffer;
|
||||||
ID3D11Device *device;
|
ID3D11Device *device;
|
||||||
IDXGISwapChain *swapchain;
|
IDXGISwapChain *swapchain;
|
||||||
struct mp_colorspace swapchain_csp;
|
struct pl_color_space swapchain_csp;
|
||||||
|
|
||||||
int64_t perf_freq;
|
int64_t perf_freq;
|
||||||
unsigned sync_refresh_count;
|
unsigned sync_refresh_count;
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct ra_fbo {
|
||||||
|
|
||||||
// Host system's colorspace that it will be interpreting
|
// Host system's colorspace that it will be interpreting
|
||||||
// the frame buffer as.
|
// the frame buffer as.
|
||||||
struct mp_colorspace color_space;
|
struct pl_color_space color_space;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ra_swapchain_fns {
|
struct ra_swapchain_fns {
|
||||||
|
|
|
@ -228,9 +228,9 @@ static const char *d3d11_get_csp_name(DXGI_COLOR_SPACE_TYPE csp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool d3d11_get_mp_csp(DXGI_COLOR_SPACE_TYPE csp,
|
static bool d3d11_get_mp_csp(DXGI_COLOR_SPACE_TYPE csp,
|
||||||
struct mp_colorspace *mp_csp)
|
struct pl_color_space *pl_color_system)
|
||||||
{
|
{
|
||||||
if (!mp_csp)
|
if (!pl_color_system)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Colorspaces utilizing gamma 2.2 (G22) are set to
|
// Colorspaces utilizing gamma 2.2 (G22) are set to
|
||||||
|
@ -243,27 +243,27 @@ static bool d3d11_get_mp_csp(DXGI_COLOR_SPACE_TYPE csp,
|
||||||
// regarding not doing conversion from BT.601 to BT.709.
|
// regarding not doing conversion from BT.601 to BT.709.
|
||||||
switch (csp) {
|
switch (csp) {
|
||||||
case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709:
|
case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709:
|
||||||
*mp_csp = (struct mp_colorspace){
|
*pl_color_system = (struct pl_color_space){
|
||||||
.gamma = MP_CSP_TRC_AUTO,
|
.transfer = PL_COLOR_TRC_UNKNOWN,
|
||||||
.primaries = MP_CSP_PRIM_AUTO,
|
.primaries = PL_COLOR_PRIM_UNKNOWN,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709:
|
case DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709:
|
||||||
*mp_csp = (struct mp_colorspace) {
|
*pl_color_system = (struct pl_color_space) {
|
||||||
.gamma = MP_CSP_TRC_LINEAR,
|
.transfer = PL_COLOR_TRC_LINEAR,
|
||||||
.primaries = MP_CSP_PRIM_AUTO,
|
.primaries = PL_COLOR_PRIM_UNKNOWN,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020:
|
case DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020:
|
||||||
*mp_csp = (struct mp_colorspace) {
|
*pl_color_system = (struct pl_color_space) {
|
||||||
.gamma = MP_CSP_TRC_PQ,
|
.transfer = PL_COLOR_TRC_PQ,
|
||||||
.primaries = MP_CSP_PRIM_BT_2020,
|
.primaries = PL_COLOR_PRIM_BT_2020,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020:
|
case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020:
|
||||||
*mp_csp = (struct mp_colorspace) {
|
*pl_color_system = (struct pl_color_space) {
|
||||||
.gamma = MP_CSP_TRC_AUTO,
|
.transfer = PL_COLOR_TRC_UNKNOWN,
|
||||||
.primaries = MP_CSP_PRIM_BT_2020,
|
.primaries = PL_COLOR_PRIM_BT_2020,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -824,7 +824,7 @@ static bool configure_created_swapchain(struct mp_log *log,
|
||||||
IDXGISwapChain *swapchain,
|
IDXGISwapChain *swapchain,
|
||||||
DXGI_FORMAT requested_format,
|
DXGI_FORMAT requested_format,
|
||||||
DXGI_COLOR_SPACE_TYPE requested_csp,
|
DXGI_COLOR_SPACE_TYPE requested_csp,
|
||||||
struct mp_colorspace *configured_csp)
|
struct pl_color_space *configured_csp)
|
||||||
{
|
{
|
||||||
DXGI_FORMAT probed_format = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT probed_format = DXGI_FORMAT_UNKNOWN;
|
||||||
DXGI_FORMAT selected_format = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT selected_format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
@ -832,7 +832,7 @@ static bool configure_created_swapchain(struct mp_log *log,
|
||||||
DXGI_COLOR_SPACE_TYPE selected_colorspace;
|
DXGI_COLOR_SPACE_TYPE selected_colorspace;
|
||||||
const char *format_name = NULL;
|
const char *format_name = NULL;
|
||||||
const char *csp_name = NULL;
|
const char *csp_name = NULL;
|
||||||
struct mp_colorspace mp_csp = { 0 };
|
struct pl_color_space pl_color_system = { 0 };
|
||||||
bool mp_csp_mapped = false;
|
bool mp_csp_mapped = false;
|
||||||
|
|
||||||
query_output_format_and_colorspace(log, swapchain,
|
query_output_format_and_colorspace(log, swapchain,
|
||||||
|
@ -848,7 +848,7 @@ static bool configure_created_swapchain(struct mp_log *log,
|
||||||
requested_csp : probed_colorspace;
|
requested_csp : probed_colorspace;
|
||||||
format_name = d3d11_get_format_name(selected_format);
|
format_name = d3d11_get_format_name(selected_format);
|
||||||
csp_name = d3d11_get_csp_name(selected_colorspace);
|
csp_name = d3d11_get_csp_name(selected_colorspace);
|
||||||
mp_csp_mapped = d3d11_get_mp_csp(selected_colorspace, &mp_csp);
|
mp_csp_mapped = d3d11_get_mp_csp(selected_colorspace, &pl_color_system);
|
||||||
|
|
||||||
mp_verbose(log, "Selected swapchain format %s (%d), attempting "
|
mp_verbose(log, "Selected swapchain format %s (%d), attempting "
|
||||||
"to utilize it.\n",
|
"to utilize it.\n",
|
||||||
|
@ -879,7 +879,7 @@ static bool configure_created_swapchain(struct mp_log *log,
|
||||||
"mapping! Overriding to standard sRGB!\n",
|
"mapping! Overriding to standard sRGB!\n",
|
||||||
csp_name, selected_colorspace);
|
csp_name, selected_colorspace);
|
||||||
selected_colorspace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
selected_colorspace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||||
d3d11_get_mp_csp(selected_colorspace, &mp_csp);
|
d3d11_get_mp_csp(selected_colorspace, &pl_color_system);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_verbose(log, "Selected swapchain color space %s (%d), attempting to "
|
mp_verbose(log, "Selected swapchain color space %s (%d), attempting to "
|
||||||
|
@ -891,7 +891,7 @@ static bool configure_created_swapchain(struct mp_log *log,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configured_csp) {
|
if (configured_csp) {
|
||||||
*configured_csp = mp_csp;
|
*configured_csp = pl_color_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -88,10 +88,10 @@ struct d3d11_swapchain_opts {
|
||||||
DXGI_FORMAT format;
|
DXGI_FORMAT format;
|
||||||
DXGI_COLOR_SPACE_TYPE color_space;
|
DXGI_COLOR_SPACE_TYPE color_space;
|
||||||
|
|
||||||
// mp_colorspace mapping of the configured swapchain colorspace
|
// pl_color_space mapping of the configured swapchain colorspace
|
||||||
// shall be written into this memory location if configuration
|
// shall be written into this memory location if configuration
|
||||||
// succeeds. Will be ignored if NULL.
|
// succeeds. Will be ignored if NULL.
|
||||||
struct mp_colorspace *configured_csp;
|
struct pl_color_space *configured_csp;
|
||||||
|
|
||||||
// Use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL if possible
|
// Use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL if possible
|
||||||
bool flip;
|
bool flip;
|
||||||
|
|
|
@ -46,8 +46,8 @@ struct gl_lcms {
|
||||||
char *current_profile;
|
char *current_profile;
|
||||||
bool using_memory_profile;
|
bool using_memory_profile;
|
||||||
bool changed;
|
bool changed;
|
||||||
enum mp_csp_prim current_prim;
|
enum pl_color_primaries current_prim;
|
||||||
enum mp_csp_trc current_trc;
|
enum pl_color_transfer current_trc;
|
||||||
|
|
||||||
struct mp_log *log;
|
struct mp_log *log;
|
||||||
struct mpv_global *global;
|
struct mpv_global *global;
|
||||||
|
@ -162,8 +162,8 @@ static bool vid_profile_eq(struct AVBufferRef *a, struct AVBufferRef *b)
|
||||||
|
|
||||||
// Return whether the profile or config has changed since the last time it was
|
// Return whether the profile or config has changed since the last time it was
|
||||||
// retrieved. If it has changed, gl_lcms_get_lut3d() should be called.
|
// retrieved. If it has changed, gl_lcms_get_lut3d() should be called.
|
||||||
bool gl_lcms_has_changed(struct gl_lcms *p, enum mp_csp_prim prim,
|
bool gl_lcms_has_changed(struct gl_lcms *p, enum pl_color_primaries prim,
|
||||||
enum mp_csp_trc trc, struct AVBufferRef *vid_profile)
|
enum pl_color_transfer trc, struct AVBufferRef *vid_profile)
|
||||||
{
|
{
|
||||||
if (p->changed || p->current_prim != prim || p->current_trc != trc)
|
if (p->changed || p->current_prim != prim || p->current_trc != trc)
|
||||||
return true;
|
return true;
|
||||||
|
@ -180,7 +180,7 @@ bool gl_lcms_has_profile(struct gl_lcms *p)
|
||||||
|
|
||||||
static cmsHPROFILE get_vid_profile(struct gl_lcms *p, cmsContext cms,
|
static cmsHPROFILE get_vid_profile(struct gl_lcms *p, cmsContext cms,
|
||||||
cmsHPROFILE disp_profile,
|
cmsHPROFILE disp_profile,
|
||||||
enum mp_csp_prim prim, enum mp_csp_trc trc)
|
enum pl_color_primaries prim, enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
if (p->opts->use_embedded && p->vid_profile) {
|
if (p->opts->use_embedded && p->vid_profile) {
|
||||||
// Try using the embedded ICC profile
|
// Try using the embedded ICC profile
|
||||||
|
@ -207,26 +207,26 @@ static cmsHPROFILE get_vid_profile(struct gl_lcms *p, cmsContext cms,
|
||||||
|
|
||||||
cmsToneCurve *tonecurve[3] = {0};
|
cmsToneCurve *tonecurve[3] = {0};
|
||||||
switch (trc) {
|
switch (trc) {
|
||||||
case MP_CSP_TRC_LINEAR: tonecurve[0] = cmsBuildGamma(cms, 1.0); break;
|
case PL_COLOR_TRC_LINEAR: tonecurve[0] = cmsBuildGamma(cms, 1.0); break;
|
||||||
case MP_CSP_TRC_GAMMA18: tonecurve[0] = cmsBuildGamma(cms, 1.8); break;
|
case PL_COLOR_TRC_GAMMA18: tonecurve[0] = cmsBuildGamma(cms, 1.8); break;
|
||||||
case MP_CSP_TRC_GAMMA20: tonecurve[0] = cmsBuildGamma(cms, 2.0); break;
|
case PL_COLOR_TRC_GAMMA20: tonecurve[0] = cmsBuildGamma(cms, 2.0); break;
|
||||||
case MP_CSP_TRC_GAMMA22: tonecurve[0] = cmsBuildGamma(cms, 2.2); break;
|
case PL_COLOR_TRC_GAMMA22: tonecurve[0] = cmsBuildGamma(cms, 2.2); break;
|
||||||
case MP_CSP_TRC_GAMMA24: tonecurve[0] = cmsBuildGamma(cms, 2.4); break;
|
case PL_COLOR_TRC_GAMMA24: tonecurve[0] = cmsBuildGamma(cms, 2.4); break;
|
||||||
case MP_CSP_TRC_GAMMA26: tonecurve[0] = cmsBuildGamma(cms, 2.6); break;
|
case PL_COLOR_TRC_GAMMA26: tonecurve[0] = cmsBuildGamma(cms, 2.6); break;
|
||||||
case MP_CSP_TRC_GAMMA28: tonecurve[0] = cmsBuildGamma(cms, 2.8); break;
|
case PL_COLOR_TRC_GAMMA28: tonecurve[0] = cmsBuildGamma(cms, 2.8); break;
|
||||||
|
|
||||||
case MP_CSP_TRC_SRGB:
|
case PL_COLOR_TRC_SRGB:
|
||||||
// Values copied from Little-CMS
|
// Values copied from Little-CMS
|
||||||
tonecurve[0] = cmsBuildParametricToneCurve(cms, 4,
|
tonecurve[0] = cmsBuildParametricToneCurve(cms, 4,
|
||||||
(double[5]){2.40, 1/1.055, 0.055/1.055, 1/12.92, 0.04045});
|
(double[5]){2.40, 1/1.055, 0.055/1.055, 1/12.92, 0.04045});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_CSP_TRC_PRO_PHOTO:
|
case PL_COLOR_TRC_PRO_PHOTO:
|
||||||
tonecurve[0] = cmsBuildParametricToneCurve(cms, 4,
|
tonecurve[0] = cmsBuildParametricToneCurve(cms, 4,
|
||||||
(double[5]){1.8, 1.0, 0.0, 1/16.0, 0.03125});
|
(double[5]){1.8, 1.0, 0.0, 1/16.0, 0.03125});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_CSP_TRC_BT_1886: {
|
case PL_COLOR_TRC_BT_1886: {
|
||||||
double src_black[3];
|
double src_black[3];
|
||||||
if (p->opts->contrast < 0) {
|
if (p->opts->contrast < 0) {
|
||||||
// User requested infinite contrast, return 2.4 profile
|
// User requested infinite contrast, return 2.4 profile
|
||||||
|
@ -300,7 +300,7 @@ static cmsHPROFILE get_vid_profile(struct gl_lcms *p, cmsContext cms,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d,
|
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d,
|
||||||
enum mp_csp_prim prim, enum mp_csp_trc trc,
|
enum pl_color_primaries prim, enum pl_color_transfer trc,
|
||||||
struct AVBufferRef *vid_profile)
|
struct AVBufferRef *vid_profile)
|
||||||
{
|
{
|
||||||
int s_r, s_g, s_b;
|
int s_r, s_g, s_b;
|
||||||
|
@ -474,8 +474,8 @@ struct gl_lcms *gl_lcms_init(void *talloc_ctx, struct mp_log *log,
|
||||||
void gl_lcms_update_options(struct gl_lcms *p) { }
|
void gl_lcms_update_options(struct gl_lcms *p) { }
|
||||||
bool gl_lcms_set_memory_profile(struct gl_lcms *p, bstr profile) {return false;}
|
bool gl_lcms_set_memory_profile(struct gl_lcms *p, bstr profile) {return false;}
|
||||||
|
|
||||||
bool gl_lcms_has_changed(struct gl_lcms *p, enum mp_csp_prim prim,
|
bool gl_lcms_has_changed(struct gl_lcms *p, enum pl_color_primaries prim,
|
||||||
enum mp_csp_trc trc, struct AVBufferRef *vid_profile)
|
enum pl_color_transfer trc, struct AVBufferRef *vid_profile)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -486,7 +486,7 @@ bool gl_lcms_has_profile(struct gl_lcms *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d,
|
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d,
|
||||||
enum mp_csp_prim prim, enum mp_csp_trc trc,
|
enum pl_color_primaries prim, enum pl_color_transfer trc,
|
||||||
struct AVBufferRef *vid_profile)
|
struct AVBufferRef *vid_profile)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -37,10 +37,10 @@ void gl_lcms_update_options(struct gl_lcms *p);
|
||||||
bool gl_lcms_set_memory_profile(struct gl_lcms *p, bstr profile);
|
bool gl_lcms_set_memory_profile(struct gl_lcms *p, bstr profile);
|
||||||
bool gl_lcms_has_profile(struct gl_lcms *p);
|
bool gl_lcms_has_profile(struct gl_lcms *p);
|
||||||
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **,
|
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **,
|
||||||
enum mp_csp_prim prim, enum mp_csp_trc trc,
|
enum pl_color_primaries prim, enum pl_color_transfer trc,
|
||||||
struct AVBufferRef *vid_profile);
|
struct AVBufferRef *vid_profile);
|
||||||
bool gl_lcms_has_changed(struct gl_lcms *p, enum mp_csp_prim prim,
|
bool gl_lcms_has_changed(struct gl_lcms *p, enum pl_color_primaries prim,
|
||||||
enum mp_csp_trc trc, struct AVBufferRef *vid_profile);
|
enum pl_color_transfer trc, struct AVBufferRef *vid_profile);
|
||||||
|
|
||||||
static inline bool gl_parse_3dlut_size(const char *arg, int *p1, int *p2, int *p3)
|
static inline bool gl_parse_3dlut_size(const char *arg, int *p1, int *p2, int *p3)
|
||||||
{
|
{
|
||||||
|
|
|
@ -368,13 +368,13 @@ const struct m_sub_options gl_video_conf = {
|
||||||
.deprecation_message = "no replacement"},
|
.deprecation_message = "no replacement"},
|
||||||
{"gamma-auto", OPT_BOOL(gamma_auto),
|
{"gamma-auto", OPT_BOOL(gamma_auto),
|
||||||
.deprecation_message = "no replacement"},
|
.deprecation_message = "no replacement"},
|
||||||
{"target-prim", OPT_CHOICE_C(target_prim, mp_csp_prim_names)},
|
{"target-prim", OPT_CHOICE_C(target_prim, pl_csp_prim_names)},
|
||||||
{"target-trc", OPT_CHOICE_C(target_trc, mp_csp_trc_names)},
|
{"target-trc", OPT_CHOICE_C(target_trc, pl_csp_trc_names)},
|
||||||
{"target-peak", OPT_CHOICE(target_peak, {"auto", 0}),
|
{"target-peak", OPT_CHOICE(target_peak, {"auto", 0}),
|
||||||
M_RANGE(10, 10000)},
|
M_RANGE(10, 10000)},
|
||||||
{"target-contrast", OPT_CHOICE(target_contrast, {"auto", 0}, {"inf", -1}),
|
{"target-contrast", OPT_CHOICE(target_contrast, {"auto", 0}, {"inf", -1}),
|
||||||
M_RANGE(10, 1000000)},
|
M_RANGE(10, 1000000)},
|
||||||
{"target-gamut", OPT_CHOICE_C(target_gamut, mp_csp_prim_names)},
|
{"target-gamut", OPT_CHOICE_C(target_gamut, pl_csp_prim_names)},
|
||||||
{"tone-mapping", OPT_CHOICE(tone_map.curve,
|
{"tone-mapping", OPT_CHOICE(tone_map.curve,
|
||||||
{"auto", TONE_MAPPING_AUTO},
|
{"auto", TONE_MAPPING_AUTO},
|
||||||
{"clip", TONE_MAPPING_CLIP},
|
{"clip", TONE_MAPPING_CLIP},
|
||||||
|
@ -605,15 +605,6 @@ bool gl_video_gamma_auto_enabled(struct gl_video *p)
|
||||||
return p->opts.gamma_auto;
|
return p->opts.gamma_auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mp_colorspace gl_video_get_output_colorspace(struct gl_video *p)
|
|
||||||
{
|
|
||||||
return (struct mp_colorspace) {
|
|
||||||
.primaries = p->opts.target_prim,
|
|
||||||
.gamma = p->opts.target_trc,
|
|
||||||
.hdr.max_luma = p->opts.target_peak,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warning: profile.start must point to a ta allocation, and the function
|
// Warning: profile.start must point to a ta allocation, and the function
|
||||||
// takes over ownership.
|
// takes over ownership.
|
||||||
void gl_video_set_icc_profile(struct gl_video *p, bstr icc_data)
|
void gl_video_set_icc_profile(struct gl_video *p, bstr icc_data)
|
||||||
|
@ -627,8 +618,8 @@ bool gl_video_icc_auto_enabled(struct gl_video *p)
|
||||||
return p->opts.icc_opts ? p->opts.icc_opts->profile_auto : false;
|
return p->opts.icc_opts ? p->opts.icc_opts->profile_auto : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gl_video_get_lut3d(struct gl_video *p, enum mp_csp_prim prim,
|
static bool gl_video_get_lut3d(struct gl_video *p, enum pl_color_primaries prim,
|
||||||
enum mp_csp_trc trc)
|
enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
if (!p->use_lut_3d)
|
if (!p->use_lut_3d)
|
||||||
return false;
|
return false;
|
||||||
|
@ -796,9 +787,9 @@ static void pass_get_images(struct gl_video *p, struct video_image *vimg,
|
||||||
ctype = PLANE_NONE;
|
ctype = PLANE_NONE;
|
||||||
} else if (c == 4) {
|
} else if (c == 4) {
|
||||||
ctype = PLANE_ALPHA;
|
ctype = PLANE_ALPHA;
|
||||||
} else if (p->image_params.color.space == MP_CSP_RGB) {
|
} else if (p->image_params.repr.sys == PL_COLOR_SYSTEM_RGB) {
|
||||||
ctype = PLANE_RGB;
|
ctype = PLANE_RGB;
|
||||||
} else if (p->image_params.color.space == MP_CSP_XYZ) {
|
} else if (p->image_params.repr.sys == PL_COLOR_SYSTEM_XYZ) {
|
||||||
ctype = PLANE_XYZ;
|
ctype = PLANE_XYZ;
|
||||||
} else {
|
} else {
|
||||||
ctype = c == 1 ? PLANE_LUMA : PLANE_CHROMA;
|
ctype = c == 1 ? PLANE_LUMA : PLANE_CHROMA;
|
||||||
|
@ -810,7 +801,7 @@ static void pass_get_images(struct gl_video *p, struct video_image *vimg,
|
||||||
|
|
||||||
int msb_valid_bits =
|
int msb_valid_bits =
|
||||||
p->ra_format.component_bits + MPMIN(p->ra_format.component_pad, 0);
|
p->ra_format.component_bits + MPMIN(p->ra_format.component_pad, 0);
|
||||||
int csp = type == PLANE_ALPHA ? MP_CSP_RGB : p->image_params.color.space;
|
int csp = type == PLANE_ALPHA ? PL_COLOR_SYSTEM_RGB : p->image_params.repr.sys;
|
||||||
float tex_mul =
|
float tex_mul =
|
||||||
1.0 / mp_get_csp_mul(csp, msb_valid_bits, p->ra_format.component_bits);
|
1.0 / mp_get_csp_mul(csp, msb_valid_bits, p->ra_format.component_bits);
|
||||||
if (p->ra_format.component_type == RA_CTYPE_FLOAT)
|
if (p->ra_format.component_type == RA_CTYPE_FLOAT)
|
||||||
|
@ -1957,7 +1948,7 @@ static void deband_hook(struct gl_video *p, struct image img,
|
||||||
{
|
{
|
||||||
pass_describe(p, "debanding (%s)", plane_names[img.type]);
|
pass_describe(p, "debanding (%s)", plane_names[img.type]);
|
||||||
pass_sample_deband(p->sc, p->opts.deband_opts, &p->lfg,
|
pass_sample_deband(p->sc, p->opts.deband_opts, &p->lfg,
|
||||||
p->image_params.color.gamma);
|
p->image_params.color.transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unsharp_hook(struct gl_video *p, struct image img,
|
static void unsharp_hook(struct gl_video *p, struct image img,
|
||||||
|
@ -2345,8 +2336,8 @@ static void pass_convert_yuv(struct gl_video *p)
|
||||||
GLSLF("color = color.%s;\n", p->color_swizzle);
|
GLSLF("color = color.%s;\n", p->color_swizzle);
|
||||||
|
|
||||||
// Pre-colormatrix input gamma correction
|
// Pre-colormatrix input gamma correction
|
||||||
if (cparams.color.space == MP_CSP_XYZ)
|
if (cparams.repr.sys == PL_COLOR_SYSTEM_XYZ)
|
||||||
pass_linearize(p->sc, p->image_params.color.gamma);
|
pass_linearize(p->sc, p->image_params.color.transfer);
|
||||||
|
|
||||||
// We always explicitly normalize the range in pass_read_video
|
// We always explicitly normalize the range in pass_read_video
|
||||||
cparams.input_bits = cparams.texture_bits = 0;
|
cparams.input_bits = cparams.texture_bits = 0;
|
||||||
|
@ -2360,14 +2351,14 @@ static void pass_convert_yuv(struct gl_video *p)
|
||||||
|
|
||||||
GLSL(color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;)
|
GLSL(color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;)
|
||||||
|
|
||||||
if (cparams.color.space == MP_CSP_XYZ) {
|
if (cparams.repr.sys == PL_COLOR_SYSTEM_XYZ) {
|
||||||
pass_delinearize(p->sc, p->image_params.color.gamma);
|
pass_delinearize(p->sc, p->image_params.color.transfer);
|
||||||
// mp_get_csp_matrix implicitly converts XYZ to DCI-P3
|
// mp_get_csp_matrix implicitly converts XYZ to DCI-P3
|
||||||
p->image_params.color.space = MP_CSP_RGB;
|
p->image_params.repr.sys = PL_COLOR_SYSTEM_RGB;
|
||||||
p->image_params.color.primaries = MP_CSP_PRIM_DCI_P3;
|
p->image_params.color.primaries = PL_COLOR_PRIM_DCI_P3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->image_params.color.space == MP_CSP_BT_2020_C) {
|
if (p->image_params.repr.sys == PL_COLOR_SYSTEM_BT_2020_C) {
|
||||||
// Conversion for C'rcY'cC'bc via the BT.2020 CL system:
|
// Conversion for C'rcY'cC'bc via the BT.2020 CL system:
|
||||||
// C'bc = (B'-Y'c) / 1.9404 | C'bc <= 0
|
// C'bc = (B'-Y'c) / 1.9404 | C'bc <= 0
|
||||||
// = (B'-Y'c) / 1.5816 | C'bc > 0
|
// = (B'-Y'c) / 1.5816 | C'bc > 0
|
||||||
|
@ -2491,7 +2482,7 @@ static void pass_scale_main(struct gl_video *p)
|
||||||
// Linear light downscaling results in nasty artifacts for HDR curves
|
// Linear light downscaling results in nasty artifacts for HDR curves
|
||||||
// due to the potentially extreme brightness differences severely
|
// due to the potentially extreme brightness differences severely
|
||||||
// compounding any ringing. So just scale in gamma light instead.
|
// compounding any ringing. So just scale in gamma light instead.
|
||||||
if (mp_trc_is_hdr(p->image_params.color.gamma))
|
if (mp_trc_is_hdr(p->image_params.color.transfer))
|
||||||
use_linear = false;
|
use_linear = false;
|
||||||
} else if (upscaling) {
|
} else if (upscaling) {
|
||||||
use_linear = p->opts.linear_upscaling || p->opts.sigmoid_upscaling;
|
use_linear = p->opts.linear_upscaling || p->opts.sigmoid_upscaling;
|
||||||
|
@ -2499,7 +2490,7 @@ static void pass_scale_main(struct gl_video *p)
|
||||||
|
|
||||||
if (use_linear) {
|
if (use_linear) {
|
||||||
p->use_linear = true;
|
p->use_linear = true;
|
||||||
pass_linearize(p->sc, p->image_params.color.gamma);
|
pass_linearize(p->sc, p->image_params.color.transfer);
|
||||||
pass_opt_hook_point(p, "LINEAR", NULL);
|
pass_opt_hook_point(p, "LINEAR", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2552,8 +2543,9 @@ static void pass_scale_main(struct gl_video *p)
|
||||||
// rendering)
|
// rendering)
|
||||||
// If OSD is true, ignore any changes that may have been made to the video
|
// If OSD is true, ignore any changes that may have been made to the video
|
||||||
// by previous passes (i.e. linear scaling)
|
// by previous passes (i.e. linear scaling)
|
||||||
static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
|
static void pass_colormanage(struct gl_video *p, struct pl_color_space src,
|
||||||
struct mp_colorspace fbo_csp, int flags, bool osd)
|
enum mp_csp_light src_light,
|
||||||
|
struct pl_color_space fbo_csp, int flags, bool osd)
|
||||||
{
|
{
|
||||||
struct ra *ra = p->ra;
|
struct ra *ra = p->ra;
|
||||||
|
|
||||||
|
@ -2561,18 +2553,17 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
|
||||||
// unless specific transfer function, primaries or target peak
|
// unless specific transfer function, primaries or target peak
|
||||||
// is set. If values are set to _AUTO, the most likely intended
|
// is set. If values are set to _AUTO, the most likely intended
|
||||||
// values are guesstimated later in this function.
|
// values are guesstimated later in this function.
|
||||||
struct mp_colorspace dst = {
|
struct pl_color_space dst = {
|
||||||
.gamma = p->opts.target_trc == MP_CSP_TRC_AUTO ?
|
.transfer = p->opts.target_trc == PL_COLOR_TRC_UNKNOWN ?
|
||||||
fbo_csp.gamma : p->opts.target_trc,
|
fbo_csp.transfer : p->opts.target_trc,
|
||||||
.primaries = p->opts.target_prim == MP_CSP_PRIM_AUTO ?
|
.primaries = p->opts.target_prim == PL_COLOR_PRIM_UNKNOWN ?
|
||||||
fbo_csp.primaries : p->opts.target_prim,
|
fbo_csp.primaries : p->opts.target_prim,
|
||||||
.light = MP_CSP_LIGHT_DISPLAY,
|
|
||||||
.hdr.max_luma = !p->opts.target_peak ?
|
.hdr.max_luma = !p->opts.target_peak ?
|
||||||
fbo_csp.hdr.max_luma : p->opts.target_peak,
|
fbo_csp.hdr.max_luma : p->opts.target_peak,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!p->colorspace_override_warned &&
|
if (!p->colorspace_override_warned &&
|
||||||
((fbo_csp.gamma && dst.gamma != fbo_csp.gamma) ||
|
((fbo_csp.transfer && dst.transfer != fbo_csp.transfer) ||
|
||||||
(fbo_csp.primaries && dst.primaries != fbo_csp.primaries)))
|
(fbo_csp.primaries && dst.primaries != fbo_csp.primaries)))
|
||||||
{
|
{
|
||||||
MP_WARN(p, "One or more colorspace value is being overridden "
|
MP_WARN(p, "One or more colorspace value is being overridden "
|
||||||
|
@ -2580,44 +2571,44 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
|
||||||
"transfer function: (dst: %s, fbo: %s), "
|
"transfer function: (dst: %s, fbo: %s), "
|
||||||
"primaries: (dst: %s, fbo: %s). "
|
"primaries: (dst: %s, fbo: %s). "
|
||||||
"Rendering can lead to incorrect results!\n",
|
"Rendering can lead to incorrect results!\n",
|
||||||
m_opt_choice_str(mp_csp_trc_names, dst.gamma),
|
m_opt_choice_str(pl_csp_trc_names, dst.transfer),
|
||||||
m_opt_choice_str(mp_csp_trc_names, fbo_csp.gamma),
|
m_opt_choice_str(pl_csp_trc_names, fbo_csp.transfer),
|
||||||
m_opt_choice_str(mp_csp_prim_names, dst.primaries),
|
m_opt_choice_str(pl_csp_prim_names, dst.primaries),
|
||||||
m_opt_choice_str(mp_csp_prim_names, fbo_csp.primaries));
|
m_opt_choice_str(pl_csp_prim_names, fbo_csp.primaries));
|
||||||
p->colorspace_override_warned = true;
|
p->colorspace_override_warned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst.gamma == MP_CSP_TRC_HLG)
|
enum mp_csp_light dst_light = dst.transfer == PL_COLOR_TRC_HLG ?
|
||||||
dst.light = MP_CSP_LIGHT_SCENE_HLG;
|
MP_CSP_LIGHT_SCENE_HLG : MP_CSP_LIGHT_DISPLAY;
|
||||||
|
|
||||||
if (p->use_lut_3d && (flags & RENDER_SCREEN_COLOR)) {
|
if (p->use_lut_3d && (flags & RENDER_SCREEN_COLOR)) {
|
||||||
// The 3DLUT is always generated against the video's original source
|
// The 3DLUT is always generated against the video's original source
|
||||||
// space, *not* the reference space. (To avoid having to regenerate
|
// space, *not* the reference space. (To avoid having to regenerate
|
||||||
// the 3DLUT for the OSD on every frame)
|
// the 3DLUT for the OSD on every frame)
|
||||||
enum mp_csp_prim prim_orig = p->image_params.color.primaries;
|
enum pl_color_primaries prim_orig = p->image_params.color.primaries;
|
||||||
enum mp_csp_trc trc_orig = p->image_params.color.gamma;
|
enum pl_color_transfer trc_orig = p->image_params.color.transfer;
|
||||||
|
|
||||||
// One exception: HDR is not implemented by LittleCMS for technical
|
// One exception: HDR is not implemented by LittleCMS for technical
|
||||||
// limitation reasons, so we use a gamma 2.2 input curve here instead.
|
// limitation reasons, so we use a gamma 2.2 input curve here instead.
|
||||||
// We could pick any value we want here, the difference is just coding
|
// We could pick any value we want here, the difference is just coding
|
||||||
// efficiency.
|
// efficiency.
|
||||||
if (mp_trc_is_hdr(trc_orig))
|
if (mp_trc_is_hdr(trc_orig))
|
||||||
trc_orig = MP_CSP_TRC_GAMMA22;
|
trc_orig = PL_COLOR_TRC_GAMMA22;
|
||||||
|
|
||||||
if (gl_video_get_lut3d(p, prim_orig, trc_orig)) {
|
if (gl_video_get_lut3d(p, prim_orig, trc_orig)) {
|
||||||
dst.primaries = prim_orig;
|
dst.primaries = prim_orig;
|
||||||
dst.gamma = trc_orig;
|
dst.transfer = trc_orig;
|
||||||
assert(dst.primaries && dst.gamma);
|
assert(dst.primaries && dst.transfer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst.primaries == MP_CSP_PRIM_AUTO) {
|
if (dst.primaries == PL_COLOR_PRIM_UNKNOWN) {
|
||||||
// The vast majority of people are on sRGB or BT.709 displays, so pick
|
// The vast majority of people are on sRGB or BT.709 displays, so pick
|
||||||
// this as the default output color space.
|
// this as the default output color space.
|
||||||
dst.primaries = MP_CSP_PRIM_BT_709;
|
dst.primaries = PL_COLOR_PRIM_BT_709;
|
||||||
|
|
||||||
if (src.primaries == MP_CSP_PRIM_BT_601_525 ||
|
if (src.primaries == PL_COLOR_PRIM_BT_601_525 ||
|
||||||
src.primaries == MP_CSP_PRIM_BT_601_625)
|
src.primaries == PL_COLOR_PRIM_BT_601_625)
|
||||||
{
|
{
|
||||||
// Since we auto-pick BT.601 and BT.709 based on the dimensions,
|
// Since we auto-pick BT.601 and BT.709 based on the dimensions,
|
||||||
// combined with the fact that they're very similar to begin with,
|
// combined with the fact that they're very similar to begin with,
|
||||||
|
@ -2627,28 +2618,28 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst.gamma == MP_CSP_TRC_AUTO) {
|
if (dst.transfer == PL_COLOR_TRC_UNKNOWN) {
|
||||||
// Most people seem to complain when the image is darker or brighter
|
// Most people seem to complain when the image is darker or brighter
|
||||||
// than what they're "used to", so just avoid changing the gamma
|
// than what they're "used to", so just avoid changing the gamma
|
||||||
// altogether by default. The only exceptions to this rule apply to
|
// altogether by default. The only exceptions to this rule apply to
|
||||||
// very unusual TRCs, which even hardcode technoluddites would probably
|
// very unusual TRCs, which even hardcode technoluddites would probably
|
||||||
// not enjoy viewing unaltered.
|
// not enjoy viewing unaltered.
|
||||||
dst.gamma = src.gamma;
|
dst.transfer = src.transfer;
|
||||||
|
|
||||||
// Avoid outputting linear light or HDR content "by default". For these
|
// Avoid outputting linear light or HDR content "by default". For these
|
||||||
// just pick gamma 2.2 as a default, since it's a good estimate for
|
// just pick gamma 2.2 as a default, since it's a good estimate for
|
||||||
// the response of typical displays
|
// the response of typical displays
|
||||||
if (dst.gamma == MP_CSP_TRC_LINEAR || mp_trc_is_hdr(dst.gamma))
|
if (dst.transfer == PL_COLOR_TRC_LINEAR || mp_trc_is_hdr(dst.transfer))
|
||||||
dst.gamma = MP_CSP_TRC_GAMMA22;
|
dst.transfer = PL_COLOR_TRC_GAMMA22;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's no specific signal peak known for the output display, infer
|
// If there's no specific signal peak known for the output display, infer
|
||||||
// it from the chosen transfer function. Also normalize the src peak, in
|
// it from the chosen transfer function. Also normalize the src peak, in
|
||||||
// case it was unknown
|
// case it was unknown
|
||||||
if (!dst.hdr.max_luma)
|
if (!dst.hdr.max_luma)
|
||||||
dst.hdr.max_luma = mp_trc_nom_peak(dst.gamma) * MP_REF_WHITE;
|
dst.hdr.max_luma = mp_trc_nom_peak(dst.transfer) * MP_REF_WHITE;
|
||||||
if (!src.hdr.max_luma)
|
if (!src.hdr.max_luma)
|
||||||
src.hdr.max_luma = mp_trc_nom_peak(src.gamma) * MP_REF_WHITE;
|
src.hdr.max_luma = mp_trc_nom_peak(src.transfer) * MP_REF_WHITE;
|
||||||
|
|
||||||
// Whitelist supported modes
|
// Whitelist supported modes
|
||||||
switch (p->opts.tone_map.curve) {
|
switch (p->opts.tone_map.curve) {
|
||||||
|
@ -2680,7 +2671,7 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gl_tone_map_opts tone_map = p->opts.tone_map;
|
struct gl_tone_map_opts tone_map = p->opts.tone_map;
|
||||||
bool detect_peak = tone_map.compute_peak >= 0 && mp_trc_is_hdr(src.gamma)
|
bool detect_peak = tone_map.compute_peak >= 0 && mp_trc_is_hdr(src.transfer)
|
||||||
&& src.hdr.max_luma > dst.hdr.max_luma;
|
&& src.hdr.max_luma > dst.hdr.max_luma;
|
||||||
|
|
||||||
if (detect_peak && !p->hdr_peak_ssbo) {
|
if (detect_peak && !p->hdr_peak_ssbo) {
|
||||||
|
@ -2719,7 +2710,7 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapt from src to dst as necessary
|
// Adapt from src to dst as necessary
|
||||||
pass_color_map(p->sc, p->use_linear && !osd, src, dst, &tone_map);
|
pass_color_map(p->sc, p->use_linear && !osd, src, dst, src_light, dst_light, &tone_map);
|
||||||
|
|
||||||
if (p->use_lut_3d && (flags & RENDER_SCREEN_COLOR)) {
|
if (p->use_lut_3d && (flags & RENDER_SCREEN_COLOR)) {
|
||||||
gl_sc_uniform_texture(p->sc, "lut_3d", p->lut_3d_texture);
|
gl_sc_uniform_texture(p->sc, "lut_3d", p->lut_3d_texture);
|
||||||
|
@ -2910,13 +2901,13 @@ static void pass_draw_osd(struct gl_video *p, int osd_flags, int frame_flags,
|
||||||
// When subtitles need to be color managed, assume they're in sRGB
|
// When subtitles need to be color managed, assume they're in sRGB
|
||||||
// (for lack of anything saner to do)
|
// (for lack of anything saner to do)
|
||||||
if (cms) {
|
if (cms) {
|
||||||
static const struct mp_colorspace csp_srgb = {
|
static const struct pl_color_space csp_srgb = {
|
||||||
.primaries = MP_CSP_PRIM_BT_709,
|
.primaries = PL_COLOR_PRIM_BT_709,
|
||||||
.gamma = MP_CSP_TRC_SRGB,
|
.transfer = PL_COLOR_TRC_SRGB,
|
||||||
.light = MP_CSP_LIGHT_DISPLAY,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pass_colormanage(p, csp_srgb, fbo->color_space, frame_flags, true);
|
pass_colormanage(p, csp_srgb, MP_CSP_LIGHT_DISPLAY, fbo->color_space,
|
||||||
|
frame_flags, true);
|
||||||
}
|
}
|
||||||
mpgl_osd_draw_finish(p->osd, n, p->sc, fbo);
|
mpgl_osd_draw_finish(p->osd, n, p->sc, fbo);
|
||||||
}
|
}
|
||||||
|
@ -3041,7 +3032,7 @@ static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi,
|
||||||
rect.mt *= scale[1]; rect.mb *= scale[1];
|
rect.mt *= scale[1]; rect.mb *= scale[1];
|
||||||
// We should always blend subtitles in non-linear light
|
// We should always blend subtitles in non-linear light
|
||||||
if (p->use_linear) {
|
if (p->use_linear) {
|
||||||
pass_delinearize(p->sc, p->image_params.color.gamma);
|
pass_delinearize(p->sc, p->image_params.color.transfer);
|
||||||
p->use_linear = false;
|
p->use_linear = false;
|
||||||
}
|
}
|
||||||
finish_pass_tex(p, &p->blend_subs_tex, p->texture_w, p->texture_h);
|
finish_pass_tex(p, &p->blend_subs_tex, p->texture_w, p->texture_h);
|
||||||
|
@ -3068,7 +3059,8 @@ static void pass_draw_to_screen(struct gl_video *p, const struct ra_fbo *fbo, in
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(user_gamma));)
|
GLSL(color.rgb = pow(color.rgb, vec3(user_gamma));)
|
||||||
}
|
}
|
||||||
|
|
||||||
pass_colormanage(p, p->image_params.color, fbo->color_space, flags, false);
|
pass_colormanage(p, p->image_params.color, p->image_params.light,
|
||||||
|
fbo->color_space, flags, false);
|
||||||
|
|
||||||
// Since finish_pass_fbo doesn't work with compute shaders, and neither
|
// Since finish_pass_fbo doesn't work with compute shaders, and neither
|
||||||
// does the checkerboard/dither code, we may need an indirection via
|
// does the checkerboard/dither code, we may need an indirection via
|
||||||
|
@ -3123,7 +3115,7 @@ static bool update_surface(struct gl_video *p, struct mp_image *mpi,
|
||||||
// because mixing in compressed light artificially darkens the results
|
// because mixing in compressed light artificially darkens the results
|
||||||
if (!p->use_linear) {
|
if (!p->use_linear) {
|
||||||
p->use_linear = true;
|
p->use_linear = true;
|
||||||
pass_linearize(p->sc, p->image_params.color.gamma);
|
pass_linearize(p->sc, p->image_params.color.transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish_pass_tex(p, &surf->tex, vp_w, vp_h);
|
finish_pass_tex(p, &surf->tex, vp_w, vp_h);
|
||||||
|
@ -3914,8 +3906,8 @@ static void check_gl_features(struct gl_video *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int use_cms = p->opts.target_prim != MP_CSP_PRIM_AUTO ||
|
int use_cms = p->opts.target_prim != PL_COLOR_PRIM_UNKNOWN ||
|
||||||
p->opts.target_trc != MP_CSP_TRC_AUTO || p->use_lut_3d;
|
p->opts.target_trc != PL_COLOR_TRC_UNKNOWN || p->use_lut_3d;
|
||||||
|
|
||||||
// mix() is needed for some gamma functions
|
// mix() is needed for some gamma functions
|
||||||
if (!have_mglsl && (p->opts.linear_downscaling ||
|
if (!have_mglsl && (p->opts.linear_downscaling ||
|
||||||
|
@ -3927,8 +3919,8 @@ static void check_gl_features(struct gl_video *p)
|
||||||
MP_WARN(p, "Disabling linear/sigmoid scaling (GLSL version too old).\n");
|
MP_WARN(p, "Disabling linear/sigmoid scaling (GLSL version too old).\n");
|
||||||
}
|
}
|
||||||
if (!have_mglsl && use_cms) {
|
if (!have_mglsl && use_cms) {
|
||||||
p->opts.target_prim = MP_CSP_PRIM_AUTO;
|
p->opts.target_prim = PL_COLOR_PRIM_UNKNOWN;
|
||||||
p->opts.target_trc = MP_CSP_TRC_AUTO;
|
p->opts.target_trc = PL_COLOR_TRC_UNKNOWN;
|
||||||
p->use_lut_3d = false;
|
p->use_lut_3d = false;
|
||||||
MP_WARN(p, "Disabling color management (GLSL version too old).\n");
|
MP_WARN(p, "Disabling color management (GLSL version too old).\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,6 @@ void gl_video_set_ambient_lux(struct gl_video *p, int lux);
|
||||||
void gl_video_set_icc_profile(struct gl_video *p, bstr icc_data);
|
void gl_video_set_icc_profile(struct gl_video *p, bstr icc_data);
|
||||||
bool gl_video_icc_auto_enabled(struct gl_video *p);
|
bool gl_video_icc_auto_enabled(struct gl_video *p);
|
||||||
bool gl_video_gamma_auto_enabled(struct gl_video *p);
|
bool gl_video_gamma_auto_enabled(struct gl_video *p);
|
||||||
struct mp_colorspace gl_video_get_output_colorspace(struct gl_video *p);
|
|
||||||
|
|
||||||
void gl_video_reset(struct gl_video *p);
|
void gl_video_reset(struct gl_video *p);
|
||||||
bool gl_video_showing_interpolated_frame(struct gl_video *p);
|
bool gl_video_showing_interpolated_frame(struct gl_video *p);
|
||||||
|
|
|
@ -338,9 +338,9 @@ static const float SLOG_A = 0.432699,
|
||||||
// These functions always output to a normalized scale of [0,1], for
|
// These functions always output to a normalized scale of [0,1], for
|
||||||
// convenience of the video.c code that calls it. To get the values in an
|
// convenience of the video.c code that calls it. To get the values in an
|
||||||
// absolute scale, multiply the result by `mp_trc_nom_peak(trc)`
|
// absolute scale, multiply the result by `mp_trc_nom_peak(trc)`
|
||||||
void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
void pass_linearize(struct gl_shader_cache *sc, enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
if (trc == MP_CSP_TRC_LINEAR)
|
if (trc == PL_COLOR_TRC_LINEAR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GLSLF("// linearize\n");
|
GLSLF("// linearize\n");
|
||||||
|
@ -353,40 +353,40 @@ void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
||||||
GLSL(color.rgb = clamp(color.rgb, 0.0, 1.0);)
|
GLSL(color.rgb = clamp(color.rgb, 0.0, 1.0);)
|
||||||
|
|
||||||
switch (trc) {
|
switch (trc) {
|
||||||
case MP_CSP_TRC_SRGB:
|
case PL_COLOR_TRC_SRGB:
|
||||||
GLSLF("color.rgb = mix(color.rgb * vec3(1.0/12.92), \n"
|
GLSLF("color.rgb = mix(color.rgb * vec3(1.0/12.92), \n"
|
||||||
" pow((color.rgb + vec3(0.055))/vec3(1.055), vec3(2.4)), \n"
|
" pow((color.rgb + vec3(0.055))/vec3(1.055), vec3(2.4)), \n"
|
||||||
" %s(lessThan(vec3(0.04045), color.rgb))); \n",
|
" %s(lessThan(vec3(0.04045), color.rgb))); \n",
|
||||||
gl_sc_bvec(sc, 3));
|
gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_BT_1886:
|
case PL_COLOR_TRC_BT_1886:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(2.4));)
|
GLSL(color.rgb = pow(color.rgb, vec3(2.4));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA18:
|
case PL_COLOR_TRC_GAMMA18:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.8));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.8));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA20:
|
case PL_COLOR_TRC_GAMMA20:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(2.0));)
|
GLSL(color.rgb = pow(color.rgb, vec3(2.0));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA22:
|
case PL_COLOR_TRC_GAMMA22:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(2.2));)
|
GLSL(color.rgb = pow(color.rgb, vec3(2.2));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA24:
|
case PL_COLOR_TRC_GAMMA24:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(2.4));)
|
GLSL(color.rgb = pow(color.rgb, vec3(2.4));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA26:
|
case PL_COLOR_TRC_GAMMA26:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(2.6));)
|
GLSL(color.rgb = pow(color.rgb, vec3(2.6));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA28:
|
case PL_COLOR_TRC_GAMMA28:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(2.8));)
|
GLSL(color.rgb = pow(color.rgb, vec3(2.8));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_PRO_PHOTO:
|
case PL_COLOR_TRC_PRO_PHOTO:
|
||||||
GLSLF("color.rgb = mix(color.rgb * vec3(1.0/16.0), \n"
|
GLSLF("color.rgb = mix(color.rgb * vec3(1.0/16.0), \n"
|
||||||
" pow(color.rgb, vec3(1.8)), \n"
|
" pow(color.rgb, vec3(1.8)), \n"
|
||||||
" %s(lessThan(vec3(0.03125), color.rgb))); \n",
|
" %s(lessThan(vec3(0.03125), color.rgb))); \n",
|
||||||
gl_sc_bvec(sc, 3));
|
gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_PQ:
|
case PL_COLOR_TRC_PQ:
|
||||||
GLSLF("color.rgb = pow(color.rgb, vec3(1.0/%f));\n", PQ_M2);
|
GLSLF("color.rgb = pow(color.rgb, vec3(1.0/%f));\n", PQ_M2);
|
||||||
GLSLF("color.rgb = max(color.rgb - vec3(%f), vec3(0.0)) \n"
|
GLSLF("color.rgb = max(color.rgb - vec3(%f), vec3(0.0)) \n"
|
||||||
" / (vec3(%f) - vec3(%f) * color.rgb);\n",
|
" / (vec3(%f) - vec3(%f) * color.rgb);\n",
|
||||||
|
@ -396,33 +396,33 @@ void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
||||||
// MP_REF_WHITE instead, so rescale
|
// MP_REF_WHITE instead, so rescale
|
||||||
GLSLF("color.rgb *= vec3(%f);\n", 10000 / MP_REF_WHITE);
|
GLSLF("color.rgb *= vec3(%f);\n", 10000 / MP_REF_WHITE);
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_HLG:
|
case PL_COLOR_TRC_HLG:
|
||||||
GLSLF("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,\n"
|
GLSLF("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,\n"
|
||||||
" exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f),\n"
|
" exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f),\n"
|
||||||
" %s(lessThan(vec3(0.5), color.rgb)));\n",
|
" %s(lessThan(vec3(0.5), color.rgb)));\n",
|
||||||
HLG_C, HLG_A, HLG_B, gl_sc_bvec(sc, 3));
|
HLG_C, HLG_A, HLG_B, gl_sc_bvec(sc, 3));
|
||||||
GLSLF("color.rgb *= vec3(1.0/%f);\n", MP_REF_WHITE_HLG);
|
GLSLF("color.rgb *= vec3(1.0/%f);\n", MP_REF_WHITE_HLG);
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_V_LOG:
|
case PL_COLOR_TRC_V_LOG:
|
||||||
GLSLF("color.rgb = mix((color.rgb - vec3(0.125)) * vec3(1.0/5.6), \n"
|
GLSLF("color.rgb = mix((color.rgb - vec3(0.125)) * vec3(1.0/5.6), \n"
|
||||||
" pow(vec3(10.0), (color.rgb - vec3(%f)) * vec3(1.0/%f)) \n"
|
" pow(vec3(10.0), (color.rgb - vec3(%f)) * vec3(1.0/%f)) \n"
|
||||||
" - vec3(%f), \n"
|
" - vec3(%f), \n"
|
||||||
" %s(lessThanEqual(vec3(0.181), color.rgb))); \n",
|
" %s(lessThanEqual(vec3(0.181), color.rgb))); \n",
|
||||||
VLOG_D, VLOG_C, VLOG_B, gl_sc_bvec(sc, 3));
|
VLOG_D, VLOG_C, VLOG_B, gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_S_LOG1:
|
case PL_COLOR_TRC_S_LOG1:
|
||||||
GLSLF("color.rgb = pow(vec3(10.0), (color.rgb - vec3(%f)) * vec3(1.0/%f))\n"
|
GLSLF("color.rgb = pow(vec3(10.0), (color.rgb - vec3(%f)) * vec3(1.0/%f))\n"
|
||||||
" - vec3(%f);\n",
|
" - vec3(%f);\n",
|
||||||
SLOG_C, SLOG_A, SLOG_B);
|
SLOG_C, SLOG_A, SLOG_B);
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_S_LOG2:
|
case PL_COLOR_TRC_S_LOG2:
|
||||||
GLSLF("color.rgb = mix((color.rgb - vec3(%f)) * vec3(1.0/%f), \n"
|
GLSLF("color.rgb = mix((color.rgb - vec3(%f)) * vec3(1.0/%f), \n"
|
||||||
" (pow(vec3(10.0), (color.rgb - vec3(%f)) * vec3(1.0/%f)) \n"
|
" (pow(vec3(10.0), (color.rgb - vec3(%f)) * vec3(1.0/%f)) \n"
|
||||||
" - vec3(%f)) * vec3(1.0/%f), \n"
|
" - vec3(%f)) * vec3(1.0/%f), \n"
|
||||||
" %s(lessThanEqual(vec3(%f), color.rgb))); \n",
|
" %s(lessThanEqual(vec3(%f), color.rgb))); \n",
|
||||||
SLOG_Q, SLOG_P, SLOG_C, SLOG_A, SLOG_B, SLOG_K2, gl_sc_bvec(sc, 3), SLOG_Q);
|
SLOG_Q, SLOG_P, SLOG_C, SLOG_A, SLOG_B, SLOG_K2, gl_sc_bvec(sc, 3), SLOG_Q);
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_ST428:
|
case PL_COLOR_TRC_ST428:
|
||||||
GLSL(color.rgb = vec3(52.37/48.0) * pow(color.rgb, vec3(2.6)););
|
GLSL(color.rgb = vec3(52.37/48.0) * pow(color.rgb, vec3(2.6)););
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -438,9 +438,9 @@ void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
||||||
// reference monitor.
|
// reference monitor.
|
||||||
//
|
//
|
||||||
// Like pass_linearize, this functions ingests values on an normalized scale
|
// Like pass_linearize, this functions ingests values on an normalized scale
|
||||||
void pass_delinearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
void pass_delinearize(struct gl_shader_cache *sc, enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
if (trc == MP_CSP_TRC_LINEAR)
|
if (trc == PL_COLOR_TRC_LINEAR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GLSLF("// delinearize\n");
|
GLSLF("// delinearize\n");
|
||||||
|
@ -448,41 +448,41 @@ void pass_delinearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
||||||
GLSLF("color.rgb *= vec3(%f);\n", mp_trc_nom_peak(trc));
|
GLSLF("color.rgb *= vec3(%f);\n", mp_trc_nom_peak(trc));
|
||||||
|
|
||||||
switch (trc) {
|
switch (trc) {
|
||||||
case MP_CSP_TRC_SRGB:
|
case PL_COLOR_TRC_SRGB:
|
||||||
GLSLF("color.rgb = mix(color.rgb * vec3(12.92), \n"
|
GLSLF("color.rgb = mix(color.rgb * vec3(12.92), \n"
|
||||||
" vec3(1.055) * pow(color.rgb, vec3(1.0/2.4)) \n"
|
" vec3(1.055) * pow(color.rgb, vec3(1.0/2.4)) \n"
|
||||||
" - vec3(0.055), \n"
|
" - vec3(0.055), \n"
|
||||||
" %s(lessThanEqual(vec3(0.0031308), color.rgb))); \n",
|
" %s(lessThanEqual(vec3(0.0031308), color.rgb))); \n",
|
||||||
gl_sc_bvec(sc, 3));
|
gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_BT_1886:
|
case PL_COLOR_TRC_BT_1886:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.4));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.4));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA18:
|
case PL_COLOR_TRC_GAMMA18:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/1.8));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.0/1.8));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA20:
|
case PL_COLOR_TRC_GAMMA20:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.0));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.0));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA22:
|
case PL_COLOR_TRC_GAMMA22:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.2));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.2));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA24:
|
case PL_COLOR_TRC_GAMMA24:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.4));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.4));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA26:
|
case PL_COLOR_TRC_GAMMA26:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.6));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.6));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_GAMMA28:
|
case PL_COLOR_TRC_GAMMA28:
|
||||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.8));)
|
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.8));)
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_PRO_PHOTO:
|
case PL_COLOR_TRC_PRO_PHOTO:
|
||||||
GLSLF("color.rgb = mix(color.rgb * vec3(16.0), \n"
|
GLSLF("color.rgb = mix(color.rgb * vec3(16.0), \n"
|
||||||
" pow(color.rgb, vec3(1.0/1.8)), \n"
|
" pow(color.rgb, vec3(1.0/1.8)), \n"
|
||||||
" %s(lessThanEqual(vec3(0.001953), color.rgb))); \n",
|
" %s(lessThanEqual(vec3(0.001953), color.rgb))); \n",
|
||||||
gl_sc_bvec(sc, 3));
|
gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_PQ:
|
case PL_COLOR_TRC_PQ:
|
||||||
GLSLF("color.rgb *= vec3(1.0/%f);\n", 10000 / MP_REF_WHITE);
|
GLSLF("color.rgb *= vec3(1.0/%f);\n", 10000 / MP_REF_WHITE);
|
||||||
GLSLF("color.rgb = pow(color.rgb, vec3(%f));\n", PQ_M1);
|
GLSLF("color.rgb = pow(color.rgb, vec3(%f));\n", PQ_M1);
|
||||||
GLSLF("color.rgb = (vec3(%f) + vec3(%f) * color.rgb) \n"
|
GLSLF("color.rgb = (vec3(%f) + vec3(%f) * color.rgb) \n"
|
||||||
|
@ -490,32 +490,32 @@ void pass_delinearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
|
||||||
PQ_C1, PQ_C2, PQ_C3);
|
PQ_C1, PQ_C2, PQ_C3);
|
||||||
GLSLF("color.rgb = pow(color.rgb, vec3(%f));\n", PQ_M2);
|
GLSLF("color.rgb = pow(color.rgb, vec3(%f));\n", PQ_M2);
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_HLG:
|
case PL_COLOR_TRC_HLG:
|
||||||
GLSLF("color.rgb *= vec3(%f);\n", MP_REF_WHITE_HLG);
|
GLSLF("color.rgb *= vec3(%f);\n", MP_REF_WHITE_HLG);
|
||||||
GLSLF("color.rgb = mix(vec3(0.5) * sqrt(color.rgb),\n"
|
GLSLF("color.rgb = mix(vec3(0.5) * sqrt(color.rgb),\n"
|
||||||
" vec3(%f) * log(color.rgb - vec3(%f)) + vec3(%f),\n"
|
" vec3(%f) * log(color.rgb - vec3(%f)) + vec3(%f),\n"
|
||||||
" %s(lessThan(vec3(1.0), color.rgb)));\n",
|
" %s(lessThan(vec3(1.0), color.rgb)));\n",
|
||||||
HLG_A, HLG_B, HLG_C, gl_sc_bvec(sc, 3));
|
HLG_A, HLG_B, HLG_C, gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_V_LOG:
|
case PL_COLOR_TRC_V_LOG:
|
||||||
GLSLF("color.rgb = mix(vec3(5.6) * color.rgb + vec3(0.125), \n"
|
GLSLF("color.rgb = mix(vec3(5.6) * color.rgb + vec3(0.125), \n"
|
||||||
" vec3(%f) * log(color.rgb + vec3(%f)) \n"
|
" vec3(%f) * log(color.rgb + vec3(%f)) \n"
|
||||||
" + vec3(%f), \n"
|
" + vec3(%f), \n"
|
||||||
" %s(lessThanEqual(vec3(0.01), color.rgb))); \n",
|
" %s(lessThanEqual(vec3(0.01), color.rgb))); \n",
|
||||||
VLOG_C / M_LN10, VLOG_B, VLOG_D, gl_sc_bvec(sc, 3));
|
VLOG_C / M_LN10, VLOG_B, VLOG_D, gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_S_LOG1:
|
case PL_COLOR_TRC_S_LOG1:
|
||||||
GLSLF("color.rgb = vec3(%f) * log(color.rgb + vec3(%f)) + vec3(%f);\n",
|
GLSLF("color.rgb = vec3(%f) * log(color.rgb + vec3(%f)) + vec3(%f);\n",
|
||||||
SLOG_A / M_LN10, SLOG_B, SLOG_C);
|
SLOG_A / M_LN10, SLOG_B, SLOG_C);
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_S_LOG2:
|
case PL_COLOR_TRC_S_LOG2:
|
||||||
GLSLF("color.rgb = mix(vec3(%f) * color.rgb + vec3(%f), \n"
|
GLSLF("color.rgb = mix(vec3(%f) * color.rgb + vec3(%f), \n"
|
||||||
" vec3(%f) * log(vec3(%f) * color.rgb + vec3(%f)) \n"
|
" vec3(%f) * log(vec3(%f) * color.rgb + vec3(%f)) \n"
|
||||||
" + vec3(%f), \n"
|
" + vec3(%f), \n"
|
||||||
" %s(lessThanEqual(vec3(0.0), color.rgb))); \n",
|
" %s(lessThanEqual(vec3(0.0), color.rgb))); \n",
|
||||||
SLOG_P, SLOG_Q, SLOG_A / M_LN10, SLOG_K2, SLOG_B, SLOG_C, gl_sc_bvec(sc, 3));
|
SLOG_P, SLOG_Q, SLOG_A / M_LN10, SLOG_K2, SLOG_B, SLOG_C, gl_sc_bvec(sc, 3));
|
||||||
break;
|
break;
|
||||||
case MP_CSP_TRC_ST428:
|
case PL_COLOR_TRC_ST428:
|
||||||
GLSL(color.rgb = pow(color.rgb * vec3(48.0/52.37), vec3(1.0/2.6)););
|
GLSL(color.rgb = pow(color.rgb * vec3(48.0/52.37), vec3(1.0/2.6)););
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -834,7 +834,8 @@ static void pass_tone_map(struct gl_shader_cache *sc,
|
||||||
// the caller to have already bound the appropriate SSBO and set up the compute
|
// the caller to have already bound the appropriate SSBO and set up the compute
|
||||||
// shader metadata
|
// shader metadata
|
||||||
void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
|
void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
|
||||||
struct mp_colorspace src, struct mp_colorspace dst,
|
struct pl_color_space src, struct pl_color_space dst,
|
||||||
|
enum mp_csp_light src_light, enum mp_csp_light dst_light,
|
||||||
const struct gl_tone_map_opts *opts)
|
const struct gl_tone_map_opts *opts)
|
||||||
{
|
{
|
||||||
GLSLF("// color mapping\n");
|
GLSLF("// color mapping\n");
|
||||||
|
@ -847,29 +848,29 @@ void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
|
||||||
mp_get_rgb2xyz_matrix(mp_get_csp_primaries(dst.primaries), rgb2xyz);
|
mp_get_rgb2xyz_matrix(mp_get_csp_primaries(dst.primaries), rgb2xyz);
|
||||||
gl_sc_uniform_vec3(sc, "dst_luma", rgb2xyz[1]);
|
gl_sc_uniform_vec3(sc, "dst_luma", rgb2xyz[1]);
|
||||||
|
|
||||||
bool need_ootf = src.light != dst.light;
|
bool need_ootf = src_light != dst_light;
|
||||||
if (src.light == MP_CSP_LIGHT_SCENE_HLG && src.hdr.max_luma != dst.hdr.max_luma)
|
if (src_light == MP_CSP_LIGHT_SCENE_HLG && src.hdr.max_luma != dst.hdr.max_luma)
|
||||||
need_ootf = true;
|
need_ootf = true;
|
||||||
|
|
||||||
// All operations from here on require linear light as a starting point,
|
// All operations from here on require linear light as a starting point,
|
||||||
// so we linearize even if src.gamma == dst.gamma when one of the other
|
// so we linearize even if src.gamma == dst.transfer when one of the other
|
||||||
// operations needs it
|
// operations needs it
|
||||||
bool need_linear = src.gamma != dst.gamma ||
|
bool need_linear = src.transfer != dst.transfer ||
|
||||||
src.primaries != dst.primaries ||
|
src.primaries != dst.primaries ||
|
||||||
src.hdr.max_luma != dst.hdr.max_luma ||
|
src.hdr.max_luma != dst.hdr.max_luma ||
|
||||||
need_ootf;
|
need_ootf;
|
||||||
|
|
||||||
if (need_linear && !is_linear) {
|
if (need_linear && !is_linear) {
|
||||||
// We also pull it up so that 1.0 is the reference white
|
// We also pull it up so that 1.0 is the reference white
|
||||||
pass_linearize(sc, src.gamma);
|
pass_linearize(sc, src.transfer);
|
||||||
is_linear = true;
|
is_linear = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-scale the incoming values into an absolute scale
|
// Pre-scale the incoming values into an absolute scale
|
||||||
GLSLF("color.rgb *= vec3(%f);\n", mp_trc_nom_peak(src.gamma));
|
GLSLF("color.rgb *= vec3(%f);\n", mp_trc_nom_peak(src.transfer));
|
||||||
|
|
||||||
if (need_ootf)
|
if (need_ootf)
|
||||||
pass_ootf(sc, src.light, src.hdr.max_luma / MP_REF_WHITE);
|
pass_ootf(sc, src_light, src.hdr.max_luma / MP_REF_WHITE);
|
||||||
|
|
||||||
// Tone map to prevent clipping due to excessive brightness
|
// Tone map to prevent clipping due to excessive brightness
|
||||||
if (src.hdr.max_luma > dst.hdr.max_luma) {
|
if (src.hdr.max_luma > dst.hdr.max_luma) {
|
||||||
|
@ -900,14 +901,14 @@ void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_ootf)
|
if (need_ootf)
|
||||||
pass_inverse_ootf(sc, dst.light, dst.hdr.max_luma / MP_REF_WHITE);
|
pass_inverse_ootf(sc, dst_light, dst.hdr.max_luma / MP_REF_WHITE);
|
||||||
|
|
||||||
// Post-scale the outgoing values from absolute scale to normalized.
|
// Post-scale the outgoing values from absolute scale to normalized.
|
||||||
// For SDR, we normalize to the chosen signal peak. For HDR, we normalize
|
// For SDR, we normalize to the chosen signal peak. For HDR, we normalize
|
||||||
// to the encoding range of the transfer function.
|
// to the encoding range of the transfer function.
|
||||||
float dst_range = dst.hdr.max_luma / MP_REF_WHITE;
|
float dst_range = dst.hdr.max_luma / MP_REF_WHITE;
|
||||||
if (mp_trc_is_hdr(dst.gamma))
|
if (mp_trc_is_hdr(dst.transfer))
|
||||||
dst_range = mp_trc_nom_peak(dst.gamma);
|
dst_range = mp_trc_nom_peak(dst.transfer);
|
||||||
|
|
||||||
GLSLF("color.rgb *= vec3(%f);\n", 1.0 / dst_range);
|
GLSLF("color.rgb *= vec3(%f);\n", 1.0 / dst_range);
|
||||||
|
|
||||||
|
@ -919,7 +920,7 @@ void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_linear)
|
if (is_linear)
|
||||||
pass_delinearize(sc, dst.gamma);
|
pass_delinearize(sc, dst.transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wide usage friendly PRNG, shamelessly stolen from a GLSL tricks forum post.
|
// Wide usage friendly PRNG, shamelessly stolen from a GLSL tricks forum post.
|
||||||
|
@ -964,7 +965,7 @@ const struct m_sub_options deband_conf = {
|
||||||
|
|
||||||
// Stochastically sample a debanded result from a hooked texture.
|
// Stochastically sample a debanded result from a hooked texture.
|
||||||
void pass_sample_deband(struct gl_shader_cache *sc, struct deband_opts *opts,
|
void pass_sample_deband(struct gl_shader_cache *sc, struct deband_opts *opts,
|
||||||
AVLFG *lfg, enum mp_csp_trc trc)
|
AVLFG *lfg, enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
// Initialize the PRNG
|
// Initialize the PRNG
|
||||||
GLSLF("{\n");
|
GLSLF("{\n");
|
||||||
|
|
|
@ -44,15 +44,16 @@ void pass_sample_bicubic_fast(struct gl_shader_cache *sc);
|
||||||
void pass_sample_oversample(struct gl_shader_cache *sc, struct scaler *scaler,
|
void pass_sample_oversample(struct gl_shader_cache *sc, struct scaler *scaler,
|
||||||
int w, int h);
|
int w, int h);
|
||||||
|
|
||||||
void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc);
|
void pass_linearize(struct gl_shader_cache *sc, enum pl_color_transfer trc);
|
||||||
void pass_delinearize(struct gl_shader_cache *sc, enum mp_csp_trc trc);
|
void pass_delinearize(struct gl_shader_cache *sc, enum pl_color_transfer trc);
|
||||||
|
|
||||||
void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
|
void pass_color_map(struct gl_shader_cache *sc, bool is_linear,
|
||||||
struct mp_colorspace src, struct mp_colorspace dst,
|
struct pl_color_space src, struct pl_color_space dst,
|
||||||
|
enum mp_csp_light src_light, enum mp_csp_light dst_light,
|
||||||
const struct gl_tone_map_opts *opts);
|
const struct gl_tone_map_opts *opts);
|
||||||
|
|
||||||
void pass_sample_deband(struct gl_shader_cache *sc, struct deband_opts *opts,
|
void pass_sample_deband(struct gl_shader_cache *sc, struct deband_opts *opts,
|
||||||
AVLFG *lfg, enum mp_csp_trc trc);
|
AVLFG *lfg, enum pl_color_transfer trc);
|
||||||
|
|
||||||
void pass_sample_unsharp(struct gl_shader_cache *sc, float param);
|
void pass_sample_unsharp(struct gl_shader_cache *sc, float param);
|
||||||
|
|
||||||
|
|
|
@ -82,12 +82,12 @@ static size_t layout_buffer(struct mp_image *mpi, MMAL_BUFFER_HEADER_T *buffer,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MMAL_FOURCC_T map_csp(enum mp_csp csp)
|
static MMAL_FOURCC_T map_csp(enum pl_color_system csp)
|
||||||
{
|
{
|
||||||
switch (csp) {
|
switch (csp) {
|
||||||
case MP_CSP_BT_601: return MMAL_COLOR_SPACE_ITUR_BT601;
|
case PL_COLOR_SYSTEM_BT_601: return MMAL_COLOR_SPACE_ITUR_BT601;
|
||||||
case MP_CSP_BT_709: return MMAL_COLOR_SPACE_ITUR_BT709;
|
case PL_COLOR_SYSTEM_BT_709: return MMAL_COLOR_SPACE_ITUR_BT709;
|
||||||
case MP_CSP_SMPTE_240M: return MMAL_COLOR_SPACE_SMPTE240M;
|
case PL_COLOR_SYSTEM_SMPTE_240M: return MMAL_COLOR_SPACE_SMPTE240M;
|
||||||
default: return MMAL_COLOR_SPACE_UNKNOWN;
|
default: return MMAL_COLOR_SPACE_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ static int enable_renderer(struct ra_hwdec *hw)
|
||||||
input->format->es->video.height = MP_ALIGN_UP(params->h, ALIGN_H);
|
input->format->es->video.height = MP_ALIGN_UP(params->h, ALIGN_H);
|
||||||
input->format->es->video.crop = (MMAL_RECT_T){0, 0, params->w, params->h};
|
input->format->es->video.crop = (MMAL_RECT_T){0, 0, params->w, params->h};
|
||||||
input->format->es->video.par = (MMAL_RATIONAL_T){params->p_w, params->p_h};
|
input->format->es->video.par = (MMAL_RATIONAL_T){params->p_w, params->p_h};
|
||||||
input->format->es->video.color_space = map_csp(params->color.space);
|
input->format->es->video.color_space = map_csp(params->repr.sys);
|
||||||
|
|
||||||
if (mmal_port_format_commit(input))
|
if (mmal_port_format_commit(input))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -72,154 +72,6 @@ void mppl_log_set_probing(pl_log log, bool probing)
|
||||||
pl_log_update(log, ¶ms);
|
pl_log_update(log, ¶ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum pl_color_primaries mp_prim_to_pl(enum mp_csp_prim prim)
|
|
||||||
{
|
|
||||||
switch (prim) {
|
|
||||||
case MP_CSP_PRIM_AUTO: return PL_COLOR_PRIM_UNKNOWN;
|
|
||||||
case MP_CSP_PRIM_BT_601_525: return PL_COLOR_PRIM_BT_601_525;
|
|
||||||
case MP_CSP_PRIM_BT_601_625: return PL_COLOR_PRIM_BT_601_625;
|
|
||||||
case MP_CSP_PRIM_BT_709: return PL_COLOR_PRIM_BT_709;
|
|
||||||
case MP_CSP_PRIM_BT_2020: return PL_COLOR_PRIM_BT_2020;
|
|
||||||
case MP_CSP_PRIM_BT_470M: return PL_COLOR_PRIM_BT_470M;
|
|
||||||
case MP_CSP_PRIM_APPLE: return PL_COLOR_PRIM_APPLE;
|
|
||||||
case MP_CSP_PRIM_ADOBE: return PL_COLOR_PRIM_ADOBE;
|
|
||||||
case MP_CSP_PRIM_PRO_PHOTO: return PL_COLOR_PRIM_PRO_PHOTO;
|
|
||||||
case MP_CSP_PRIM_CIE_1931: return PL_COLOR_PRIM_CIE_1931;
|
|
||||||
case MP_CSP_PRIM_DCI_P3: return PL_COLOR_PRIM_DCI_P3;
|
|
||||||
case MP_CSP_PRIM_DISPLAY_P3: return PL_COLOR_PRIM_DISPLAY_P3;
|
|
||||||
case MP_CSP_PRIM_V_GAMUT: return PL_COLOR_PRIM_V_GAMUT;
|
|
||||||
case MP_CSP_PRIM_S_GAMUT: return PL_COLOR_PRIM_S_GAMUT;
|
|
||||||
case MP_CSP_PRIM_EBU_3213: return PL_COLOR_PRIM_EBU_3213;
|
|
||||||
case MP_CSP_PRIM_FILM_C: return PL_COLOR_PRIM_FILM_C;
|
|
||||||
case MP_CSP_PRIM_ACES_AP0: return PL_COLOR_PRIM_ACES_AP0;
|
|
||||||
case MP_CSP_PRIM_ACES_AP1: return PL_COLOR_PRIM_ACES_AP1;
|
|
||||||
case MP_CSP_PRIM_COUNT: return PL_COLOR_PRIM_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_ASSERT_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp_prim mp_prim_from_pl(enum pl_color_primaries prim)
|
|
||||||
{
|
|
||||||
switch (prim){
|
|
||||||
case PL_COLOR_PRIM_UNKNOWN: return MP_CSP_PRIM_AUTO;
|
|
||||||
case PL_COLOR_PRIM_BT_601_525: return MP_CSP_PRIM_BT_601_525;
|
|
||||||
case PL_COLOR_PRIM_BT_601_625: return MP_CSP_PRIM_BT_601_625;
|
|
||||||
case PL_COLOR_PRIM_BT_709: return MP_CSP_PRIM_BT_709;
|
|
||||||
case PL_COLOR_PRIM_BT_2020: return MP_CSP_PRIM_BT_2020;
|
|
||||||
case PL_COLOR_PRIM_BT_470M: return MP_CSP_PRIM_BT_470M;
|
|
||||||
case PL_COLOR_PRIM_APPLE: return MP_CSP_PRIM_APPLE;
|
|
||||||
case PL_COLOR_PRIM_ADOBE: return MP_CSP_PRIM_ADOBE;
|
|
||||||
case PL_COLOR_PRIM_PRO_PHOTO: return MP_CSP_PRIM_PRO_PHOTO;
|
|
||||||
case PL_COLOR_PRIM_CIE_1931: return MP_CSP_PRIM_CIE_1931;
|
|
||||||
case PL_COLOR_PRIM_DCI_P3: return MP_CSP_PRIM_DCI_P3;
|
|
||||||
case PL_COLOR_PRIM_DISPLAY_P3: return MP_CSP_PRIM_DISPLAY_P3;
|
|
||||||
case PL_COLOR_PRIM_V_GAMUT: return MP_CSP_PRIM_V_GAMUT;
|
|
||||||
case PL_COLOR_PRIM_S_GAMUT: return MP_CSP_PRIM_S_GAMUT;
|
|
||||||
case PL_COLOR_PRIM_EBU_3213: return MP_CSP_PRIM_EBU_3213;
|
|
||||||
case PL_COLOR_PRIM_FILM_C: return MP_CSP_PRIM_FILM_C;
|
|
||||||
case PL_COLOR_PRIM_ACES_AP0: return MP_CSP_PRIM_ACES_AP0;
|
|
||||||
case PL_COLOR_PRIM_ACES_AP1: return MP_CSP_PRIM_ACES_AP1;
|
|
||||||
case PL_COLOR_PRIM_COUNT: return MP_CSP_PRIM_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_ASSERT_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum pl_color_transfer mp_trc_to_pl(enum mp_csp_trc trc)
|
|
||||||
{
|
|
||||||
switch (trc) {
|
|
||||||
case MP_CSP_TRC_AUTO: return PL_COLOR_TRC_UNKNOWN;
|
|
||||||
case MP_CSP_TRC_BT_1886: return PL_COLOR_TRC_BT_1886;
|
|
||||||
case MP_CSP_TRC_SRGB: return PL_COLOR_TRC_SRGB;
|
|
||||||
case MP_CSP_TRC_LINEAR: return PL_COLOR_TRC_LINEAR;
|
|
||||||
case MP_CSP_TRC_GAMMA18: return PL_COLOR_TRC_GAMMA18;
|
|
||||||
case MP_CSP_TRC_GAMMA20: return PL_COLOR_TRC_GAMMA20;
|
|
||||||
case MP_CSP_TRC_GAMMA22: return PL_COLOR_TRC_GAMMA22;
|
|
||||||
case MP_CSP_TRC_GAMMA24: return PL_COLOR_TRC_GAMMA24;
|
|
||||||
case MP_CSP_TRC_GAMMA26: return PL_COLOR_TRC_GAMMA26;
|
|
||||||
case MP_CSP_TRC_GAMMA28: return PL_COLOR_TRC_GAMMA28;
|
|
||||||
case MP_CSP_TRC_PRO_PHOTO: return PL_COLOR_TRC_PRO_PHOTO;
|
|
||||||
case MP_CSP_TRC_PQ: return PL_COLOR_TRC_PQ;
|
|
||||||
case MP_CSP_TRC_HLG: return PL_COLOR_TRC_HLG;
|
|
||||||
case MP_CSP_TRC_V_LOG: return PL_COLOR_TRC_V_LOG;
|
|
||||||
case MP_CSP_TRC_S_LOG1: return PL_COLOR_TRC_S_LOG1;
|
|
||||||
case MP_CSP_TRC_S_LOG2: return PL_COLOR_TRC_S_LOG2;
|
|
||||||
case MP_CSP_TRC_ST428: return PL_COLOR_TRC_ST428;
|
|
||||||
case MP_CSP_TRC_COUNT: return PL_COLOR_TRC_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_ASSERT_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp_trc mp_trc_from_pl(enum pl_color_transfer trc)
|
|
||||||
{
|
|
||||||
switch (trc){
|
|
||||||
case PL_COLOR_TRC_UNKNOWN: return MP_CSP_TRC_AUTO;
|
|
||||||
case PL_COLOR_TRC_BT_1886: return MP_CSP_TRC_BT_1886;
|
|
||||||
case PL_COLOR_TRC_SRGB: return MP_CSP_TRC_SRGB;
|
|
||||||
case PL_COLOR_TRC_LINEAR: return MP_CSP_TRC_LINEAR;
|
|
||||||
case PL_COLOR_TRC_GAMMA18: return MP_CSP_TRC_GAMMA18;
|
|
||||||
case PL_COLOR_TRC_GAMMA20: return MP_CSP_TRC_GAMMA20;
|
|
||||||
case PL_COLOR_TRC_GAMMA22: return MP_CSP_TRC_GAMMA22;
|
|
||||||
case PL_COLOR_TRC_GAMMA24: return MP_CSP_TRC_GAMMA24;
|
|
||||||
case PL_COLOR_TRC_GAMMA26: return MP_CSP_TRC_GAMMA26;
|
|
||||||
case PL_COLOR_TRC_GAMMA28: return MP_CSP_TRC_GAMMA28;
|
|
||||||
case PL_COLOR_TRC_PRO_PHOTO: return MP_CSP_TRC_PRO_PHOTO;
|
|
||||||
case PL_COLOR_TRC_PQ: return MP_CSP_TRC_PQ;
|
|
||||||
case PL_COLOR_TRC_HLG: return MP_CSP_TRC_HLG;
|
|
||||||
case PL_COLOR_TRC_V_LOG: return MP_CSP_TRC_V_LOG;
|
|
||||||
case PL_COLOR_TRC_S_LOG1: return MP_CSP_TRC_S_LOG1;
|
|
||||||
case PL_COLOR_TRC_S_LOG2: return MP_CSP_TRC_S_LOG2;
|
|
||||||
case PL_COLOR_TRC_ST428: return MP_CSP_TRC_ST428;
|
|
||||||
case PL_COLOR_TRC_COUNT: return MP_CSP_TRC_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_ASSERT_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum pl_color_system mp_csp_to_pl(enum mp_csp csp)
|
|
||||||
{
|
|
||||||
switch (csp) {
|
|
||||||
case MP_CSP_AUTO: return PL_COLOR_SYSTEM_UNKNOWN;
|
|
||||||
case MP_CSP_BT_601: return PL_COLOR_SYSTEM_BT_601;
|
|
||||||
case MP_CSP_BT_709: return PL_COLOR_SYSTEM_BT_709;
|
|
||||||
case MP_CSP_SMPTE_240M: return PL_COLOR_SYSTEM_SMPTE_240M;
|
|
||||||
case MP_CSP_BT_2020_NC: return PL_COLOR_SYSTEM_BT_2020_NC;
|
|
||||||
case MP_CSP_BT_2020_C: return PL_COLOR_SYSTEM_BT_2020_C;
|
|
||||||
case MP_CSP_RGB: return PL_COLOR_SYSTEM_RGB;
|
|
||||||
case MP_CSP_XYZ: return PL_COLOR_SYSTEM_XYZ;
|
|
||||||
case MP_CSP_YCGCO: return PL_COLOR_SYSTEM_YCGCO;
|
|
||||||
case MP_CSP_COUNT: return PL_COLOR_SYSTEM_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_ASSERT_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum pl_color_levels mp_levels_to_pl(enum mp_csp_levels levels)
|
|
||||||
{
|
|
||||||
switch (levels) {
|
|
||||||
case MP_CSP_LEVELS_AUTO: return PL_COLOR_LEVELS_UNKNOWN;
|
|
||||||
case MP_CSP_LEVELS_TV: return PL_COLOR_LEVELS_TV;
|
|
||||||
case MP_CSP_LEVELS_PC: return PL_COLOR_LEVELS_PC;
|
|
||||||
case MP_CSP_LEVELS_COUNT: return PL_COLOR_LEVELS_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_ASSERT_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum mp_csp_levels mp_levels_from_pl(enum pl_color_levels levels)
|
|
||||||
{
|
|
||||||
switch (levels){
|
|
||||||
case PL_COLOR_LEVELS_UNKNOWN: return MP_CSP_LEVELS_AUTO;
|
|
||||||
case PL_COLOR_LEVELS_TV: return MP_CSP_LEVELS_TV;
|
|
||||||
case PL_COLOR_LEVELS_PC: return MP_CSP_LEVELS_PC;
|
|
||||||
case PL_COLOR_LEVELS_COUNT: return MP_CSP_LEVELS_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MP_ASSERT_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum pl_alpha_mode mp_alpha_to_pl(enum mp_alpha_type alpha)
|
enum pl_alpha_mode mp_alpha_to_pl(enum mp_alpha_type alpha)
|
||||||
{
|
{
|
||||||
switch (alpha) {
|
switch (alpha) {
|
||||||
|
|
|
@ -27,13 +27,6 @@ static inline struct pl_rect2d mp_rect2d_to_pl(struct mp_rect rc)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
enum pl_color_primaries mp_prim_to_pl(enum mp_csp_prim prim);
|
|
||||||
enum mp_csp_prim mp_prim_from_pl(enum pl_color_primaries prim);
|
|
||||||
enum pl_color_transfer mp_trc_to_pl(enum mp_csp_trc trc);
|
|
||||||
enum mp_csp_trc mp_trc_from_pl(enum pl_color_transfer trc);
|
|
||||||
enum pl_color_system mp_csp_to_pl(enum mp_csp csp);
|
|
||||||
enum pl_color_levels mp_levels_to_pl(enum mp_csp_levels levels);
|
|
||||||
enum mp_csp_levels mp_levels_from_pl(enum pl_color_levels levels);
|
|
||||||
enum pl_alpha_mode mp_alpha_to_pl(enum mp_alpha_type alpha);
|
enum pl_alpha_mode mp_alpha_to_pl(enum mp_alpha_type alpha);
|
||||||
enum pl_chroma_location mp_chroma_to_pl(enum mp_chroma_location chroma);
|
enum pl_chroma_location mp_chroma_to_pl(enum mp_chroma_location chroma);
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ struct priv {
|
||||||
struct mp_csp_equalizer_state *video_eq;
|
struct mp_csp_equalizer_state *video_eq;
|
||||||
struct scaler_params scalers[SCALER_COUNT];
|
struct scaler_params scalers[SCALER_COUNT];
|
||||||
const struct pl_hook **hooks; // storage for `params.hooks`
|
const struct pl_hook **hooks; // storage for `params.hooks`
|
||||||
enum mp_csp_levels output_levels;
|
enum pl_color_levels output_levels;
|
||||||
char **raw_opts;
|
char **raw_opts;
|
||||||
|
|
||||||
struct pl_icc_params icc_params;
|
struct pl_icc_params icc_params;
|
||||||
|
@ -444,8 +444,8 @@ static int plane_data_from_imgfmt(struct pl_plane_data out_data[4],
|
||||||
static struct pl_color_space get_mpi_csp(struct vo *vo, struct mp_image *mpi)
|
static struct pl_color_space get_mpi_csp(struct vo *vo, struct mp_image *mpi)
|
||||||
{
|
{
|
||||||
struct pl_color_space csp = {
|
struct pl_color_space csp = {
|
||||||
.primaries = mp_prim_to_pl(mpi->params.color.primaries),
|
.primaries = mpi->params.color.primaries,
|
||||||
.transfer = mp_trc_to_pl(mpi->params.color.gamma),
|
.transfer = mpi->params.color.transfer,
|
||||||
.hdr = mpi->params.color.hdr,
|
.hdr = mpi->params.color.hdr,
|
||||||
};
|
};
|
||||||
return csp;
|
return csp;
|
||||||
|
@ -573,8 +573,8 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
|
||||||
*frame = (struct pl_frame) {
|
*frame = (struct pl_frame) {
|
||||||
.color = get_mpi_csp(vo, mpi),
|
.color = get_mpi_csp(vo, mpi),
|
||||||
.repr = {
|
.repr = {
|
||||||
.sys = mp_csp_to_pl(par->color.space),
|
.sys = par->repr.sys,
|
||||||
.levels = mp_levels_to_pl(par->color.levels),
|
.levels = par->repr.levels,
|
||||||
.alpha = mp_alpha_to_pl(par->alpha),
|
.alpha = mp_alpha_to_pl(par->alpha),
|
||||||
},
|
},
|
||||||
.profile = {
|
.profile = {
|
||||||
|
@ -588,14 +588,14 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
|
||||||
// mp_image, like AVFrame, likes communicating RGB/XYZ/YCbCr status
|
// mp_image, like AVFrame, likes communicating RGB/XYZ/YCbCr status
|
||||||
// implicitly via the image format, rather than the actual tagging.
|
// implicitly via the image format, rather than the actual tagging.
|
||||||
switch (mp_imgfmt_get_forced_csp(par->imgfmt)) {
|
switch (mp_imgfmt_get_forced_csp(par->imgfmt)) {
|
||||||
case MP_CSP_RGB:
|
case PL_COLOR_SYSTEM_RGB:
|
||||||
frame->repr.sys = PL_COLOR_SYSTEM_RGB;
|
frame->repr.sys = PL_COLOR_SYSTEM_RGB;
|
||||||
frame->repr.levels = PL_COLOR_LEVELS_FULL;
|
frame->repr.levels = PL_COLOR_LEVELS_FULL;
|
||||||
break;
|
break;
|
||||||
case MP_CSP_XYZ:
|
case PL_COLOR_SYSTEM_XYZ:
|
||||||
frame->repr.sys = PL_COLOR_SYSTEM_XYZ;
|
frame->repr.sys = PL_COLOR_SYSTEM_XYZ;
|
||||||
break;
|
break;
|
||||||
case MP_CSP_AUTO:
|
case PL_COLOR_SYSTEM_UNKNOWN:
|
||||||
if (!frame->repr.sys)
|
if (!frame->repr.sys)
|
||||||
frame->repr.sys = pl_color_system_guess_ycbcr(par->w, par->h);
|
frame->repr.sys = pl_color_system_guess_ycbcr(par->w, par->h);
|
||||||
break;
|
break;
|
||||||
|
@ -783,11 +783,11 @@ static void apply_target_options(struct priv *p, struct pl_frame *target)
|
||||||
// Colorspace overrides
|
// Colorspace overrides
|
||||||
const struct gl_video_opts *opts = p->opts_cache->opts;
|
const struct gl_video_opts *opts = p->opts_cache->opts;
|
||||||
if (p->output_levels)
|
if (p->output_levels)
|
||||||
target->repr.levels = mp_levels_to_pl(p->output_levels);
|
target->repr.levels = p->output_levels;
|
||||||
if (opts->target_prim)
|
if (opts->target_prim)
|
||||||
target->color.primaries = mp_prim_to_pl(opts->target_prim);
|
target->color.primaries = opts->target_prim;
|
||||||
if (opts->target_trc)
|
if (opts->target_trc)
|
||||||
target->color.transfer = mp_trc_to_pl(opts->target_trc);
|
target->color.transfer = opts->target_trc;
|
||||||
// If swapchain returned a value use this, override is used in hint
|
// If swapchain returned a value use this, override is used in hint
|
||||||
if (opts->target_peak && !target->color.hdr.max_luma)
|
if (opts->target_peak && !target->color.hdr.max_luma)
|
||||||
target->color.hdr.max_luma = opts->target_peak;
|
target->color.hdr.max_luma = opts->target_peak;
|
||||||
|
@ -796,7 +796,7 @@ static void apply_target_options(struct priv *p, struct pl_frame *target)
|
||||||
if (opts->target_gamut) {
|
if (opts->target_gamut) {
|
||||||
// Ensure resulting gamut still fits inside container
|
// Ensure resulting gamut still fits inside container
|
||||||
const struct pl_raw_primaries *gamut, *container;
|
const struct pl_raw_primaries *gamut, *container;
|
||||||
gamut = pl_raw_primaries_get(mp_prim_to_pl(opts->target_gamut));
|
gamut = pl_raw_primaries_get(opts->target_gamut);
|
||||||
container = pl_raw_primaries_get(target->color.primaries);
|
container = pl_raw_primaries_get(target->color.primaries);
|
||||||
target->color.hdr.prim = pl_primaries_clip(gamut, container);
|
target->color.hdr.prim = pl_primaries_clip(gamut, container);
|
||||||
}
|
}
|
||||||
|
@ -942,9 +942,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
|
||||||
if (p->target_hint && frame->current) {
|
if (p->target_hint && frame->current) {
|
||||||
struct pl_color_space hint = get_mpi_csp(vo, frame->current);
|
struct pl_color_space hint = get_mpi_csp(vo, frame->current);
|
||||||
if (opts->target_prim)
|
if (opts->target_prim)
|
||||||
hint.primaries = mp_prim_to_pl(opts->target_prim);
|
hint.primaries = opts->target_prim;
|
||||||
if (opts->target_trc)
|
if (opts->target_trc)
|
||||||
hint.transfer = mp_trc_to_pl(opts->target_trc);
|
hint.transfer = opts->target_trc;
|
||||||
if (opts->target_peak)
|
if (opts->target_peak)
|
||||||
hint.hdr.max_luma = opts->target_peak;
|
hint.hdr.max_luma = opts->target_peak;
|
||||||
apply_target_contrast(p, &hint);
|
apply_target_contrast(p, &hint);
|
||||||
|
@ -1381,9 +1381,9 @@ static void video_screenshot(struct vo *vo, struct voctrl_screenshot *args)
|
||||||
if (!args->res)
|
if (!args->res)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
args->res->params.color.primaries = mp_prim_from_pl(target.color.primaries);
|
args->res->params.color.primaries = target.color.primaries;
|
||||||
args->res->params.color.gamma = mp_trc_from_pl(target.color.transfer);
|
args->res->params.color.transfer = target.color.transfer;
|
||||||
args->res->params.color.levels = mp_levels_from_pl(target.repr.levels);
|
args->res->params.repr.levels = target.repr.levels;
|
||||||
args->res->params.color.hdr = target.color.hdr;
|
args->res->params.color.hdr = target.color.hdr;
|
||||||
if (args->scaled)
|
if (args->scaled)
|
||||||
args->res->params.p_w = args->res->params.p_h = 1;
|
args->res->params.p_w = args->res->params.p_h = 1;
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <libplacebo/utils/libav.h>
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "options/options.h"
|
#include "options/options.h"
|
||||||
#include "video/fmt-conversion.h"
|
#include "video/fmt-conversion.h"
|
||||||
|
@ -112,8 +114,8 @@ static int reconfig2(struct vo *vo, struct mp_image *img)
|
||||||
encoder->width = width;
|
encoder->width = width;
|
||||||
encoder->height = height;
|
encoder->height = height;
|
||||||
encoder->pix_fmt = pix_fmt;
|
encoder->pix_fmt = pix_fmt;
|
||||||
encoder->colorspace = mp_csp_to_avcol_spc(params->color.space);
|
encoder->colorspace = pl_system_to_av(params->repr.sys);
|
||||||
encoder->color_range = mp_csp_levels_to_avcol_range(params->color.levels);
|
encoder->color_range = pl_levels_to_av(params->repr.levels);
|
||||||
|
|
||||||
AVRational tb;
|
AVRational tb;
|
||||||
|
|
||||||
|
|
|
@ -587,12 +587,12 @@ static int query_format(struct vo *vo, int format)
|
||||||
return format == IMGFMT_MMAL || format == IMGFMT_420P;
|
return format == IMGFMT_MMAL || format == IMGFMT_420P;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MMAL_FOURCC_T map_csp(enum mp_csp csp)
|
static MMAL_FOURCC_T map_csp(enum pl_color_system csp)
|
||||||
{
|
{
|
||||||
switch (csp) {
|
switch (csp) {
|
||||||
case MP_CSP_BT_601: return MMAL_COLOR_SPACE_ITUR_BT601;
|
case PL_COLOR_SYSTEM_BT_601: return MMAL_COLOR_SPACE_ITUR_BT601;
|
||||||
case MP_CSP_BT_709: return MMAL_COLOR_SPACE_ITUR_BT709;
|
case PL_COLOR_SYSTEM_BT_709: return MMAL_COLOR_SPACE_ITUR_BT709;
|
||||||
case MP_CSP_SMPTE_240M: return MMAL_COLOR_SPACE_SMPTE240M;
|
case PL_COLOR_SYSTEM_SMPTE_240M: return MMAL_COLOR_SPACE_SMPTE240M;
|
||||||
default: return MMAL_COLOR_SPACE_UNKNOWN;
|
default: return MMAL_COLOR_SPACE_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,7 +642,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
|
||||||
input->format->es->video.height = MP_ALIGN_UP(params->h, ALIGN_H);
|
input->format->es->video.height = MP_ALIGN_UP(params->h, ALIGN_H);
|
||||||
input->format->es->video.crop = (MMAL_RECT_T){0, 0, params->w, params->h};
|
input->format->es->video.crop = (MMAL_RECT_T){0, 0, params->w, params->h};
|
||||||
input->format->es->video.par = (MMAL_RATIONAL_T){params->p_w, params->p_h};
|
input->format->es->video.par = (MMAL_RATIONAL_T){params->p_w, params->p_h};
|
||||||
input->format->es->video.color_space = map_csp(params->color.space);
|
input->format->es->video.color_space = map_csp(params->repr.sys);
|
||||||
|
|
||||||
if (mmal_port_format_commit(input))
|
if (mmal_port_format_commit(input))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -519,7 +519,7 @@ static bool render_to_screen(struct priv *p, struct mp_image *mpi)
|
||||||
CHECK_VA_STATUS(p, "vaAssociateSubpicture()");
|
CHECK_VA_STATUS(p, "vaAssociateSubpicture()");
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = va_get_colorspace_flag(p->image_params.color.space) |
|
int flags = va_get_colorspace_flag(p->image_params.repr.sys) |
|
||||||
p->scaling | VA_FRAME_PICTURE;
|
p->scaling | VA_FRAME_PICTURE;
|
||||||
status = vaPutSurface(p->display,
|
status = vaPutSurface(p->display,
|
||||||
surface,
|
surface,
|
||||||
|
|
|
@ -401,7 +401,7 @@ static void read_xv_csp(struct vo *vo)
|
||||||
ctx->cached_csp = 0;
|
ctx->cached_csp = 0;
|
||||||
int bt709_enabled;
|
int bt709_enabled;
|
||||||
if (xv_get_eq(vo, ctx->xv_port, "bt_709", &bt709_enabled))
|
if (xv_get_eq(vo, ctx->xv_port, "bt_709", &bt709_enabled))
|
||||||
ctx->cached_csp = bt709_enabled == 100 ? MP_CSP_BT_709 : MP_CSP_BT_601;
|
ctx->cached_csp = bt709_enabled == 100 ? PL_COLOR_SYSTEM_BT_709 : PL_COLOR_SYSTEM_BT_601;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -519,7 +519,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
|
||||||
ctx->current_buf = 0;
|
ctx->current_buf = 0;
|
||||||
ctx->current_ip_buf = 0;
|
ctx->current_ip_buf = 0;
|
||||||
|
|
||||||
int is_709 = params->color.space == MP_CSP_BT_709;
|
int is_709 = params->repr.sys == PL_COLOR_SYSTEM_BT_709;
|
||||||
xv_set_eq(vo, ctx->xv_port, "bt_709", is_709 * 200 - 100);
|
xv_set_eq(vo, ctx->xv_port, "bt_709", is_709 * 200 - 100);
|
||||||
read_xv_csp(vo);
|
read_xv_csp(vo);
|
||||||
|
|
||||||
|
@ -652,7 +652,7 @@ static struct mp_image get_xv_buffer(struct vo *vo, int buf_index)
|
||||||
if (vo->params) {
|
if (vo->params) {
|
||||||
struct mp_image_params params = *vo->params;
|
struct mp_image_params params = *vo->params;
|
||||||
if (ctx->cached_csp)
|
if (ctx->cached_csp)
|
||||||
params.color.space = ctx->cached_csp;
|
params.repr.sys = ctx->cached_csp;
|
||||||
mp_image_set_attributes(&img, ¶ms);
|
mp_image_set_attributes(&img, ¶ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,8 @@ struct mp_repack {
|
||||||
int f32_comp_size;
|
int f32_comp_size;
|
||||||
float f32_m[4], f32_o[4];
|
float f32_m[4], f32_o[4];
|
||||||
uint32_t f32_pmax[4];
|
uint32_t f32_pmax[4];
|
||||||
enum mp_csp f32_csp_space;
|
enum pl_color_system f32_csp_space;
|
||||||
enum mp_csp_levels f32_csp_levels;
|
enum pl_color_levels f32_csp_levels;
|
||||||
|
|
||||||
// REPACK_STEP_REPACK: if true, need to copy this plane
|
// REPACK_STEP_REPACK: if true, need to copy this plane
|
||||||
bool copy_buf[4];
|
bool copy_buf[4];
|
||||||
|
@ -95,7 +95,7 @@ static int find_gbrp_format(int depth, int num_planes)
|
||||||
return 0;
|
return 0;
|
||||||
struct mp_regular_imgfmt desc = {
|
struct mp_regular_imgfmt desc = {
|
||||||
.component_type = MP_COMPONENT_TYPE_UINT,
|
.component_type = MP_COMPONENT_TYPE_UINT,
|
||||||
.forced_csp = MP_CSP_RGB,
|
.forced_csp = PL_COLOR_SYSTEM_RGB,
|
||||||
.component_size = depth > 8 ? 2 : 1,
|
.component_size = depth > 8 ? 2 : 1,
|
||||||
.component_pad = depth - (depth > 8 ? 16 : 8),
|
.component_pad = depth - (depth > 8 ? 16 : 8),
|
||||||
.num_planes = num_planes,
|
.num_planes = num_planes,
|
||||||
|
@ -467,7 +467,7 @@ static void setup_fringe_rgb_packer(struct mp_repack *rp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (desc.bpp[0] > 16 || (desc.bpp[0] % 8u) ||
|
if (desc.bpp[0] > 16 || (desc.bpp[0] % 8u) ||
|
||||||
mp_imgfmt_get_forced_csp(rp->imgfmt_a) != MP_CSP_RGB ||
|
mp_imgfmt_get_forced_csp(rp->imgfmt_a) != PL_COLOR_SYSTEM_RGB ||
|
||||||
desc.num_planes != 1 || desc.comps[3].size)
|
desc.num_planes != 1 || desc.comps[3].size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -845,8 +845,8 @@ static void update_repack_float(struct mp_repack *rp)
|
||||||
// Image in input format.
|
// Image in input format.
|
||||||
struct mp_image *ui = rp->pack ? rp->steps[rp->num_steps - 1].buf[1]
|
struct mp_image *ui = rp->pack ? rp->steps[rp->num_steps - 1].buf[1]
|
||||||
: rp->steps[0].buf[0];
|
: rp->steps[0].buf[0];
|
||||||
enum mp_csp csp = ui->params.color.space;
|
enum pl_color_system csp = ui->params.repr.sys;
|
||||||
enum mp_csp_levels levels = ui->params.color.levels;
|
enum pl_color_levels levels = ui->params.repr.levels;
|
||||||
if (rp->f32_csp_space == csp && rp->f32_csp_levels == levels)
|
if (rp->f32_csp_space == csp && rp->f32_csp_levels == levels)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -989,8 +989,8 @@ static bool setup_format_ne(struct mp_repack *rp)
|
||||||
(desc.component_size != 1 && desc.component_size != 2))
|
(desc.component_size != 1 && desc.component_size != 2))
|
||||||
return false;
|
return false;
|
||||||
rp->f32_comp_size = desc.component_size;
|
rp->f32_comp_size = desc.component_size;
|
||||||
rp->f32_csp_space = MP_CSP_COUNT;
|
rp->f32_csp_space = PL_COLOR_SYSTEM_COUNT;
|
||||||
rp->f32_csp_levels = MP_CSP_LEVELS_COUNT;
|
rp->f32_csp_levels = PL_COLOR_LEVELS_COUNT;
|
||||||
rp->steps[rp->num_steps++] = (struct repack_step) {
|
rp->steps[rp->num_steps++] = (struct repack_step) {
|
||||||
.type = REPACK_STEP_FLOAT,
|
.type = REPACK_STEP_FLOAT,
|
||||||
.fmt = {
|
.fmt = {
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 37, 100)
|
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 37, 100)
|
||||||
#include <libavutil/pixdesc.h>
|
#include <libavutil/pixdesc.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <libplacebo/utils/libav.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -156,11 +157,11 @@ bool mp_sws_supports_formats(struct mp_sws_context *ctx,
|
||||||
sws_isSupportedOutput(imgfmt2pixfmt(imgfmt_out));
|
sws_isSupportedOutput(imgfmt2pixfmt(imgfmt_out));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mp_csp_to_sws_colorspace(enum mp_csp csp)
|
static int pl_csp_to_sws_colorspace(enum pl_color_system csp)
|
||||||
{
|
{
|
||||||
// The SWS_CS_* macros are just convenience redefinitions of the
|
// The SWS_CS_* macros are just convenience redefinitions of the
|
||||||
// AVCOL_SPC_* macros, inside swscale.h.
|
// AVCOL_SPC_* macros, inside swscale.h.
|
||||||
return mp_csp_to_avcol_spc(csp);
|
return pl_system_to_av(csp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cache_valid(struct mp_sws_context *ctx)
|
static bool cache_valid(struct mp_sws_context *ctx)
|
||||||
|
@ -289,11 +290,11 @@ int mp_sws_reinit(struct mp_sws_context *ctx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int s_csp = mp_csp_to_sws_colorspace(src.color.space);
|
int s_csp = pl_csp_to_sws_colorspace(src.repr.sys);
|
||||||
int s_range = src.color.levels == MP_CSP_LEVELS_PC;
|
int s_range = src.repr.levels == PL_COLOR_LEVELS_FULL;
|
||||||
|
|
||||||
int d_csp = mp_csp_to_sws_colorspace(dst.color.space);
|
int d_csp = pl_csp_to_sws_colorspace(src.repr.sys);
|
||||||
int d_range = dst.color.levels == MP_CSP_LEVELS_PC;
|
int d_range = dst.repr.levels == PL_COLOR_LEVELS_FULL;
|
||||||
|
|
||||||
av_opt_set_int(ctx->sws, "sws_flags", ctx->flags, 0);
|
av_opt_set_int(ctx->sws, "sws_flags", ctx->flags, 0);
|
||||||
|
|
||||||
|
@ -407,11 +408,11 @@ int mp_sws_scale(struct mp_sws_context *ctx, struct mp_image *dst,
|
||||||
return mp_zimg_convert(ctx->zimg, dst, src) ? 0 : -1;
|
return mp_zimg_convert(ctx->zimg, dst, src) ? 0 : -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (src->params.color.space == MP_CSP_XYZ && dst->params.color.space != MP_CSP_XYZ) {
|
if (src->params.repr.sys == PL_COLOR_SYSTEM_XYZ && dst->params.repr.sys != PL_COLOR_SYSTEM_XYZ) {
|
||||||
// swsscale has hardcoded gamma 2.2 internally and 2.6 for XYZ
|
// swsscale has hardcoded gamma 2.2 internally and 2.6 for XYZ
|
||||||
dst->params.color.gamma = MP_CSP_TRC_GAMMA22;
|
dst->params.color.transfer = PL_COLOR_TRC_GAMMA22;
|
||||||
// and sRGB primaries...
|
// and sRGB primaries...
|
||||||
dst->params.color.primaries = MP_CSP_PRIM_BT_709;
|
dst->params.color.primaries = PL_COLOR_PRIM_BT_709;
|
||||||
// it doesn't adjust white point though, but it is not worth to support
|
// it doesn't adjust white point though, but it is not worth to support
|
||||||
// this case. It would require custom prim with equal energy white point
|
// this case. It would require custom prim with equal energy white point
|
||||||
// and sRGB primaries.
|
// and sRGB primaries.
|
||||||
|
|
|
@ -69,12 +69,12 @@ const struct m_sub_options vaapi_conf = {
|
||||||
.size = sizeof(struct vaapi_opts),
|
.size = sizeof(struct vaapi_opts),
|
||||||
};
|
};
|
||||||
|
|
||||||
int va_get_colorspace_flag(enum mp_csp csp)
|
int va_get_colorspace_flag(enum pl_color_system csp)
|
||||||
{
|
{
|
||||||
switch (csp) {
|
switch (csp) {
|
||||||
case MP_CSP_BT_601: return VA_SRC_BT601;
|
case PL_COLOR_SYSTEM_BT_601: return VA_SRC_BT601;
|
||||||
case MP_CSP_BT_709: return VA_SRC_BT709;
|
case PL_COLOR_SYSTEM_BT_709: return VA_SRC_BT709;
|
||||||
case MP_CSP_SMPTE_240M: return VA_SRC_SMPTE_240;
|
case PL_COLOR_SYSTEM_SMPTE_240M: return VA_SRC_SMPTE_240;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ struct mp_vaapi_ctx {
|
||||||
#define CHECK_VA_STATUS(ctx, msg) \
|
#define CHECK_VA_STATUS(ctx, msg) \
|
||||||
CHECK_VA_STATUS_LEVEL(ctx, msg, MSGL_ERR)
|
CHECK_VA_STATUS_LEVEL(ctx, msg, MSGL_ERR)
|
||||||
|
|
||||||
int va_get_colorspace_flag(enum mp_csp csp);
|
int va_get_colorspace_flag(enum pl_color_system csp);
|
||||||
|
|
||||||
struct mp_vaapi_ctx * va_initialize(VADisplay *display, struct mp_log *plog, bool probing);
|
struct mp_vaapi_ctx * va_initialize(VADisplay *display, struct mp_log *plog, bool probing);
|
||||||
void va_destroy(struct mp_vaapi_ctx *ctx);
|
void va_destroy(struct mp_vaapi_ctx *ctx);
|
||||||
|
|
102
video/zimg.c
102
video/zimg.c
|
@ -131,66 +131,66 @@ static zimg_chroma_location_e mp_to_z_chroma(enum mp_chroma_location cl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static zimg_matrix_coefficients_e mp_to_z_matrix(enum mp_csp csp)
|
static zimg_matrix_coefficients_e pl_to_z_matrix(enum pl_color_system csp)
|
||||||
{
|
{
|
||||||
switch (csp) {
|
switch (csp) {
|
||||||
case MP_CSP_BT_601: return ZIMG_MATRIX_BT470_BG;
|
case PL_COLOR_SYSTEM_BT_601: return ZIMG_MATRIX_BT470_BG;
|
||||||
case MP_CSP_BT_709: return ZIMG_MATRIX_BT709;
|
case PL_COLOR_SYSTEM_BT_709: return ZIMG_MATRIX_BT709;
|
||||||
case MP_CSP_SMPTE_240M: return ZIMG_MATRIX_ST240_M;
|
case PL_COLOR_SYSTEM_SMPTE_240M: return ZIMG_MATRIX_ST240_M;
|
||||||
case MP_CSP_BT_2020_NC: return ZIMG_MATRIX_BT2020_NCL;
|
case PL_COLOR_SYSTEM_BT_2020_NC: return ZIMG_MATRIX_BT2020_NCL;
|
||||||
case MP_CSP_BT_2020_C: return ZIMG_MATRIX_BT2020_CL;
|
case PL_COLOR_SYSTEM_BT_2020_C: return ZIMG_MATRIX_BT2020_CL;
|
||||||
case MP_CSP_RGB: return ZIMG_MATRIX_RGB;
|
case PL_COLOR_SYSTEM_RGB: return ZIMG_MATRIX_RGB;
|
||||||
case MP_CSP_XYZ: return ZIMG_MATRIX_RGB;
|
case PL_COLOR_SYSTEM_XYZ: return ZIMG_MATRIX_RGB;
|
||||||
case MP_CSP_YCGCO: return ZIMG_MATRIX_YCGCO;
|
case PL_COLOR_SYSTEM_YCGCO: return ZIMG_MATRIX_YCGCO;
|
||||||
default: return ZIMG_MATRIX_BT709;
|
default: return ZIMG_MATRIX_BT709;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static zimg_transfer_characteristics_e mp_to_z_trc(enum mp_csp_trc trc)
|
static zimg_transfer_characteristics_e pl_to_z_trc(enum pl_color_transfer trc)
|
||||||
{
|
{
|
||||||
switch (trc) {
|
switch (trc) {
|
||||||
case MP_CSP_TRC_BT_1886: return ZIMG_TRANSFER_BT709;
|
case PL_COLOR_TRC_BT_1886: return ZIMG_TRANSFER_BT709;
|
||||||
case MP_CSP_TRC_SRGB: return ZIMG_TRANSFER_IEC_61966_2_1;
|
case PL_COLOR_TRC_SRGB: return ZIMG_TRANSFER_IEC_61966_2_1;
|
||||||
case MP_CSP_TRC_LINEAR: return ZIMG_TRANSFER_LINEAR;
|
case PL_COLOR_TRC_LINEAR: return ZIMG_TRANSFER_LINEAR;
|
||||||
case MP_CSP_TRC_GAMMA22: return ZIMG_TRANSFER_BT470_M;
|
case PL_COLOR_TRC_GAMMA22: return ZIMG_TRANSFER_BT470_M;
|
||||||
case MP_CSP_TRC_GAMMA28: return ZIMG_TRANSFER_BT470_BG;
|
case PL_COLOR_TRC_GAMMA28: return ZIMG_TRANSFER_BT470_BG;
|
||||||
case MP_CSP_TRC_PQ: return ZIMG_TRANSFER_ST2084;
|
case PL_COLOR_TRC_PQ: return ZIMG_TRANSFER_ST2084;
|
||||||
case MP_CSP_TRC_HLG: return ZIMG_TRANSFER_ARIB_B67;
|
case PL_COLOR_TRC_HLG: return ZIMG_TRANSFER_ARIB_B67;
|
||||||
#if HAVE_ZIMG_ST428
|
#if HAVE_ZIMG_ST428
|
||||||
case MP_CSP_TRC_ST428: return ZIMG_TRANSFER_ST428;
|
case PL_COLOR_TRC_ST428: return ZIMG_TRANSFER_ST428;
|
||||||
#endif
|
#endif
|
||||||
case MP_CSP_TRC_GAMMA18: // ?
|
case PL_COLOR_TRC_GAMMA18: // ?
|
||||||
case MP_CSP_TRC_GAMMA20:
|
case PL_COLOR_TRC_GAMMA20:
|
||||||
case MP_CSP_TRC_GAMMA24:
|
case PL_COLOR_TRC_GAMMA24:
|
||||||
case MP_CSP_TRC_GAMMA26:
|
case PL_COLOR_TRC_GAMMA26:
|
||||||
case MP_CSP_TRC_PRO_PHOTO:
|
case PL_COLOR_TRC_PRO_PHOTO:
|
||||||
case MP_CSP_TRC_V_LOG:
|
case PL_COLOR_TRC_V_LOG:
|
||||||
case MP_CSP_TRC_S_LOG1:
|
case PL_COLOR_TRC_S_LOG1:
|
||||||
case MP_CSP_TRC_S_LOG2: // ?
|
case PL_COLOR_TRC_S_LOG2: // ?
|
||||||
default: return ZIMG_TRANSFER_BT709;
|
default: return ZIMG_TRANSFER_BT709;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static zimg_color_primaries_e mp_to_z_prim(enum mp_csp_prim prim)
|
static zimg_color_primaries_e mp_to_z_prim(enum pl_color_primaries prim)
|
||||||
{
|
{
|
||||||
switch (prim) {
|
switch (prim) {
|
||||||
case MP_CSP_PRIM_BT_601_525:return ZIMG_PRIMARIES_ST170_M;
|
case PL_COLOR_PRIM_BT_601_525:return ZIMG_PRIMARIES_ST170_M;
|
||||||
case MP_CSP_PRIM_BT_601_625:return ZIMG_PRIMARIES_BT470_BG;
|
case PL_COLOR_PRIM_BT_601_625:return ZIMG_PRIMARIES_BT470_BG;
|
||||||
case MP_CSP_PRIM_BT_709: return ZIMG_PRIMARIES_BT709;
|
case PL_COLOR_PRIM_BT_709: return ZIMG_PRIMARIES_BT709;
|
||||||
case MP_CSP_PRIM_BT_2020: return ZIMG_PRIMARIES_BT2020;
|
case PL_COLOR_PRIM_BT_2020: return ZIMG_PRIMARIES_BT2020;
|
||||||
case MP_CSP_PRIM_BT_470M: return ZIMG_PRIMARIES_BT470_M;
|
case PL_COLOR_PRIM_BT_470M: return ZIMG_PRIMARIES_BT470_M;
|
||||||
case MP_CSP_PRIM_DCI_P3: return ZIMG_PRIMARIES_ST431_2;
|
case PL_COLOR_PRIM_DCI_P3: return ZIMG_PRIMARIES_ST431_2;
|
||||||
case MP_CSP_PRIM_DISPLAY_P3:return ZIMG_PRIMARIES_ST432_1;
|
case PL_COLOR_PRIM_DISPLAY_P3:return ZIMG_PRIMARIES_ST432_1;
|
||||||
case MP_CSP_PRIM_EBU_3213: return ZIMG_PRIMARIES_EBU3213_E;
|
case PL_COLOR_PRIM_EBU_3213: return ZIMG_PRIMARIES_EBU3213_E;
|
||||||
case MP_CSP_PRIM_FILM_C: return ZIMG_PRIMARIES_FILM;
|
case PL_COLOR_PRIM_FILM_C: return ZIMG_PRIMARIES_FILM;
|
||||||
case MP_CSP_PRIM_CIE_1931:
|
case PL_COLOR_PRIM_CIE_1931:
|
||||||
case MP_CSP_PRIM_APPLE: // ?
|
case PL_COLOR_PRIM_APPLE: // ?
|
||||||
case MP_CSP_PRIM_ADOBE:
|
case PL_COLOR_PRIM_ADOBE:
|
||||||
case MP_CSP_PRIM_PRO_PHOTO:
|
case PL_COLOR_PRIM_PRO_PHOTO:
|
||||||
case MP_CSP_PRIM_V_GAMUT:
|
case PL_COLOR_PRIM_V_GAMUT:
|
||||||
case MP_CSP_PRIM_S_GAMUT: // ?
|
case PL_COLOR_PRIM_S_GAMUT: // ?
|
||||||
case MP_CSP_PRIM_ACES_AP0:
|
case PL_COLOR_PRIM_ACES_AP0:
|
||||||
case MP_CSP_PRIM_ACES_AP1:
|
case PL_COLOR_PRIM_ACES_AP1:
|
||||||
default: return ZIMG_PRIMARIES_BT709;
|
default: return ZIMG_PRIMARIES_BT709;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,7 +414,7 @@ static bool setup_format(zimg_image_format *zfmt, struct mp_zimg_repack *r,
|
||||||
zfmt->color_family = ZIMG_COLOR_YUV;
|
zfmt->color_family = ZIMG_COLOR_YUV;
|
||||||
if (desc.num_planes <= 2) {
|
if (desc.num_planes <= 2) {
|
||||||
zfmt->color_family = ZIMG_COLOR_GREY;
|
zfmt->color_family = ZIMG_COLOR_GREY;
|
||||||
} else if (fmt.color.space == MP_CSP_RGB || fmt.color.space == MP_CSP_XYZ) {
|
} else if (fmt.repr.sys == PL_COLOR_SYSTEM_RGB || fmt.repr.sys == PL_COLOR_SYSTEM_XYZ) {
|
||||||
zfmt->color_family = ZIMG_COLOR_RGB;
|
zfmt->color_family = ZIMG_COLOR_RGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,13 +441,13 @@ static bool setup_format(zimg_image_format *zfmt, struct mp_zimg_repack *r,
|
||||||
// (Formats like P010 are basically reported as P016.)
|
// (Formats like P010 are basically reported as P016.)
|
||||||
zfmt->depth = desc.component_size * 8 + MPMIN(0, desc.component_pad);
|
zfmt->depth = desc.component_size * 8 + MPMIN(0, desc.component_pad);
|
||||||
|
|
||||||
zfmt->pixel_range = fmt.color.levels == MP_CSP_LEVELS_PC ?
|
zfmt->pixel_range = fmt.repr.levels == PL_COLOR_LEVELS_FULL ?
|
||||||
ZIMG_RANGE_FULL : ZIMG_RANGE_LIMITED;
|
ZIMG_RANGE_FULL : ZIMG_RANGE_LIMITED;
|
||||||
|
|
||||||
zfmt->matrix_coefficients = mp_to_z_matrix(fmt.color.space);
|
zfmt->matrix_coefficients = pl_to_z_matrix(fmt.repr.sys);
|
||||||
zfmt->transfer_characteristics = mp_to_z_trc(fmt.color.gamma);
|
zfmt->transfer_characteristics = pl_to_z_trc(fmt.color.transfer);
|
||||||
// For MP_CSP_XYZ only valid primaries are defined in ST 428-1
|
// For PL_COLOR_SYSTEM_XYZ only valid primaries are defined in ST 428-1
|
||||||
zfmt->color_primaries = fmt.color.space == MP_CSP_XYZ
|
zfmt->color_primaries = fmt.repr.sys == PL_COLOR_SYSTEM_XYZ
|
||||||
? ZIMG_PRIMARIES_ST428
|
? ZIMG_PRIMARIES_ST428
|
||||||
: mp_to_z_prim(fmt.color.primaries);
|
: mp_to_z_prim(fmt.color.primaries);
|
||||||
zfmt->chroma_location = mp_to_z_chroma(fmt.chroma_location);
|
zfmt->chroma_location = mp_to_z_chroma(fmt.chroma_location);
|
||||||
|
@ -548,7 +548,7 @@ static bool mp_zimg_state_init(struct mp_zimg_context *ctx,
|
||||||
params.allow_approximate_gamma = 1;
|
params.allow_approximate_gamma = 1;
|
||||||
|
|
||||||
// leave at default for SDR, which means 100 cd/m^2 for zimg
|
// leave at default for SDR, which means 100 cd/m^2 for zimg
|
||||||
if (ctx->dst.color.hdr.max_luma > 0 && mp_trc_is_hdr(ctx->dst.color.gamma))
|
if (ctx->dst.color.hdr.max_luma > 0 && mp_trc_is_hdr(ctx->dst.color.transfer))
|
||||||
params.nominal_peak_luminance = ctx->dst.color.hdr.max_luma;
|
params.nominal_peak_luminance = ctx->dst.color.hdr.max_luma;
|
||||||
|
|
||||||
st->graph = zimg_filter_graph_build(&src_fmt, &dst_fmt, ¶ms);
|
st->graph = zimg_filter_graph_build(&src_fmt, &dst_fmt, ¶ms);
|
||||||
|
|
Loading…
Reference in New Issue