summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2022-01-03 04:07:52 +0100
committerNiklas Haas <github-daiK1o@haasn.dev>2022-01-07 06:28:14 +0100
commit2332445d8d78d569015cabbacb3d9cf5552e5c73 (patch)
treef346ca0723ec2d14567ba4452395635278f09571 /video/out
parenta9cb2e2821adb40e7548e8233390e79706104041 (diff)
downloadmpv-2332445d8d78d569015cabbacb3d9cf5552e5c73.tar.bz2
mpv-2332445d8d78d569015cabbacb3d9cf5552e5c73.tar.xz
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.
Diffstat (limited to 'video/out')
-rw-r--r--video/out/placebo/utils.c14
-rw-r--r--video/out/placebo/utils.h1
-rw-r--r--video/out/vo_gpu_next.c114
3 files changed, 52 insertions, 77 deletions
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