From 2332445d8d78d569015cabbacb3d9cf5552e5c73 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Mon, 3 Jan 2022 04:07:52 +0100 Subject: vo_gpu_next: use new HDR metadata options Properly forward the HDR metadata from the mpi to the equivalent (new) fields in pl_color_space. Used by the new tone mapping code. --- video/out/placebo/utils.c | 14 ------ video/out/placebo/utils.h | 1 - video/out/vo_gpu_next.c | 114 +++++++++++++++++++++------------------------- 3 files changed, 52 insertions(+), 77 deletions(-) (limited to 'video/out') diff --git a/video/out/placebo/utils.c b/video/out/placebo/utils.c index da16b65745..35cca963c4 100644 --- a/video/out/placebo/utils.c +++ b/video/out/placebo/utils.c @@ -107,20 +107,6 @@ enum pl_color_transfer mp_trc_to_pl(enum mp_csp_trc trc) MP_ASSERT_UNREACHABLE(); } -enum pl_color_light mp_light_to_pl(enum mp_csp_light light) -{ - switch (light) { - case MP_CSP_LIGHT_AUTO: return PL_COLOR_LIGHT_UNKNOWN; - case MP_CSP_LIGHT_DISPLAY: return PL_COLOR_LIGHT_DISPLAY; - case MP_CSP_LIGHT_SCENE_HLG: return PL_COLOR_LIGHT_SCENE_HLG; - case MP_CSP_LIGHT_SCENE_709_1886: return PL_COLOR_LIGHT_SCENE_709_1886; - case MP_CSP_LIGHT_SCENE_1_2: return PL_COLOR_LIGHT_SCENE_1_2; - case MP_CSP_LIGHT_COUNT: return PL_COLOR_LIGHT_COUNT; - } - - MP_ASSERT_UNREACHABLE(); -} - enum pl_color_system mp_csp_to_pl(enum mp_csp csp) { switch (csp) { diff --git a/video/out/placebo/utils.h b/video/out/placebo/utils.h index a28a3a6793..258f25086e 100644 --- a/video/out/placebo/utils.h +++ b/video/out/placebo/utils.h @@ -22,7 +22,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 pl_color_transfer mp_trc_to_pl(enum mp_csp_trc trc); -enum pl_color_light mp_light_to_pl(enum mp_csp_light light); 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 pl_alpha_mode mp_alpha_to_pl(enum mp_alpha_type alpha); diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 16ce51279a..14e2fdeadc 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -392,6 +392,49 @@ static int plane_data_from_imgfmt(struct pl_plane_data out_data[4], return desc.num_planes; } +static struct pl_color_space get_mpi_csp(struct vo *vo, struct mp_image *mpi) +{ + struct pl_color_space csp = { + .primaries = mp_prim_to_pl(mpi->params.color.primaries), + .transfer = mp_trc_to_pl(mpi->params.color.gamma), + .hdr.max_luma = mpi->params.color.sig_peak * MP_REF_WHITE, + }; + + for (int i = 0; i < mpi->num_ff_side_data; i++) { + void *data = mpi->ff_side_data[i].buf->data; + switch (mpi->ff_side_data[i].type) { + case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: { + const AVContentLightMetadata *clm = data; + csp.hdr.max_cll = clm->MaxCLL; + csp.hdr.max_fall = clm->MaxFALL; + break; + } + case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: { + const AVMasteringDisplayMetadata *mdm = data; + if (mdm->has_luminance) { + csp.hdr.min_luma = av_q2d(mdm->min_luminance); + csp.hdr.max_luma = av_q2d(mdm->max_luminance); + } + + if (mdm->has_primaries) { + csp.hdr.prim.red.x = av_q2d(mdm->display_primaries[0][0]); + csp.hdr.prim.red.y = av_q2d(mdm->display_primaries[0][1]); + csp.hdr.prim.green.x = av_q2d(mdm->display_primaries[1][0]); + csp.hdr.prim.green.y = av_q2d(mdm->display_primaries[1][1]); + csp.hdr.prim.blue.x = av_q2d(mdm->display_primaries[2][0]); + csp.hdr.prim.blue.y = av_q2d(mdm->display_primaries[2][1]); + csp.hdr.prim.white.x = av_q2d(mdm->white_point[0]); + csp.hdr.prim.white.y = av_q2d(mdm->white_point[1]); + } + break; + } + default: break; + } + } + + return csp; +} + static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src, struct pl_frame *frame) { @@ -405,12 +448,7 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src // TODO: implement support for hwdec wrappers *frame = (struct pl_frame) { .num_planes = mpi->num_planes, - .color = { - .primaries = mp_prim_to_pl(par->color.primaries), - .transfer = mp_trc_to_pl(par->color.gamma), - .light = mp_light_to_pl(par->color.light), - .sig_peak = par->color.sig_peak, - }, + .color = get_mpi_csp(vo, mpi), .repr = { .sys = mp_csp_to_pl(par->color.space), .levels = mp_levels_to_pl(par->color.levels), @@ -511,57 +549,6 @@ static void discard_frame(const struct pl_source_frame *src) talloc_free(mpi); } -static struct pl_swapchain_colors get_csp_hint(struct vo *vo, struct mp_image *mpi) -{ - struct priv *p = vo->priv; - const struct gl_video_opts *opts = p->opts_cache->opts; - - struct pl_swapchain_colors hint = { - .primaries = mp_prim_to_pl(mpi->params.color.primaries), - .transfer = mp_trc_to_pl(mpi->params.color.gamma), - }; - - // Respect target color space overrides - if (opts->target_prim) - hint.primaries = mp_prim_to_pl(opts->target_prim); - if (opts->target_trc) - hint.transfer = mp_prim_to_pl(opts->target_trc); - - for (int i = 0; i < mpi->num_ff_side_data; i++) { - void *data = mpi->ff_side_data[i].buf->data; - switch (mpi->ff_side_data[i].type) { - case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: { - const AVContentLightMetadata *clm = data; - hint.hdr.max_cll = clm->MaxCLL; - hint.hdr.max_fall = clm->MaxFALL; - break; - } - case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: { - const AVMasteringDisplayMetadata *mdm = data; - if (mdm->has_luminance) { - hint.hdr.min_luma = av_q2d(mdm->min_luminance); - hint.hdr.max_luma = av_q2d(mdm->max_luminance); - } - - if (mdm->has_primaries) { - hint.hdr.prim.red.x = av_q2d(mdm->display_primaries[0][0]); - hint.hdr.prim.red.y = av_q2d(mdm->display_primaries[0][1]); - hint.hdr.prim.green.x = av_q2d(mdm->display_primaries[1][0]); - hint.hdr.prim.green.y = av_q2d(mdm->display_primaries[1][1]); - hint.hdr.prim.blue.x = av_q2d(mdm->display_primaries[2][0]); - hint.hdr.prim.blue.y = av_q2d(mdm->display_primaries[2][1]); - hint.hdr.prim.white.x = av_q2d(mdm->white_point[0]); - hint.hdr.prim.white.y = av_q2d(mdm->white_point[1]); - } - break; - } - default: break; - } - } - - return hint; -} - static void info_callback(void *priv, const struct pl_render_info *info) { struct vo *vo = priv; @@ -635,7 +622,7 @@ static void apply_target_options(struct priv *p, struct pl_frame *target) if (opts->target_trc) target->color.transfer = mp_trc_to_pl(opts->target_trc); if (opts->target_peak) - target->color.sig_peak = opts->target_peak / PL_COLOR_SDR_WHITE; + target->color.hdr.max_luma = opts->target_peak; if (opts->dither_depth > 0) { struct pl_bit_encoding *tbits = &target->repr.bits; tbits->color_depth += opts->dither_depth - tbits->sample_depth; @@ -703,18 +690,21 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) p->last_id = id; } + const struct gl_video_opts *opts = p->opts_cache->opts; if (p->target_hint && frame->current) { - struct pl_swapchain_colors hint = get_csp_hint(vo, frame->current); + struct pl_color_space hint = get_mpi_csp(vo, frame->current); + if (opts->target_prim) + hint.primaries = mp_prim_to_pl(opts->target_prim); + if (opts->target_trc) + hint.transfer = mp_prim_to_pl(opts->target_trc); pl_swapchain_colorspace_hint(p->sw, &hint); } else if (!p->target_hint) { pl_swapchain_colorspace_hint(p->sw, NULL); } - const struct gl_video_opts *opts = p->opts_cache->opts; - double vsync_offset = opts->interpolation ? frame->vsync_offset : 0; - struct pl_swapchain_frame swframe; struct ra_swapchain *sw = p->ra_ctx->swapchain; + double vsync_offset = opts->interpolation ? frame->vsync_offset : 0; bool should_draw = sw->fns->start_frame(sw, NULL); // for wayland logic if (!should_draw || !pl_swapchain_start_frame(p->sw, &swframe)) { // Advance the queue state to the current PTS to discard unused frames -- cgit v1.2.3