summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst24
-rw-r--r--options/options.c4
-rw-r--r--options/options.h2
-rw-r--r--video/out/aspect.c48
4 files changed, 73 insertions, 5 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index c70b26aa2c..79a2287467 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -1261,6 +1261,30 @@ Video
This option is disabled if the ``--no-keepaspect`` option is used.
+``--video-margin-ratio-left=<val>``, ``--video-margin-ratio-right=<val>``, ``--video-margin-ratio-top=<val>``, ``--video-margin-ratio-bottom=<val>``
+ 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
+ ``--video-margin-ratio-right=0.2`` at a window size of 1000 pixels will add
+ a 200 pixels border on the right side of the window.
+
+ The video is "boxed" by these margins. The window size is not changed. In
+ particular it does not enlarge the window, and the margins will cause the
+ video to be downscaled by default. This may or may not change in the future.
+
+ The margins are applied after 90° video rotation, but before any other video
+ transformations.
+
+ This option is disabled if the ``--no-keepaspect`` option is used.
+
+ Subtitles still may use the margins, depending on ``--sub-use-margins`` and
+ similar options.
+
+ These options were created for the OSC. Some odd decisions, such as making
+ the margin values a ratio (instead of pixels), were made for the sake of
+ the OSC. It's possible that these options may be replaced by ones that are
+ more generally useful. The behavior of these options may change to fit
+ OSC requirements better, too.
+
``--correct-pts``, ``--no-correct-pts``
``--no-correct-pts`` switches mpv to a mode where video timing is
determined using a fixed framerate value (either using the ``--fps``
diff --git a/options/options.c b/options/options.c
index a4d04c68f7..c5812f93f8 100644
--- a/options/options.c
+++ b/options/options.c
@@ -130,6 +130,10 @@ static const m_option_t mp_vo_opt_list[] = {
OPT_FLOATRANGE("video-pan-y", pan_y, 0, -3.0, 3.0),
OPT_FLOATRANGE("video-align-x", align_x, 0, -1.0, 1.0),
OPT_FLOATRANGE("video-align-y", align_y, 0, -1.0, 1.0),
+ OPT_FLOATRANGE("video-margin-ratio-left", margin_x[0], 0, 0.0, 1.0),
+ OPT_FLOATRANGE("video-margin-ratio-right", margin_x[1], 0, 0.0, 1.0),
+ OPT_FLOATRANGE("video-margin-ratio-top", margin_y[0], 0, 0.0, 1.0),
+ OPT_FLOATRANGE("video-margin-ratio-bottom", margin_y[1], 0, 0.0, 1.0),
OPT_CHOICE("video-unscaled", unscaled, 0,
({"no", 0}, {"yes", 1}, {"downscale-big", 2})),
OPT_INT64("wid", WinID, 0),
diff --git a/options/options.h b/options/options.h
index 182b901cd4..1f78dd9303 100644
--- a/options/options.h
+++ b/options/options.h
@@ -29,6 +29,8 @@ typedef struct mp_vo_opts {
float zoom;
float pan_x, pan_y;
float align_x, align_y;
+ float margin_x[2];
+ float margin_y[2];
int unscaled;
struct m_geometry geometry;
diff --git a/video/out/aspect.c b/video/out/aspect.c
index 896fa4980f..dc13d4e447 100644
--- a/video/out/aspect.c
+++ b/video/out/aspect.c
@@ -113,6 +113,18 @@ static void src_dst_split_scaling(int src_size, int dst_size,
*osd_margin_b = dst_size - *dst_end;
}
+static void calc_margin(float opts[2], int out[2], int size)
+{
+ out[0] = MPCLAMP((int)(opts[0] * size), 0, size);
+ out[1] = MPCLAMP((int)(opts[1] * size), 0, size);
+
+ if (out[0] + out[1] >= size) {
+ // This case is not really supported. Show an error by 1 pixel.
+ out[0] = 0;
+ out[1] = MPMAX(0, size - 1);
+ }
+}
+
void mp_get_src_dst_rects(struct mp_log *log, struct mp_vo_opts *opts,
int vo_caps, struct mp_image_params *video,
int window_w, int window_h, double monitor_par,
@@ -123,6 +135,7 @@ void mp_get_src_dst_rects(struct mp_log *log, struct mp_vo_opts *opts,
int src_w = video->w;
int src_h = video->h;
int src_dw, src_dh;
+
mp_image_params_get_dsize(video, &src_dw, &src_dh);
if (video->rotate % 180 == 90 && (vo_caps & VO_CAP_ROTATE90)) {
MPSWAP(int, src_w, src_h);
@@ -130,6 +143,17 @@ void mp_get_src_dst_rects(struct mp_log *log, struct mp_vo_opts *opts,
}
window_w = MPMAX(1, window_w);
window_h = MPMAX(1, window_h);
+
+ int margin_x[2] = {0};
+ int margin_y[2] = {0};
+ if (opts->keepaspect) {
+ calc_margin(opts->margin_x, margin_x, window_w);
+ calc_margin(opts->margin_y, margin_y, window_h);
+ }
+
+ int vid_window_w = window_w - margin_x[0] - margin_x[1];
+ int vid_window_h = window_h - margin_y[0] - margin_y[1];
+
struct mp_rect dst = {0, 0, window_w, window_h};
struct mp_rect src = {0, 0, src_w, src_h};
struct mp_osd_res osd = {
@@ -137,21 +161,34 @@ void mp_get_src_dst_rects(struct mp_log *log, struct mp_vo_opts *opts,
.h = window_h,
.display_par = monitor_par,
};
+
if (opts->keepaspect) {
int scaled_width, scaled_height;
aspect_calc_panscan(opts, src_w, src_h, src_dw, src_dh, opts->unscaled,
- window_w, window_h, monitor_par,
+ vid_window_w, vid_window_h, monitor_par,
&scaled_width, &scaled_height);
- src_dst_split_scaling(src_w, window_w, scaled_width,
+ src_dst_split_scaling(src_w, vid_window_w, scaled_width,
opts->zoom, opts->align_x, opts->pan_x,
&src.x0, &src.x1, &dst.x0, &dst.x1,
&osd.ml, &osd.mr);
- src_dst_split_scaling(src_h, window_h, scaled_height,
+ src_dst_split_scaling(src_h, vid_window_h, scaled_height,
opts->zoom, opts->align_y, opts->pan_y,
&src.y0, &src.y1, &dst.y0, &dst.y1,
&osd.mt, &osd.mb);
}
+ dst.x0 += margin_x[0];
+ dst.y0 += margin_y[0];
+ dst.x1 += margin_x[0];
+ dst.y1 += margin_y[0];
+
+ // OSD really uses the full window, but was computed on the margin-cut
+ // video sub-window. Correct it to the full window.
+ osd.ml += margin_x[0];
+ osd.mr += margin_x[1];
+ osd.mt += margin_y[0];
+ osd.mb += margin_y[1];
+
*out_src = src;
*out_dst = dst;
*out_osd = osd;
@@ -159,8 +196,9 @@ void mp_get_src_dst_rects(struct mp_log *log, struct mp_vo_opts *opts,
int sw = src.x1 - src.x0, sh = src.y1 - src.y0;
int dw = dst.x1 - dst.x0, dh = dst.y1 - dst.y0;
- mp_verbose(log, "Window size: %dx%d\n",
- window_w, window_h);
+ mp_verbose(log, "Window size: %dx%d (Borders: l=%d t=%d r=%d b=%d)\n",
+ window_w, window_h,
+ margin_x[0], margin_y[0], margin_x[1], margin_y[1]);
mp_verbose(log, "Video source: %dx%d (%d:%d)\n",
video->w, video->h, video->p_w, video->p_h);
mp_verbose(log, "Video display: (%d, %d) %dx%d -> (%d, %d) %dx%d\n",