summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/options.rst48
-rw-r--r--core/cfg-mplayer.h2
-rw-r--r--core/m_option.c27
-rw-r--r--core/m_option.h3
-rw-r--r--core/options.h2
-rw-r--r--etc/example.conf3
-rw-r--r--video/out/vo.c35
7 files changed, 118 insertions, 2 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index fb3a96307d..a0995db964 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -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.
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index 5264784a56..54fa3f3ab5 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -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),
diff --git a/core/m_option.c b/core/m_option.c
index a55e87a5d3..c1d2ee4fbe 100644
--- a/core/m_option.c
+++ b/core/m_option.c
@@ -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"
diff --git a/core/m_option.h b/core/m_option.h
index 87fa959992..81ab73e98b 100644
--- a/core/m_option.h
+++ b/core/m_option.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}))
diff --git a/core/options.h b/core/options.h
index 10932a4edf..3cd0132847 100644
--- a/core/options.h
+++ b/core/options.h
@@ -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;
diff --git a/etc/example.conf b/etc/example.conf
index bb37a5e26d..e610b81b4f 100644
--- a/etc/example.conf
+++ b/etc/example.conf
@@ -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
diff --git a/video/out/vo.c b/video/out/vo.c
index 29307b7218..484aa20a56 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -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;