mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-22 10:57:08 +00:00
screenshot: add osd and scaled flags to screenshot commands
Currently, screenshot being scaled and the presence of OSD and subtitles cannot be independently controlled. This adds osd and scaled flags to screenshot commands that make it possible to e.g. take screenshots with only OSD without subtitles, or take screenshots at scaled resolution without OSD or subtitles. The "window" flag is now an alias of scaled+subtitles+osd, and is kept for convenience.
This commit is contained in:
1
DOCS/interface-changes/screenshot-flags.txt
Normal file
1
DOCS/interface-changes/screenshot-flags.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
add `scaled` and `osd` flags to screenshot commands
|
||||||
@@ -1419,16 +1419,21 @@ Screenshot Commands
|
|||||||
|
|
||||||
Multiple flags are available (some can be combined with ``+``):
|
Multiple flags are available (some can be combined with ``+``):
|
||||||
|
|
||||||
|
<video>
|
||||||
|
Save the video image in its original resolution, without OSD or
|
||||||
|
subtitles. This is the default when no flag is specified, and it does
|
||||||
|
not need to be explicitly added when combined with other flags.
|
||||||
|
<scaled>
|
||||||
|
Save the video image in the current playback resolution.
|
||||||
<subtitles> (default)
|
<subtitles> (default)
|
||||||
Save the video image, in its original resolution, and with subtitles.
|
Save the video image with subtitles.
|
||||||
Some video outputs may still include the OSD in the output under certain
|
Some video outputs may still include the OSD in the output under certain
|
||||||
circumstances.
|
circumstances.
|
||||||
<video>
|
<osd>
|
||||||
Like ``subtitles``, but typically without OSD or subtitles. The exact
|
Save the video image with OSD.
|
||||||
behavior depends on the selected video output.
|
|
||||||
<window>
|
<window>
|
||||||
Save the contents of the mpv window. Typically scaled, with OSD and
|
Save the contents of the mpv window, with OSD and subtitles.
|
||||||
subtitles. The exact behavior depends on the selected video output.
|
This is an alias of ``scaled+subtitles+osd``.
|
||||||
<each-frame>
|
<each-frame>
|
||||||
Take a screenshot each frame. Issue this command again to stop taking
|
Take a screenshot each frame. Issue this command again to stop taking
|
||||||
screenshots. Note that you should disable frame-dropping when using
|
screenshots. Note that you should disable frame-dropping when using
|
||||||
@@ -1436,6 +1441,9 @@ Screenshot Commands
|
|||||||
frame was dropped. This flag can be combined with the other flags,
|
frame was dropped. This flag can be combined with the other flags,
|
||||||
e.g. ``video+each-frame``.
|
e.g. ``video+each-frame``.
|
||||||
|
|
||||||
|
The exact behaviors of all flags other than ``each-frame`` depend on the
|
||||||
|
selected video output.
|
||||||
|
|
||||||
Older mpv versions required passing ``single`` and ``each-frame`` as
|
Older mpv versions required passing ``single`` and ``each-frame`` as
|
||||||
second argument (and did not have flags). This syntax is still understood,
|
second argument (and did not have flags). This syntax is still understood,
|
||||||
but deprecated and might be removed in the future.
|
but deprecated and might be removed in the future.
|
||||||
|
|||||||
@@ -7347,11 +7347,14 @@ const struct mp_cmd_def mp_cmds[] = {
|
|||||||
{ "screenshot", cmd_screenshot,
|
{ "screenshot", cmd_screenshot,
|
||||||
{
|
{
|
||||||
{"flags", OPT_FLAGS(v.i,
|
{"flags", OPT_FLAGS(v.i,
|
||||||
{"video", 4|0}, {"-", 4|0},
|
{"video", 0},
|
||||||
{"window", 4|1},
|
{"scaled", 1},
|
||||||
{"subtitles", 4|2},
|
{"subtitles", 2},
|
||||||
{"each-frame", 8}),
|
{"osd", 4},
|
||||||
OPTDEF_INT(4|2)},
|
{"each-frame", 8},
|
||||||
|
{"-", 0},
|
||||||
|
{"window", 1|2|4}),
|
||||||
|
OPTDEF_INT(2)},
|
||||||
// backwards compatibility
|
// backwards compatibility
|
||||||
{"legacy", OPT_CHOICE(v.i,
|
{"legacy", OPT_CHOICE(v.i,
|
||||||
{"unused", 0}, {"single", 0},
|
{"unused", 0}, {"single", 0},
|
||||||
@@ -7365,8 +7368,10 @@ const struct mp_cmd_def mp_cmds[] = {
|
|||||||
{"filename", OPT_STRING(v.s)},
|
{"filename", OPT_STRING(v.s)},
|
||||||
{"flags", OPT_CHOICE(v.i,
|
{"flags", OPT_CHOICE(v.i,
|
||||||
{"video", 0},
|
{"video", 0},
|
||||||
{"window", 1},
|
{"scaled", 1},
|
||||||
{"subtitles", 2}),
|
{"subtitles", 2},
|
||||||
|
{"osd", 4},
|
||||||
|
{"window", 1|2|4}),
|
||||||
OPTDEF_INT(2)},
|
OPTDEF_INT(2)},
|
||||||
},
|
},
|
||||||
.spawn_thread = true,
|
.spawn_thread = true,
|
||||||
@@ -7375,8 +7380,10 @@ const struct mp_cmd_def mp_cmds[] = {
|
|||||||
{
|
{
|
||||||
{"flags", OPT_CHOICE(v.i,
|
{"flags", OPT_CHOICE(v.i,
|
||||||
{"video", 0},
|
{"video", 0},
|
||||||
{"window", 1},
|
{"scaled", 1},
|
||||||
{"subtitles", 2}),
|
{"subtitles", 2},
|
||||||
|
{"osd", 4},
|
||||||
|
{"window", 1|2|4}),
|
||||||
OPTDEF_INT(2)},
|
OPTDEF_INT(2)},
|
||||||
{"format", OPT_CHOICE(v.i,
|
{"format", OPT_CHOICE(v.i,
|
||||||
{"bgr0", 0},
|
{"bgr0", 0},
|
||||||
|
|||||||
@@ -43,8 +43,9 @@
|
|||||||
|
|
||||||
#include "video/csputils.h"
|
#include "video/csputils.h"
|
||||||
|
|
||||||
#define MODE_FULL_WINDOW 1
|
#define MODE_SCALED 1
|
||||||
#define MODE_SUBTITLES 2
|
#define MODE_SUBTITLES 2
|
||||||
|
#define MODE_OSD 4
|
||||||
|
|
||||||
typedef struct screenshot_ctx {
|
typedef struct screenshot_ctx {
|
||||||
struct MPContext *mpctx;
|
struct MPContext *mpctx;
|
||||||
@@ -324,14 +325,13 @@ static char *gen_fname(struct mp_cmd_ctx *cmd, const char *file_ext)
|
|||||||
|
|
||||||
static void add_osd(struct MPContext *mpctx, struct mp_image *image, int mode)
|
static void add_osd(struct MPContext *mpctx, struct mp_image *image, int mode)
|
||||||
{
|
{
|
||||||
bool window = mode == MODE_FULL_WINDOW;
|
struct mp_osd_res res = (mode & MODE_SCALED) ? osd_get_vo_res(mpctx->video_out->osd) :
|
||||||
struct mp_osd_res res = window ? osd_get_vo_res(mpctx->video_out->osd) :
|
|
||||||
osd_res_from_image_params(&image->params);
|
osd_res_from_image_params(&image->params);
|
||||||
if (mode == MODE_SUBTITLES || window) {
|
if (mode & MODE_SUBTITLES) {
|
||||||
osd_draw_on_image(mpctx->osd, res, mpctx->video_pts,
|
osd_draw_on_image(mpctx->osd, res, mpctx->video_pts,
|
||||||
OSD_DRAW_SUB_ONLY, image);
|
OSD_DRAW_SUB_ONLY, image);
|
||||||
}
|
}
|
||||||
if (window) {
|
if (mode & MODE_OSD) {
|
||||||
osd_draw_on_image(mpctx->osd, res, mpctx->video_pts,
|
osd_draw_on_image(mpctx->osd, res, mpctx->video_pts,
|
||||||
OSD_DRAW_OSD_ONLY, image);
|
OSD_DRAW_OSD_ONLY, image);
|
||||||
}
|
}
|
||||||
@@ -342,8 +342,8 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode,
|
|||||||
{
|
{
|
||||||
struct mp_image *image = NULL;
|
struct mp_image *image = NULL;
|
||||||
const struct image_writer_opts *imgopts = mpctx->opts->screenshot_image_opts;
|
const struct image_writer_opts *imgopts = mpctx->opts->screenshot_image_opts;
|
||||||
if (mode == MODE_SUBTITLES && osd_get_render_subs_in_filter(mpctx->osd))
|
if ((mode & MODE_SUBTITLES) && osd_get_render_subs_in_filter(mpctx->osd))
|
||||||
mode = 0;
|
mode &= ~MODE_SUBTITLES;
|
||||||
|
|
||||||
if (!mpctx->video_out || !mpctx->video_out->config_ok)
|
if (!mpctx->video_out || !mpctx->video_out->config_ok)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -351,11 +351,13 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode,
|
|||||||
vo_wait_frame(mpctx->video_out); // important for each-frame mode
|
vo_wait_frame(mpctx->video_out); // important for each-frame mode
|
||||||
|
|
||||||
bool use_sw = mpctx->opts->screenshot_sw;
|
bool use_sw = mpctx->opts->screenshot_sw;
|
||||||
bool window = mode == MODE_FULL_WINDOW;
|
bool scaled = mode & MODE_SCALED;
|
||||||
|
bool subs = mode & MODE_SUBTITLES;
|
||||||
|
bool osd = mode & MODE_OSD;
|
||||||
struct voctrl_screenshot ctrl = {
|
struct voctrl_screenshot ctrl = {
|
||||||
.scaled = window,
|
.scaled = scaled,
|
||||||
.subs = mode != 0,
|
.subs = subs,
|
||||||
.osd = window,
|
.osd = osd,
|
||||||
.high_bit_depth = high_depth && imgopts->high_bit_depth,
|
.high_bit_depth = high_depth && imgopts->high_bit_depth,
|
||||||
.native_csp = image_writer_flexible_csp(imgopts),
|
.native_csp = image_writer_flexible_csp(imgopts),
|
||||||
};
|
};
|
||||||
@@ -363,7 +365,9 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode,
|
|||||||
vo_control(mpctx->video_out, VOCTRL_SCREENSHOT, &ctrl);
|
vo_control(mpctx->video_out, VOCTRL_SCREENSHOT, &ctrl);
|
||||||
image = ctrl.res;
|
image = ctrl.res;
|
||||||
|
|
||||||
if (!use_sw && !image && window)
|
// VOCTRL_SCREENSHOT_WIN gets the complete rendered image so it's only
|
||||||
|
// usable for scaled+sub+osd screenshots.
|
||||||
|
if (!use_sw && !image && scaled && subs && osd)
|
||||||
vo_control(mpctx->video_out, VOCTRL_SCREENSHOT_WIN, &image);
|
vo_control(mpctx->video_out, VOCTRL_SCREENSHOT_WIN, &image);
|
||||||
|
|
||||||
if (!image) {
|
if (!image) {
|
||||||
@@ -381,7 +385,7 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode,
|
|||||||
image = nimage;
|
image = nimage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_sw && image && window) {
|
if (use_sw && image && scaled) {
|
||||||
if (mp_image_crop_valid(&image->params) &&
|
if (mp_image_crop_valid(&image->params) &&
|
||||||
(mp_rect_w(image->params.crop) != image->w ||
|
(mp_rect_w(image->params.crop) != image->w ||
|
||||||
mp_rect_h(image->params.crop) != image->h))
|
mp_rect_h(image->params.crop) != image->h))
|
||||||
@@ -506,14 +510,14 @@ void cmd_screenshot(void *p)
|
|||||||
struct mp_cmd_ctx *cmd = p;
|
struct mp_cmd_ctx *cmd = p;
|
||||||
struct MPContext *mpctx = cmd->mpctx;
|
struct MPContext *mpctx = cmd->mpctx;
|
||||||
struct mpv_node *res = &cmd->result;
|
struct mpv_node *res = &cmd->result;
|
||||||
int mode = cmd->args[0].v.i & 3;
|
int mode = cmd->args[0].v.i & 7;
|
||||||
bool each_frame_toggle = (cmd->args[0].v.i | cmd->args[1].v.i) & 8;
|
bool each_frame_toggle = (cmd->args[0].v.i | cmd->args[1].v.i) & 8;
|
||||||
bool each_frame_mode = cmd->args[0].v.i & 16;
|
bool each_frame_mode = cmd->args[0].v.i & 16;
|
||||||
|
|
||||||
screenshot_ctx *ctx = mpctx->screenshot_ctx;
|
screenshot_ctx *ctx = mpctx->screenshot_ctx;
|
||||||
|
|
||||||
if (mode == MODE_SUBTITLES && osd_get_render_subs_in_filter(mpctx->osd))
|
if ((mode & MODE_SUBTITLES) && osd_get_render_subs_in_filter(mpctx->osd))
|
||||||
mode = 0;
|
mode &= ~MODE_SUBTITLES;
|
||||||
|
|
||||||
if (!each_frame_mode) {
|
if (!each_frame_mode) {
|
||||||
if (each_frame_toggle) {
|
if (each_frame_toggle) {
|
||||||
|
|||||||
Reference in New Issue
Block a user