Skip to content

command: add primaries, transfer and video_colorspace to overlay-add - #18395

Open
kasper93 wants to merge 7 commits into
mpv-player:masterfrom
kasper93:overlay-add-csp
Open

command: add primaries, transfer and video_colorspace to overlay-add#18395
kasper93 wants to merge 7 commits into
mpv-player:masterfrom
kasper93:overlay-add-csp

Conversation

@kasper93

Copy link
Copy Markdown
Member

No description provided.

kasper93 and others added 5 commits August 20, 2026 20:16
The union member is only valid for SUBBITMAP_LIBASS. The resulting data
is only read for PL_OVERLAY_MONOCHROME, so there was no risk of using
garbage data, but we can make it explicit.
The flag was lost when replacing the result with the packed image.
Bitmap subtitles muxed in media file are generally the same colorspace
as video. Generic overlays may not be.
@kasper93

Copy link
Copy Markdown
Member Author

/cc @na-na-hi @iwalton3 @posilash

@iwalton3

iwalton3 commented Aug 20, 2026

Copy link
Copy Markdown

I can confirm this fixes the SDR usecase again.
2026-08-20_18-35
(Compare to broken version.)

It also appears to work with a patched thumbfast too to emit actual HDR thumbnails on an HDR display, although I need to fix some local issues to actually test mpv with real HDR support not through a screengrab proxy.

hdrproxy-20260820-182104

Edit: I got my HDR display and Nvidia drivers working, HDR thumbnails are working end-to-end!

@kasper93

Copy link
Copy Markdown
Member Author

@posilash: You removed the comment, do you want image_subs_hdr_peak to affect overlays too, same as subtitles? I think it generally makes sense (current pr), the image_subs_hdr_peak option itself is bit silly anyway.

@posilash

posilash commented Aug 20, 2026

Copy link
Copy Markdown

@kasper93 I was running more tests, wanted concrete numbers to back my suggestion.

Comment thread video/out/vo_gpu_next.c
// Muxed image subtitles and overlays tagged with video_colorspace
// are in the video's colorspace
color = src->params.color;
if (pl_color_transfer_is_hdr(color.transfer)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (pl_color_transfer_is_hdr(color.transfer)) {
if (!b->bgra.video_color_space && pl_color_transfer_is_hdr(color.transfer)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs for video_colorspace say the overlay is interpreted in the video's colorspace "including HDR metadata", but the metadata gets replaced by --image-subs-hdr-peak here. Printing color at the end of bgra_overlay_color(), just before it returns, on a BT.2020/PQ file with video_colorspace=true and default options:

overlay  prim=6 trc=12 max_luma=1000.0   min_luma=0.000000
video    prim=6 trc=12 max_luma=10000.0  min_luma=0.000001
memcmp over the whole pl_color_space: not equal

With the fix applied:

overlay  prim=6 trc=12 max_luma=10000.0  min_luma=0.000001
video    prim=6 trc=12 max_luma=10000.0  min_luma=0.000001
memcmp over the whole pl_color_space: equal

Image subtitles keep the clamp, i checked by setting item->video_color_space on an overlay-add bitmap so it takes that path, and it still responds to --image-subs-hdr-peak.

One thing to check: else if (ref_luma) below becomes reachable for these overlays with the change. ref_luma is 0 here unless --hdr-reference-white is set, and i couldn't measure a difference either way, but you'd know whether it matters.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs for video_colorspace say the overlay is interpreted in the video's colorspace "including HDR metadata", but the metadata gets replaced by --image-subs-hdr-peak here.

It's stated explicity

video_colorspace (default: no) interprets the overlay in the video's colorspace, including HDR metadata, so it is tone mapped exactly like the video. The overlay is treated like image subtitles (see --image-subs-hdr-peak).

I will think tomorrow what we can do about overlays better.

@posilash posilash Aug 20, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overlay is treated like image subtitles (see --image-subs-hdr-peak).

I think those two sentences are contradictory, instead of one qualifying the other. "tone mapped exactly like the video" and "treated like image subtitles" can't both hold, since the image subtitle path is defined by replacing the peak. Either way the docs will need a clearer statement once you've settled what the behaviour should be.

Also, wrt the docs, <primaries> <transfer> <video_colorspace> should be [<primaries>] [<transfer>] [<video_colorspace>] since they're optional arguments.

@kasper93

Copy link
Copy Markdown
Member Author

I have not added it here, but we might need max luminance parameter for HDR overlays. I think single luminance value would be enough in practice to get us most of the use cases.

@posilash

Copy link
Copy Markdown

I have not added it here, but we might need max luminance parameter for HDR overlays. I think single luminance value would be enough in practice to get us most of the use cases.

Yes, this was part of my discussion with @llyyr in #18394

Either way, explicit HDR transfers would need to include the peak metadata (from where?), or else the overlay blowout issue would persist.

@posilash

Copy link
Copy Markdown

@posilash: You removed the comment, do you want image_subs_hdr_peak to affect overlays too, same as subtitles? I think it generally makes sense (current pr), the image_subs_hdr_peak option itself is bit silly anyway.

No, I don't think image_subs_hdr_peak should affect video_colorspace overlays. For image subtitles the clamp earns its place, they're authored at graphics white with no relation to the video's peak. video_colorspace is the client saying the bitmap is already in the video's colorspace, with the metadata, so replacing the peak contradicts what it was told.

@kasper93

Copy link
Copy Markdown
Member Author

For image subtitles the clamp earns its place, they're authored at graphics white with no relation to the video's peak.

That's dubious. And the actual clamp is a workaround for badly mastered homebrew PGS subtitles. Hardware blu-ray players does not tone map subtitles, they are compositioned onto video, and would be tone mapped with video as single image.

@posilash

Copy link
Copy Markdown

For image subtitles the clamp earns its place, they're authored at graphics white with no relation to the video's peak.

That's dubious. And the actual clamp is a workaround for badly mastered homebrew PGS subtitles. Hardware blu-ray players does not tone map subtitles, they are compositioned onto video, and would be tone mapped with video as single image.

I didn't know about that to be fair, i had the rationale wrong then. But that makes the case stronger though, if the clamp is a workaround for badly mastered PGS then it's the last thing you'd want applied to a bitmap the client explicitly said is in the video's colorspace.

No rush, i'll leave the suggestion there for whenever you look at it.

Split the parts into runs of consecutive parts that share a colorspace
and render each run as a separate overlay referencing the same texture.
Add primaries, transfer, max_luma and video_colorspace arguments.
Allows tagging the colorspace of the overlay bitmap instead of assuming
sRGB. video_colorspace interprets the bitmap in the video's colorspace,
so it is tone mapped exactly like the video. max_luma overrides the
luminance peak of the bitmap. Currently only vo_gpu_next honors these
parameters. vo_gpu keeps its sRGB assumption regardless of the tag.

Fixes mpv-player#10678
@kasper93

Copy link
Copy Markdown
Member Author

I've added max_luma parameter, the name is consistent with other parts of code. This will overwrite luminance value in HDR metadata. At the same time, this is the only piece exposed. It's arguably the important one. Adding all the rest would be annoying for command itself. Not sure it's really fessible with current design.

@posilash

posilash commented Aug 21, 2026

Copy link
Copy Markdown

Looks good to me. You're right it doesn't make sense to add all the other hdr params.

@posilash

Copy link
Copy Markdown

All test are good on my end. It's ready to merge in my opinion.

@na-na-hi na-na-hi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavior looks OK.

Comment thread DOCS/man/input.rst
on the OSD. ``no-osd`` has no effect on this command.

``overlay-add <id> <x> <y> <file> <offset> <fmt> <w> <h> <stride> <dw> <dh>``
``overlay-add <id> <x> <y> <file> <offset> <fmt> <w> <h> <stride> [<dw> [<dh> [<primaries> [<transfer> [<max_luma> [<video_colorspace>]]]]]]``

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to make video_colorspace the first parameter to avoid needing to specify other parameters that will be overriden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants