From 3cf71fd7c7f5d4052b67ebdf11ff416a9beffbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 29 Aug 2023 10:21:35 +0200 Subject: [PATCH] command: add hdr-metadata property --- DOCS/interface-changes.rst | 1 + DOCS/man/input.rst | 48 ++++++++++++++++++++++++++++++++++++++ player/command.c | 35 +++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index d5d350ee86..db590e2a6f 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -51,6 +51,7 @@ Interface changes - remove `auto-forced-only` property - rename `--sub-forced-only` to `--sub-forced-events-only` - remove `sub-forced-only-cur` property (`--sub-forced-events-only` is a replacement) + - add `hdr-metadata` property --- mpv 0.36.0 --- - add `--target-contrast` - Target luminance value is now also applied when ICC profile is used. diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index d909066ace..a70318e449 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -2480,6 +2480,54 @@ Property list "average-bpp" MPV_FORMAT_INT64 "alpha" MPV_FORMAT_STRING +``hdr-metadata`` + Video HDR metadata per frame, including peak detection result. + This has a number of sub-properties: + + ``hdr-metadata/min-luma`` + Minimum luminance, as reported by HDR10 metadata (in cd/m²) + + ``hdr-metadata/max-luma`` + Maximum luminance, as reported by HDR10 metadata (in cd/m²) + + ``hdr-metadata/max-cll`` + Maximum content light level, as reported by HDR10 metadata (in cd/m²) + + ``hdr-metadata/max-fall`` + Maximum frame average light level, as reported by HDR10 metadata (in cd/m²) + + ``hdr-metadata/scene-max-r`` + MaxRGB of a scene for R component, as reported by HDR10+ metadata (in cd/m²) + + ``hdr-metadata/scene-max-g`` + MaxRGB of a scene for G component, as reported by HDR10+ metadata (in cd/m²) + + ``hdr-metadata/scene-max-b`` + MaxRGB of a scene for B component, as reported by HDR10+ metadata (in cd/m²) + + ``hdr-metadata/max-pq-y`` + Maximum PQ luminance of a frame, as reported by peak detection (in PQ, 0-1) + + ``hdr-metadata/avg-pq-y`` + Average PQ luminance of a frame, as reported by peak detection (in PQ, 0-1) + + When querying the property with the client API using ``MPV_FORMAT_NODE``, + or with Lua ``mp.get_property_native``, this will return a mpv_node with + the following contents: + + :: + + MPV_FORMAT_NODE_MAP + "min-luma" MPV_FORMAT_DOUBLE + "max-luma" MPV_FORMAT_DOUBLE + "max-cll" MPV_FORMAT_DOUBLE + "max-fall" MPV_FORMAT_DOUBLE + "scene-max-r" MPV_FORMAT_DOUBLE + "scene-max-g" MPV_FORMAT_DOUBLE + "scene-max-b" MPV_FORMAT_DOUBLE + "max-pq-y" MPV_FORMAT_DOUBLE + "avg-pq-y" MPV_FORMAT_DOUBLE + ``dwidth``, ``dheight`` Video display size. This is the video size after filters and aspect scaling have been applied. The actual video window size can still be different diff --git a/player/command.c b/player/command.c index 200696b7af..008bc593a2 100644 --- a/player/command.c +++ b/player/command.c @@ -2664,6 +2664,40 @@ out: return ret; } +static int mp_property_hdr_metadata(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + if (!mpctx->video_out) + return M_PROPERTY_UNAVAILABLE; + + struct mp_hdr_metadata data; + if (vo_control(mpctx->video_out, VOCTRL_HDR_METADATA, &data) != VO_TRUE) + return M_PROPERTY_UNAVAILABLE; + + bool has_hdr10 = data.max_luma; + bool has_hdr10plus = data.scene_avg && (data.scene_max[0] || + data.scene_max[1] || + data.scene_max[2]); + bool has_cie_y = data.max_pq_y && data.avg_pq_y; + + struct m_sub_property props[] = { + {"min-luma", SUB_PROP_FLOAT(data.min_luma), .unavailable = !has_hdr10}, + {"max-luma", SUB_PROP_FLOAT(data.max_luma), .unavailable = !has_hdr10}, + {"max-cll", SUB_PROP_FLOAT(data.max_cll), .unavailable = !has_hdr10}, + {"max-fall", SUB_PROP_FLOAT(data.max_fall), .unavailable = !has_hdr10}, + {"scene-max-r", SUB_PROP_FLOAT(data.scene_max[0]), .unavailable = !has_hdr10plus}, + {"scene-max-g", SUB_PROP_FLOAT(data.scene_max[1]), .unavailable = !has_hdr10plus}, + {"scene-max-b", SUB_PROP_FLOAT(data.scene_max[2]), .unavailable = !has_hdr10plus}, + {"scene-avg", SUB_PROP_FLOAT(data.scene_avg), .unavailable = !has_hdr10plus}, + {"max-pq-y", SUB_PROP_FLOAT(data.max_pq_y), .unavailable = !has_cie_y}, + {"avg-pq-y", SUB_PROP_FLOAT(data.avg_pq_y), .unavailable = !has_cie_y}, + {0} + }; + + return m_property_read_sub(props, action, arg); +} + static int mp_property_perf_info(void *ctx, struct m_property *p, int action, void *arg) { @@ -3934,6 +3968,7 @@ static const struct m_property mp_properties_base[] = { {"current-window-scale", mp_property_current_window_scale}, {"vo-configured", mp_property_vo_configured}, {"vo-passes", mp_property_vo_passes}, + {"hdr-metadata", mp_property_hdr_metadata}, {"perf-info", mp_property_perf_info}, {"current-vo", mp_property_vo}, {"container-fps", mp_property_fps},