mirror of
https://github.com/mpv-player/mpv
synced 2025-02-16 12:17:12 +00:00
video: add --autofit and --autofit-larger options
--autofit=WxH sets the window size to a maximum width and/or height, without changing the window's aspect ratio. --autofit-larger=WxH does the same, but only if the video size is actually larger than the window size that would result when using the --autofit=WxH option with the same arguments.
This commit is contained in:
parent
ccaed5eb07
commit
7885fce7ea
@ -203,6 +203,51 @@
|
||||
Enables caching for the stream used by ``--audiofile``, using the
|
||||
specified amount of memory.
|
||||
|
||||
--autofit=<[W[xH]]>
|
||||
Set the initial window size to a maximum size specified by WxH, without
|
||||
changing the window's aspect ratio. The size is measured in pixels, or if
|
||||
a number is followed by a percentage sign (``%``), in percents of the
|
||||
screen size.
|
||||
|
||||
This option never changes the aspect ratio of the window. If the aspect
|
||||
ratio mismatches, the window's size is reduced until it fits into the
|
||||
specified size.
|
||||
|
||||
Window position is not taken into account, nor is it modified by this
|
||||
option (the window manager still may place the window differently depending
|
||||
on size). Use ``--geometry`` to change the window position. Its effects
|
||||
are applied after this option.
|
||||
|
||||
See ``--geometry`` for details how this is handled with multi-monitor
|
||||
setups, or if the ``--wid`` option is used.
|
||||
|
||||
Use ``--autofit-larger`` instead if you don't want the window to get larger.
|
||||
Use ``--geometry`` if you want to force both window width and height to a
|
||||
specific size.
|
||||
|
||||
*NOTE*: Generally only supported by GUI VOs. Ignored for encoding.
|
||||
|
||||
*EXAMPLE*:
|
||||
|
||||
``70%``
|
||||
Make the window width 70% of the screen size, keeping aspect ratio.
|
||||
``1000``
|
||||
Set the window width to 1000 pixels, keeping aspect ratio.
|
||||
``70%:60%``
|
||||
Make the window as large as possible, without being wider than 70% of
|
||||
the screen width, or higher than 60% of the screen height.
|
||||
|
||||
--autofit-larger=<[W[xH]]>
|
||||
This option behaves exactly like ``--autofit``, except the window size is
|
||||
only changed if the window would be larger than the specified size.
|
||||
|
||||
*EXAMPLE*:
|
||||
|
||||
``90%x80%``
|
||||
If the video is larger than 90% of the screen width or 80% of the
|
||||
screen height, make the window smaller until either its width is 90%
|
||||
of the screen, or its height is 80% of the screen.
|
||||
|
||||
--autosub, --no-autosub
|
||||
Load additional subtitle files matching the video filename. Enabled by
|
||||
default. See also ``--autosub-match``.
|
||||
@ -718,6 +763,9 @@
|
||||
Sets the window to half the screen widths, and positions it 10 pixels
|
||||
below/left of the top left corner of the screen.
|
||||
|
||||
See also ``--autofit`` and ``--autofit-larger`` for fitting the window into
|
||||
a given size without changing aspect ratio.
|
||||
|
||||
--grabpointer, --no-grabpointer
|
||||
``--no-grabpointer`` tells the player to not grab the mouse pointer after a
|
||||
video mode change (``--vm``). Useful for multihead setups.
|
||||
|
@ -586,6 +586,8 @@ const m_option_t mplayer_opts[]={
|
||||
OPT_INTRANGE("screenw", vo_screenwidth, CONF_GLOBAL, 0, 4096),
|
||||
OPT_INTRANGE("screenh", vo_screenheight, CONF_GLOBAL, 0, 4096),
|
||||
OPT_GEOMETRY("geometry", vo_geometry, 0),
|
||||
OPT_SIZE_BOX("autofit", vo_autofit, 0),
|
||||
OPT_SIZE_BOX("autofit-larger", vo_autofit_larger, 0),
|
||||
OPT_MAKE_FLAGS("force-window-position", force_window_position, 0),
|
||||
// vo name (X classname) and window title strings
|
||||
OPT_STRING("name", vo_winname, 0),
|
||||
|
@ -1309,7 +1309,34 @@ const m_option_type_t m_option_type_geometry = {
|
||||
.parse = parse_geometry,
|
||||
};
|
||||
|
||||
static int parse_size_box(const m_option_t *opt, struct bstr name,
|
||||
struct bstr param, void *dst)
|
||||
{
|
||||
struct m_geometry gm;
|
||||
if (!parse_geometry_str(&gm, param))
|
||||
goto error;
|
||||
|
||||
if (gm.xy_valid)
|
||||
goto error;
|
||||
|
||||
if (dst)
|
||||
*((struct m_geometry *)dst) = gm;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: invalid size: '%.*s'\n",
|
||||
BSTR_P(name), BSTR_P(param));
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Valid format: W[%%][xH[%%]] or empty string\n");
|
||||
return M_OPT_INVALID;
|
||||
}
|
||||
|
||||
const m_option_type_t m_option_type_size_box = {
|
||||
.name = "Window size",
|
||||
.size = sizeof(struct m_geometry),
|
||||
.parse = parse_size_box,
|
||||
};
|
||||
|
||||
|
||||
#include "video/img_format.h"
|
||||
|
@ -57,6 +57,7 @@ extern const m_option_type_t m_option_type_fourcc;
|
||||
extern const m_option_type_t m_option_type_afmt;
|
||||
extern const m_option_type_t m_option_type_color;
|
||||
extern const m_option_type_t m_option_type_geometry;
|
||||
extern const m_option_type_t m_option_type_size_box;
|
||||
|
||||
// Callback used by m_option_type_print_func options.
|
||||
typedef int (*m_opt_func_full_t)(const m_option_t *, const char *, const char *);
|
||||
@ -219,6 +220,7 @@ union m_option_value {
|
||||
struct m_rel_time rel_time;
|
||||
struct m_color color;
|
||||
struct m_geometry geometry;
|
||||
struct m_geometry size_box;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -534,6 +536,7 @@ static inline void m_option_free(const m_option_t *opt, void *dst)
|
||||
#define OPT_REL_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_rel_time)
|
||||
#define OPT_COLOR(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_color)
|
||||
#define OPT_GEOMETRY(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_geometry)
|
||||
#define OPT_SIZE_BOX(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_size_box)
|
||||
|
||||
#define OPT_TRACKCHOICE(name, var) OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"no", -2}, {"auto", -1}))
|
||||
|
||||
|
@ -21,6 +21,8 @@ typedef struct MPOpts {
|
||||
int vo_screenwidth;
|
||||
int vo_screenheight;
|
||||
struct m_geometry vo_geometry;
|
||||
struct m_geometry vo_autofit;
|
||||
struct m_geometry vo_autofit_larger;
|
||||
int force_window_position;
|
||||
char *vo_winname;
|
||||
char *vo_wintitle;
|
||||
|
@ -28,6 +28,9 @@
|
||||
# force starting with centered window
|
||||
#geometry=50%:50%
|
||||
|
||||
# don't allow a new window to have a size larger than 90% of the screen size
|
||||
#autofit-larger=90%x90%
|
||||
|
||||
# Keep the player window on top of all other windows.
|
||||
#ontop=yes
|
||||
|
||||
|
@ -355,6 +355,32 @@ struct vo *init_best_video_out(struct MPOpts *opts,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fit *w/*h into the size specified by geo.
|
||||
static void apply_autofit(int *w, int *h, int scr_w, int scr_h,
|
||||
struct m_geometry *geo, bool allow_upscale)
|
||||
{
|
||||
if (!geo->wh_valid)
|
||||
return;
|
||||
|
||||
int dummy;
|
||||
int n_w = *w, n_h = *h;
|
||||
m_geometry_apply(&dummy, &dummy, &n_w, &n_h, scr_w, scr_h, geo);
|
||||
|
||||
if (!allow_upscale && *w <= n_w && *h <= n_h)
|
||||
return;
|
||||
|
||||
// If aspect mismatches, always make the window smaller than the fit box
|
||||
double asp = (double)*w / *h;
|
||||
double n_asp = (double)n_w / n_h;
|
||||
if (n_asp <= asp) {
|
||||
*w = n_w;
|
||||
*h = n_w / asp;
|
||||
} else {
|
||||
*w = n_h * asp;
|
||||
*h = n_h;
|
||||
}
|
||||
}
|
||||
|
||||
// Set window size (vo->dwidth/dheight) and position (vo->dx/dy) according to
|
||||
// the video display size d_w/d_h.
|
||||
// NOTE: currently, all GUI backends do their own handling of window geometry
|
||||
@ -365,6 +391,9 @@ static void determine_window_geometry(struct vo *vo, int d_w, int d_h)
|
||||
{
|
||||
struct MPOpts *opts = vo->opts;
|
||||
|
||||
int scr_w = opts->vo_screenwidth;
|
||||
int scr_h = opts->vo_screenheight;
|
||||
|
||||
int vid_w = vo->aspdat.orgw;
|
||||
int vid_h = vo->aspdat.orgh;
|
||||
|
||||
@ -400,10 +429,12 @@ static void determine_window_geometry(struct vo *vo, int d_w, int d_h)
|
||||
}
|
||||
}
|
||||
|
||||
apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->vo_autofit, true);
|
||||
apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->vo_autofit_larger, false);
|
||||
|
||||
vo->dx = (int)(opts->vo_screenwidth - d_w) / 2;
|
||||
vo->dy = (int)(opts->vo_screenheight - d_h) / 2;
|
||||
m_geometry_apply(&vo->dx, &vo->dy, &d_w, &d_h,
|
||||
opts->vo_screenwidth, opts->vo_screenheight,
|
||||
m_geometry_apply(&vo->dx, &vo->dy, &d_w, &d_h, scr_w, scr_h,
|
||||
&opts->vo_geometry);
|
||||
|
||||
vo->dx += xinerama_x;
|
||||
|
Loading…
Reference in New Issue
Block a user