From d816e67b6839bc138c810037338f27e3c250ca58 Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Sat, 16 Nov 2024 13:11:22 +0100 Subject: [PATCH] vo: add --video-recenter This resets ``--video-align-x`` and ``--video-align-y`` to 0 when the video becomes smaller than the OSD in the respective direction, e.g. by zooming out. Unlike doing this by observing osd-dimensions in a script, this is done before rerendering, so you don't see the image being rendered not centered for an instant after zooming out before being rerendered centered. Defaults to yes. --- DOCS/interface-changes/video-recenter.txt | 1 + DOCS/man/options.rst | 26 +++++++++++++++++----- options/options.c | 2 ++ options/options.h | 1 + video/out/vo.c | 27 +++++++++++++++++++++++ 5 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 DOCS/interface-changes/video-recenter.txt diff --git a/DOCS/interface-changes/video-recenter.txt b/DOCS/interface-changes/video-recenter.txt new file mode 100644 index 0000000000000..a0905a07f398b --- /dev/null +++ b/DOCS/interface-changes/video-recenter.txt @@ -0,0 +1 @@ +add `--video-recenter` option diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index d32bcac9d4b88..f97eeed6a3e58 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -1652,17 +1652,31 @@ Video ``--keepaspect=no`` is used. ``--video-align-x=<-1-1>``, ``--video-align-y=<-1-1>`` - Moves the video rectangle within the black borders, which are usually added - to pad the video to screen if video and screen aspect ratios are different. - ``--video-align-y=-1`` would move the video to the top of the screen - (leaving a border only on the bottom), a value of ``0`` centers it - (default), and a value of ``1`` would put the video at the bottom of the - screen. + When the video is bigger than the OSD, these move the displayed rectangle to + show different parts of the video. ``--video-align-y=-1`` would display the + top of the video, ``0`` would display around the center (default), and ``1`` + would display the bottom. + + When the video is smaller than the OSD and ``--video-recenter`` is disabled, + these move the video rectangle within the black borders, which are usually + added to pad the video to screen if video and screen aspect ratios are + different. ``--video-align-y=-1`` would move the video to the top of the + screen (leaving a border only on the bottom), ``0`` would center it, and + ``1`` would put the video at the bottom of the screen. If video and screen aspect match perfectly, these options do nothing. + Unlike ``--video-pan-x`` and ``--video-pan-y``, these don't go beyond the + video's boundaries or make the displayed rectangle drift off after zooming. + This option is disabled if ``--keepaspect=no`` is used. +``--video-recenter=`` + Whether to reset ``--video-align-x`` and ``--video-align-y`` to 0 when the + video becomes smaller than the OSD in the respective direction + + Default: yes. + ``--video-margin-ratio-left=``, ``--video-margin-ratio-right=``, ``--video-margin-ratio-top=``, ``--video-margin-ratio-bottom=`` Set extra video margins on each border (default: 0). Each value is a ratio of the window size, using a range 0.0-1.0. For example, setting the option diff --git a/options/options.c b/options/options.c index b1d5eacfaf09d..fe342d7a97755 100644 --- a/options/options.c +++ b/options/options.c @@ -160,6 +160,7 @@ static const m_option_t mp_vo_opt_list[] = { {"video-crop", OPT_RECT(video_crop), .flags = UPDATE_IMGPAR}, {"video-unscaled", OPT_CHOICE(unscaled, {"no", 0}, {"yes", 1}, {"downscale-big", 2})}, + {"video-recenter", OPT_BOOL(recenter)}, {"wid", OPT_INT64(WinID)}, {"screen", OPT_CHOICE(screen_id, {"default", -1}), M_RANGE(0, 32)}, {"screen-name", OPT_STRING(screen_name)}, @@ -250,6 +251,7 @@ const struct m_sub_options vo_sub_opts = { .scale_x = 1.0f, .scale_y = 1.0f, .auto_window_resize = true, + .recenter = true, .keepaspect = true, .keepaspect_window = true, .native_fs = true, diff --git a/options/options.h b/options/options.h index 347746f7c8696..04a8a63f1fa20 100644 --- a/options/options.h +++ b/options/options.h @@ -58,6 +58,7 @@ typedef struct mp_vo_opts { double window_scale; bool auto_window_resize; + bool recenter; bool keepaspect; bool keepaspect_window; bool hidpi_window_scale; diff --git a/video/out/vo.c b/video/out/vo.c index db29690950cc1..d49b201a955b4 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -31,6 +31,7 @@ #include "misc/dispatch.h" #include "misc/rendezvous.h" #include "options/options.h" +#include "options/m_config_frontend.h" #include "misc/bstr.h" #include "vo.h" #include "aspect.h" @@ -45,6 +46,7 @@ #include "sub/osd.h" #include "osdep/io.h" #include "osdep/threads.h" +#include "player/core.h" extern const struct vo_driver video_out_mediacodec_embed; extern const struct vo_driver video_out_x11; @@ -230,12 +232,35 @@ static void read_opts(struct vo *vo) mp_mutex_unlock(&in->lock); } +static void recenter(struct vo* vo) +{ + if (!vo->params || !vo->opts->recenter) + return; + + struct MPContext *mpctx = (struct MPContext *)vo->extra.wakeup_ctx; + struct mp_rect src, dst; + struct mp_osd_res dims = osd_get_vo_res(vo->osd); + mp_get_src_dst_rects(vo->log, vo->opts, vo->driver->caps, vo->params, + dims.w, dims.h, vo->monitor_par, &src, &dst, + &dims); + + if (dims.ml + dims.mr > 0) { + mpctx->opts->vo->align_x = 0; + m_config_notify_change_opt_ptr(mpctx->mconfig, &mpctx->opts->vo->align_x); + } + if (dims.mt + dims.mb > 0) { + mpctx->opts->vo->align_y = 0; + m_config_notify_change_opt_ptr(mpctx->mconfig, &mpctx->opts->vo->align_y); + } +} + static void update_opts(void *p) { struct vo *vo = p; if (m_config_cache_update(vo->opts_cache)) { read_opts(vo); + recenter(vo); if (vo->driver->control) { vo->driver->control(vo, VOCTRL_VO_OPTS_CHANGED, NULL); // "Legacy" update of video position related options. @@ -599,6 +624,8 @@ static void run_reconfig(void *p) vo->params = talloc_dup(vo, params); mp_mutex_unlock(&vo->params_mutex); + recenter(vo); + if (vo->driver->reconfig2) { *ret = vo->driver->reconfig2(vo, img); } else {