diff options
-rw-r--r-- | DOCS/man/options.rst | 24 | ||||
-rw-r--r-- | options/options.c | 4 | ||||
-rw-r--r-- | options/options.h | 2 | ||||
-rw-r--r-- | video/out/aspect.c | 48 |
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", |