summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-06-15 17:53:59 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:05 +0200
commit0b4790f23f045ada592be14f4cd1ceaa7ae47008 (patch)
treea2b0b0e6a1e09c794a58928f246e892238edbef6
parente1c8069b686bf67d0c2aa6a1527d5b244e170a18 (diff)
downloadmpv-0b4790f23f045ada592be14f4cd1ceaa7ae47008.tar.bz2
mpv-0b4790f23f045ada592be14f4cd1ceaa7ae47008.tar.xz
aspect: add video margin options
Semantics a bit questionable. This is done for the OSC (next commit), and a comment added the manpage explicitly states this. Meaning this is probably garbage and needs to revisit when the OSC changes and/or someone wants to use this margin feature for something else. Not sure about the subtitle thing. It's imaginable that someone uses these options to create empty borders for subtitles on the bottom, so subtitles should be located there. On the other hand, this gives a rather unpolished user experience when using the (later added) OSC feature to not overlap with the video. There's not much of a point if the OSC still overlaps the video. However, I'm too lazy to think about this, so it stays like it is.
-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",