diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index d49e61a340..b3c5a05c58 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -112,6 +112,7 @@ Interface changes - drop support for `-del` syntax for list options - `--demuxer-hysteresis-secs` now respects `--cache-secs` and/or `--demuxer-readahead-secs` as well + - add hdr metadata to `video-params` 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 00ce20c846..f2150146db 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -2476,7 +2476,7 @@ Property list ``video-params/gamma`` The gamma function in use as string. (Exact values subject to change.) - ``video-params/sig-peak`` + ``video-params/sig-peak`` (deprecated) The video file's tagged signal peak as float. ``video-params/light`` @@ -2497,6 +2497,33 @@ Property list (but in future releases, it could change to ``no``). If alpha is present, this is set to ``straight`` or ``premul``. + ``video-params/min-luma`` + Minimum luminance, as reported by HDR10 metadata (in cd/m²) + + ``video-params/max-luma`` + Maximum luminance, as reported by HDR10 metadata (in cd/m²) + + ``video-params/max-cll`` + Maximum content light level, as reported by HDR10 metadata (in cd/m²) + + ``video-params/max-fall`` + Maximum frame average light level, as reported by HDR10 metadata (in cd/m²) + + ``video-params/scene-max-r`` + MaxRGB of a scene for R component, as reported by HDR10+ metadata (in cd/m²) + + ``video-params/scene-max-g`` + MaxRGB of a scene for G component, as reported by HDR10+ metadata (in cd/m²) + + ``video-params/scene-max-b`` + MaxRGB of a scene for B component, as reported by HDR10+ metadata (in cd/m²) + + ``video-params/max-pq-y`` + Maximum PQ luminance of a frame, as reported by peak detection (in PQ, 0-1) + + ``video-params/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: @@ -2526,6 +2553,7 @@ Property list ``hdr-metadata`` Video HDR metadata per frame, including peak detection result. + If supported the same information is also included in ``video-out-params``. This has a number of sub-properties: ``hdr-metadata/min-luma`` diff --git a/player/command.c b/player/command.c index 56b65794d8..5059e02b25 100644 --- a/player/command.c +++ b/player/command.c @@ -2291,6 +2291,11 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg) (desc.flags & MP_IMGFLAG_ALPHA) ? MP_ALPHA_STRAIGHT : MP_ALPHA_AUTO; } + const struct pl_hdr_metadata *hdr = &p.color.hdr; + bool has_cie_y = pl_hdr_metadata_contains(hdr, PL_HDR_METADATA_CIE_Y); + bool has_hdr10 = pl_hdr_metadata_contains(hdr, PL_HDR_METADATA_HDR10); + bool has_hdr10plus = pl_hdr_metadata_contains(hdr, PL_HDR_METADATA_HDR10PLUS); + bool has_crop = mp_rect_w(p.crop) > 0 && mp_rect_h(p.crop) > 0; const char *aspect_name = get_aspect_ratio_name(d_w / (double)d_h); struct m_sub_property props[] = { @@ -2330,6 +2335,16 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg) SUB_PROP_STR(m_opt_choice_str(mp_alpha_names, p.alpha)), // avoid using "auto" for "no", so just make it unavailable .unavailable = p.alpha == MP_ALPHA_AUTO}, + {"min-luma", SUB_PROP_FLOAT(hdr->min_luma), .unavailable = !has_hdr10}, + {"max-luma", SUB_PROP_FLOAT(hdr->max_luma), .unavailable = !has_hdr10}, + {"max-cll", SUB_PROP_FLOAT(hdr->max_cll), .unavailable = !has_hdr10}, + {"max-fall", SUB_PROP_FLOAT(hdr->max_fall), .unavailable = !has_hdr10}, + {"scene-max-r", SUB_PROP_FLOAT(hdr->scene_max[0]), .unavailable = !has_hdr10plus}, + {"scene-max-g", SUB_PROP_FLOAT(hdr->scene_max[1]), .unavailable = !has_hdr10plus}, + {"scene-max-b", SUB_PROP_FLOAT(hdr->scene_max[2]), .unavailable = !has_hdr10plus}, + {"scene-avg", SUB_PROP_FLOAT(hdr->scene_avg), .unavailable = !has_hdr10plus}, + {"max-pq-y", SUB_PROP_FLOAT(hdr->max_pq_y), .unavailable = !has_cie_y}, + {"avg-pq-y", SUB_PROP_FLOAT(hdr->avg_pq_y), .unavailable = !has_cie_y}, {0} }; @@ -2360,7 +2375,13 @@ static int mp_property_vo_imgparams(void *ctx, struct m_property *prop, if (valid != M_PROPERTY_VALID) return valid; - return property_imgparams(get_video_out_params(ctx), action, arg); + struct mp_image_params p = get_video_out_params(ctx); + + MPContext *mpctx = ctx; + if (mpctx->video_out) + vo_control(mpctx->video_out, VOCTRL_HDR_METADATA, &p.color.hdr); + + return property_imgparams(p, action, arg); } static int mp_property_dec_imgparams(void *ctx, struct m_property *prop, diff --git a/player/lua/stats.lua b/player/lua/stats.lua index 1803313f88..75e44cd66f 100644 --- a/player/lua/stats.lua +++ b/player/lua/stats.lua @@ -934,13 +934,11 @@ local function add_video(s) end append_img_params(s, r, ro) - local hdr = mp.get_property_native("hdr-metadata") - if not hdr then - local hdrpeak = r["sig-peak"] or 0 - hdr = {["max-cll"]=math.floor(hdrpeak * 203)} + if not ro["max-cll"] then + ro["max-cll"] = math.floor((ro["sig-peak"] or 0) * 203) end - append_hdr(s, hdr) + append_hdr(s, ro) append_property(s, "packet-video-bitrate", {prefix="Bitrate:", suffix=" kbps"}) append_filters(s, "vf", "Filters:") end diff --git a/video/csputils.c b/video/csputils.c index 34fc4ead42..b7fe5737cd 100644 --- a/video/csputils.c +++ b/video/csputils.c @@ -133,6 +133,7 @@ void mp_colorspace_merge(struct mp_colorspace *orig, struct mp_colorspace *new) orig->sig_peak = new->sig_peak; 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). @@ -912,7 +913,8 @@ bool mp_colorspace_equal(struct mp_colorspace c1, struct mp_colorspace c2) c1.primaries == c2.primaries && c1.gamma == c2.gamma && c1.light == c2.light && - c1.sig_peak == c2.sig_peak; + c1.sig_peak == c2.sig_peak && + pl_hdr_metadata_equal(&c1.hdr, &c2.hdr); } enum mp_csp_equalizer_param { diff --git a/video/csputils.h b/video/csputils.h index ab5d9792e0..5b2fe6d63e 100644 --- a/video/csputils.h +++ b/video/csputils.h @@ -147,7 +147,8 @@ struct mp_colorspace { enum mp_csp_prim primaries; enum mp_csp_trc gamma; enum mp_csp_light light; - float sig_peak; // highest relative value in signal. 0 = unknown/auto + float sig_peak; // highest relative value in signal. 0 = unknown/auto (deprecated) + struct pl_hdr_metadata hdr; }; // For many colorspace conversions, in particular those involving HDR, an diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c index e295b1b752..c0ec11d0b8 100644 --- a/video/filter/vf_format.c +++ b/video/filter/vf_format.c @@ -81,8 +81,10 @@ static void set_params(struct vf_format_opts *p, struct mp_image_params *out, out->color.light = MP_CSP_LIGHT_AUTO; } } - if (p->sig_peak) + if (p->sig_peak) { out->color.sig_peak = p->sig_peak; + out->color.hdr.max_cll = p->sig_peak; + } if (p->light) out->color.light = p->light; if (p->chroma_location)