mirror of
https://github.com/mpv-player/mpv
synced 2024-10-26 07:22:17 +02: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
|
Enables caching for the stream used by ``--audiofile``, using the
|
||||||
specified amount of memory.
|
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
|
--autosub, --no-autosub
|
||||||
Load additional subtitle files matching the video filename. Enabled by
|
Load additional subtitle files matching the video filename. Enabled by
|
||||||
default. See also ``--autosub-match``.
|
default. See also ``--autosub-match``.
|
||||||
@ -718,6 +763,9 @@
|
|||||||
Sets the window to half the screen widths, and positions it 10 pixels
|
Sets the window to half the screen widths, and positions it 10 pixels
|
||||||
below/left of the top left corner of the screen.
|
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
|
--grabpointer, --no-grabpointer
|
||||||
``--no-grabpointer`` tells the player to not grab the mouse pointer after a
|
``--no-grabpointer`` tells the player to not grab the mouse pointer after a
|
||||||
video mode change (``--vm``). Useful for multihead setups.
|
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("screenw", vo_screenwidth, CONF_GLOBAL, 0, 4096),
|
||||||
OPT_INTRANGE("screenh", vo_screenheight, CONF_GLOBAL, 0, 4096),
|
OPT_INTRANGE("screenh", vo_screenheight, CONF_GLOBAL, 0, 4096),
|
||||||
OPT_GEOMETRY("geometry", vo_geometry, 0),
|
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),
|
OPT_MAKE_FLAGS("force-window-position", force_window_position, 0),
|
||||||
// vo name (X classname) and window title strings
|
// vo name (X classname) and window title strings
|
||||||
OPT_STRING("name", vo_winname, 0),
|
OPT_STRING("name", vo_winname, 0),
|
||||||
|
@ -1309,7 +1309,34 @@ const m_option_type_t m_option_type_geometry = {
|
|||||||
.parse = parse_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"
|
#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_afmt;
|
||||||
extern const m_option_type_t m_option_type_color;
|
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_geometry;
|
||||||
|
extern const m_option_type_t m_option_type_size_box;
|
||||||
|
|
||||||
// Callback used by m_option_type_print_func options.
|
// Callback used by m_option_type_print_func options.
|
||||||
typedef int (*m_opt_func_full_t)(const m_option_t *, const char *, const char *);
|
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_rel_time rel_time;
|
||||||
struct m_color color;
|
struct m_color color;
|
||||||
struct m_geometry geometry;
|
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_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_COLOR(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_color)
|
||||||
#define OPT_GEOMETRY(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_geometry)
|
#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}))
|
#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_screenwidth;
|
||||||
int vo_screenheight;
|
int vo_screenheight;
|
||||||
struct m_geometry vo_geometry;
|
struct m_geometry vo_geometry;
|
||||||
|
struct m_geometry vo_autofit;
|
||||||
|
struct m_geometry vo_autofit_larger;
|
||||||
int force_window_position;
|
int force_window_position;
|
||||||
char *vo_winname;
|
char *vo_winname;
|
||||||
char *vo_wintitle;
|
char *vo_wintitle;
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
# force starting with centered window
|
# force starting with centered window
|
||||||
#geometry=50%:50%
|
#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.
|
# Keep the player window on top of all other windows.
|
||||||
#ontop=yes
|
#ontop=yes
|
||||||
|
|
||||||
|
@ -355,6 +355,32 @@ struct vo *init_best_video_out(struct MPOpts *opts,
|
|||||||
return NULL;
|
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
|
// Set window size (vo->dwidth/dheight) and position (vo->dx/dy) according to
|
||||||
// the video display size d_w/d_h.
|
// the video display size d_w/d_h.
|
||||||
// NOTE: currently, all GUI backends do their own handling of window geometry
|
// 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;
|
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_w = vo->aspdat.orgw;
|
||||||
int vid_h = vo->aspdat.orgh;
|
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->dx = (int)(opts->vo_screenwidth - d_w) / 2;
|
||||||
vo->dy = (int)(opts->vo_screenheight - d_h) / 2;
|
vo->dy = (int)(opts->vo_screenheight - d_h) / 2;
|
||||||
m_geometry_apply(&vo->dx, &vo->dy, &d_w, &d_h,
|
m_geometry_apply(&vo->dx, &vo->dy, &d_w, &d_h, scr_w, scr_h,
|
||||||
opts->vo_screenwidth, opts->vo_screenheight,
|
|
||||||
&opts->vo_geometry);
|
&opts->vo_geometry);
|
||||||
|
|
||||||
vo->dx += xinerama_x;
|
vo->dx += xinerama_x;
|
||||||
|
Loading…
Reference in New Issue
Block a user