diff --git a/DOCS/interface-changes/screenshot-raw-format.txt b/DOCS/interface-changes/screenshot-raw-format.txt new file mode 100644 index 0000000000..4e0514d9f3 --- /dev/null +++ b/DOCS/interface-changes/screenshot-raw-format.txt @@ -0,0 +1 @@ +add `format` argument to `screenshot-raw` command diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index f1970c6965..c9d1c50c3a 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -1395,21 +1395,38 @@ Screenshot Commands Like all input command parameters, the filename is subject to property expansion as described in `Property Expansion`_. -``screenshot-raw []`` +``screenshot-raw [ []]`` Return a screenshot in memory. This can be used only through the client API. The MPV_FORMAT_NODE_MAP returned by this command has the ``w``, ``h``, - ``stride`` fields set to obvious contents. The ``format`` field is set to - ``bgr0`` by default. This format is organized as ``B8G8R8X8`` (where ``B`` - is the LSB). The contents of the padding ``X`` are undefined. The ``data`` - field is of type MPV_FORMAT_BYTE_ARRAY with the actual image data. The image - is freed as soon as the result mpv_node is freed. As usual with client API - semantics, you are not allowed to write to the image data. + ``stride`` fields set to obvious contents. + + The ``format`` field is set to the format of the screenshot image data. + This can be controlled by the ``format`` argument. The format can be one of + the following: + + bgr0 (default) + This format is organized as ``B8G8R8X8`` (where ``B`` is the LSB). + The contents of the padding ``X`` are undefined. + bgra + This format is organized as ``B8G8R8A8`` (where ``B`` is the LSB). + rgba + This format is organized as ``R8G8B8A8`` (where ``R`` is the LSB). + rgba64 + This format is organized as ``R16G16B16A16`` (where ``R`` is the LSB). + Each component occupies 2 bytes per pixel. + When this format is used, the image data will be high bit depth, and + ``--screenshot-high-bit-depth`` is ignored. + + The ``data`` field is of type MPV_FORMAT_BYTE_ARRAY with the actual image + data. The image is freed as soon as the result mpv_node is freed. As usual + with client API semantics, you are not allowed to write to the image data. The ``stride`` is the number of bytes from a pixel at ``(x0, y0)`` to the - pixel at ``(x0, y0 + 1)``. This can be larger than ``w * 4`` if the image + pixel at ``(x0, y0 + 1)``. This can be larger than ``w * bpp`` if the image was cropped, or if there is padding. This number can be negative as well. - You access a pixel with ``byte_index = y * stride + x * 4`` (assuming the - ``bgr0`` format). + You access a pixel with ``byte_index = y * stride + x * bpp``. + Here, ``bpp`` is the number of bytes per pixel, which is 8 for ``rgba64`` + format and 4 for other formats. The ``flags`` argument is like the first argument to ``screenshot`` and supports ``subtitles``, ``video``, ``window``. diff --git a/player/command.c b/player/command.c index a4aefb57fa..eeda2f8c81 100644 --- a/player/command.c +++ b/player/command.c @@ -7176,6 +7176,12 @@ const struct mp_cmd_def mp_cmds[] = { {"window", 1}, {"subtitles", 2}), OPTDEF_INT(2)}, + {"format", OPT_CHOICE(v.i, + {"bgr0", 0}, + {"bgra", 1}, + {"rgba", 2}, + {"rgba64", 3}), + OPTDEF_INT(0)}, }, }, { "loadfile", cmd_loadfile, diff --git a/player/screenshot.c b/player/screenshot.c index 365737d638..507d17ffb5 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -558,8 +558,14 @@ void cmd_screenshot_raw(void *p) struct MPContext *mpctx = cmd->mpctx; struct mpv_node *res = &cmd->result; + const enum mp_imgfmt formats[] = {IMGFMT_BGR0, IMGFMT_BGRA, IMGFMT_RGBA, IMGFMT_RGBA64}; + const char *format_names[] = {"bgr0", "bgra", "rgba", "rgba64"}; + int idx = cmd->args[1].v.i; + assert(idx >= 0 && idx <= 3); + + bool high_depth = formats[idx] == IMGFMT_RGBA64; struct mp_image *img = screenshot_get_rgb(mpctx, cmd->args[0].v.i, - false, IMGFMT_BGR0); + high_depth, formats[idx]); if (!img) { cmd->success = false; return; @@ -569,7 +575,7 @@ void cmd_screenshot_raw(void *p) node_map_add_int64(res, "w", img->w); node_map_add_int64(res, "h", img->h); node_map_add_int64(res, "stride", img->stride[0]); - node_map_add_string(res, "format", "bgr0"); + node_map_add_string(res, "format", format_names[idx]); struct mpv_byte_array *ba = node_map_add(res, "data", MPV_FORMAT_BYTE_ARRAY)->u.ba; *ba = (struct mpv_byte_array){