command: add colorspace and luminance arguments to overlay-add

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 #10678
This commit is contained in:
Kacper Michajłow committed 2026-08-23 18:09:02 +02:00
1 parent 1c2ff7d56b
commit 654e9382c0
4 files changed
+52 -3

No files matched your search

@@ -0,0 +1,2 @@
add `video_colorspace`, `max_luma`, `primaries` and `transfer` arguments
to the `overlay-add` command
+19 -1
View File
@@ -904,7 +904,7 @@ OSD Commands
Show the progress bar, the elapsed time and the total duration of the file
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> [<video_colorspace> [<max_luma> [<primaries> [<transfer>]]]]]]``
Add an OSD overlay sourced from raw data. This might be useful for scripts
and applications controlling mpv, and which want to display things on top
of the video window.
@@ -964,6 +964,24 @@ OSD Commands
in display to ``dw`` and ``dh``. If parameters are not present, the
values for ``w`` and ``h`` are used.
``video_colorspace`` (default: no) interprets the overlay in the video's
colorspace, including HDR metadata, so it is tone mapped exactly like
the video.
``max_luma`` specifies the (optional) luminance peak of the overlay in
cd/m². If unset, it is inferred from the overlay's colorspace, or taken
from the video for ``video_colorspace`` overlays.
``primaries`` and ``transfer`` specify the (optional) colorspace the
overlay is encoded in, and accept the same values as ``--target-prim``
and ``--target-trc``. The default ``auto`` means sRGB (BT.709 primaries
and sRGB transfer). They are ignored if ``video_colorspace`` is set.
Currently only ``--vo=gpu-next`` honors these parameters. ``--vo=gpu``
always assumes the overlay is sRGB and adapts it to the display. Other
VOs ignore these parameters, and either blend the overlay without any
colorspace conversion or pass it to the system compositor.
.. note::
Before mpv 0.42.0, the file was mapped into memory with ``mmap()``,
+1 -1
View File
@@ -23,7 +23,7 @@
#include "misc/bstr.h"
#include "options/m_option.h"
#define MP_CMD_DEF_MAX_ARGS 11
#define MP_CMD_DEF_MAX_ARGS 15
#define MP_CMD_OPT_ARG M_OPT_OPTIONAL_PARAM
struct mp_log;
+30 -1
View File
@@ -145,6 +145,10 @@ struct overlay {
struct mp_image *source;
int x, y;
int dw, dh;
enum pl_color_primaries primaries;
enum pl_color_transfer transfer;
float max_luma;
bool video_colorspace;
};
struct hook_handler {
@@ -5303,6 +5307,12 @@ static void recreate_overlays(struct MPContext *mpctx)
.h = s->h, .dh = o->dh,
.x = o->x,
.y = o->y,
.bgra = {
.primaries = o->primaries,
.transfer = o->transfer,
.max_luma = o->max_luma,
.video_color_space = o->video_colorspace,
},
};
MP_TARRAY_APPEND(cmd, new->parts, new->num_parts, b);
}
@@ -5420,6 +5430,13 @@ static void cmd_overlay_add(void *pcmd)
char *fmt = cmd->args[5].v.s;
int w = cmd->args[6].v.i, h = cmd->args[7].v.i, stride = cmd->args[8].v.i;
int dw = cmd->args[9].v.i, dh = cmd->args[10].v.i;
bool video_colorspace = cmd->args[11].v.b;
float max_luma = cmd->args[12].v.f;
int primaries = cmd->args[13].v.i, transfer = cmd->args[14].v.i;
// video_colorspace overrides explicit tags
if (video_colorspace)
primaries = transfer = 0;
if (dw <= 0)
dw = w;
@@ -5443,6 +5460,10 @@ static void cmd_overlay_add(void *pcmd)
.y = y,
.dw = dw,
.dh = dh,
.primaries = primaries,
.transfer = transfer,
.max_luma = max_luma,
.video_colorspace = video_colorspace,
};
if (!overlay.source)
goto error;
@@ -7890,7 +7911,15 @@ const struct mp_cmd_def mp_cmds[] = {
{"h", OPT_INT(v.i)},
{"stride", OPT_INT(v.i)},
{"dw", OPT_INT(v.i), OPTDEF_INT(0)},
{"dh", OPT_INT(v.i), OPTDEF_INT(0)}, }},
{"dh", OPT_INT(v.i), OPTDEF_INT(0)},
{"video_colorspace", OPT_BOOL(v.b),
OPTDEF_INT(0)},
{"max_luma", OPT_FLOAT(v.f),
M_RANGE(0, 10000), OPTDEF_FLOAT(0)},
{"primaries", OPT_CHOICE_C(v.i, pl_csp_prim_names),
OPTDEF_INT(PL_COLOR_PRIM_UNKNOWN)},
{"transfer", OPT_CHOICE_C(v.i, pl_csp_trc_names),
OPTDEF_INT(PL_COLOR_TRC_UNKNOWN)}, }},
{ "overlay-remove", cmd_overlay_remove, { {"id", OPT_INT(v.i)} } },
{ "osd-overlay", cmd_osd_overlay,