From 216e8320b02e76a407b114ca4de73763e9df3507 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 15 Jun 2013 00:15:32 +0200 Subject: [PATCH] video: make it possible to scale/pan the video by arbitrary amounts Add --video-align-x/y, --video-pan-x/y, --video-scale options and properties. See the additions to the manpage for description and semantics. These transformations are intentionally done on top of panscan. Unlike the (now removed) --panscanrange option, this doesn't affect the default panscan behavior. (Although panscan itself becomes kind of useless if the new options are used.) --- DOCS/man/en/input.rst | 5 +++++ DOCS/man/en/options.rst | 33 +++++++++++++++++++++++++++++++++ mpvcore/command.c | 13 +++++++++---- mpvcore/options.c | 5 +++++ mpvcore/options.h | 3 +++ video/out/vo.c | 8 +++++++- 6 files changed, 62 insertions(+), 5 deletions(-) diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst index ae887a2080b88..bacb99c14b10f 100644 --- a/DOCS/man/en/input.rst +++ b/DOCS/man/en/input.rst @@ -452,6 +452,11 @@ Name W Comment ``aspect`` x video aspect ``vid`` x current video track (similar to ``--vid``) ``video`` x alias for ``vid`` +``video-align-x`` x see ``--video-align-x`` +``video-align-y`` x see ``--video-align-y`` +``video-pan-x`` x see ``--video-pan-x`` +``video-pan-y`` x see ``--video-pan-y`` +``video-zoom`` x see ``--video-zoom`` ``program`` x switch TS program (write-only) ``sid`` x current subtitle track (similar to ``--sid``) ``sub`` x alias for ``sid`` diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index 210f89381bdb4..4174e1f0d60d2 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -2458,6 +2458,39 @@ ``--vid=`` Select video channel. ``auto`` selects the default, ``no`` disables video. +``--video-align-x=<-1-1>``, ``--video-align-y=<-1-1>`` + Moves the video rectangle within the black borders, which are usually added + to pad the video to screen if video and screen aspect ratios are different. + ``--video-align-y=-1`` would move the video to the top of the screen + (leaving a border only on the bottom), a value of ``0`` centers it + (default), and a value of ``-1`` would put the video at the bottom of the + screen. + + If video and screen aspect match perfectly, these options do nothing. + + This option is disabled if the ``--no-keepaspect`` option is used. + +``--video-pan-x=``, ``--video-pan-y=`` + Moves the displayed video rectangle by the given value in the X or Y + direction. The unit is in fractions of the size of the scaled video (the + full size, even if parts of the video are not visible due to panscan or + other options). + + For example, displaying a 1280x720 video fullscreen on a 1680x1050 screen + with ``--video-pan-x=-0.1`` would move the video 168 pixels to the left + (making 128 pixels of the source video invisible). + + This option is disabled if the ``--no-keepaspect`` option is used. + +``--video-zoom=`` + Adjust the video display scale factor by the given value. The unit is in + fractions of original video size. + + For example, given a 1280x720 video, ``--video-zoom=-0.1`` would make the + video by 128 pixels smaller in X direction, and 72 pixels in Y direction. + + This option is disabled if the ``--no-keepaspect`` option is used. + ``--vo=`` Specify a priority list of video output drivers to be used. For interactive use, one would normally specify a single one to use, but in diff --git a/mpvcore/command.c b/mpvcore/command.c index b7aa9dfe6a776..ae3f97a5bccb9 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -1253,9 +1253,9 @@ static int mp_property_colormatrix_output_range(m_option_t *prop, int action, return M_PROPERTY_OK; } -/// Panscan (RW) -static int mp_property_panscan(m_option_t *prop, int action, void *arg, - MPContext *mpctx) +// Update options which are managed through VOCTRL_GET/SET_PANSCAN. +static int panscan_property_helper(m_option_t *prop, int action, void *arg, + MPContext *mpctx) { if (!mpctx->video_out @@ -1809,7 +1809,12 @@ static const m_option_t mp_properties[] = { .offset = offsetof(struct MPOpts, gamma_saturation)), M_OPTION_PROPERTY_CUSTOM_("hue", mp_property_gamma, .offset = offsetof(struct MPOpts, gamma_hue)), - M_OPTION_PROPERTY_CUSTOM("panscan", mp_property_panscan), + M_OPTION_PROPERTY_CUSTOM("panscan", panscan_property_helper), + M_OPTION_PROPERTY_CUSTOM("video-zoom", panscan_property_helper), + M_OPTION_PROPERTY_CUSTOM("video-align-x", panscan_property_helper), + M_OPTION_PROPERTY_CUSTOM("video-align-y", panscan_property_helper), + M_OPTION_PROPERTY_CUSTOM("video-pan-x", panscan_property_helper), + M_OPTION_PROPERTY_CUSTOM("video-pan-y", panscan_property_helper), { "video-format", mp_property_video_format, CONF_TYPE_STRING, 0, 0, 0, NULL }, { "video-codec", mp_property_video_codec, CONF_TYPE_STRING, diff --git a/mpvcore/options.c b/mpvcore/options.c index 5600ccee71cf3..5aff219c14424 100644 --- a/mpvcore/options.c +++ b/mpvcore/options.c @@ -581,6 +581,11 @@ const m_option_t mp_opts[] = { OPT_INTRANGE("fsmode-dontuse", vo.fsmode, 0, 31, 4096), OPT_FLAG("native-keyrepeat", vo.native_keyrepeat, 0), OPT_FLOATRANGE("panscan", vo.panscan, 0, 0.0, 1.0), + OPT_FLOATRANGE("video-zoom", vo.zoom, 0, -20.0, 20.0), + OPT_FLOATRANGE("video-pan-x", vo.pan_x, 0, -3.0, 3.0), + OPT_FLOATRANGE("video-pan-y", vo.pan_y, 0, -3.0, 3.0), + OPT_FLOATRANGE("video-align-x", vo.align_x, 0, -1.0, 1.0), + OPT_FLOATRANGE("video-align-y", vo.align_y, 0, -1.0, 1.0), OPT_FLAG("force-rgba-osd-rendering", force_rgba_osd, 0), OPT_CHOICE("colormatrix", requested_colorspace, 0, ({"auto", MP_CSP_AUTO}, diff --git a/mpvcore/options.h b/mpvcore/options.h index 2ab9e517a0d27..1ff50688cec5e 100644 --- a/mpvcore/options.h +++ b/mpvcore/options.h @@ -19,6 +19,9 @@ typedef struct mp_vo_opts { int native_keyrepeat; float panscan; + float zoom; + float pan_x, pan_y; + float align_x, align_y; struct m_geometry geometry; struct m_geometry autofit; diff --git a/video/out/vo.c b/video/out/vo.c index be1ba84a1268f..1237ae0a23315 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -488,13 +488,17 @@ static void clamp_size(int size, int *start, int *end) static void src_dst_split_scaling(int src_size, int dst_size, int scaled_src_size, + float zoom, float align, float pan, int *src_start, int *src_end, int *dst_start, int *dst_end, int *osd_margin_a, int *osd_margin_b) { + scaled_src_size += zoom * src_size; + align = (align + 1) / 2; + *src_start = 0; *src_end = src_size; - *dst_start = (dst_size - scaled_src_size) / 2; + *dst_start = (dst_size - scaled_src_size) * align + pan * scaled_src_size; *dst_end = *dst_start + scaled_src_size; // Distance of screen frame to video @@ -543,9 +547,11 @@ void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src, int scaled_width, scaled_height; aspect_calc_panscan(vo, &scaled_width, &scaled_height); src_dst_split_scaling(src_w, vo->dwidth, 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, vo->dheight, scaled_height, + opts->zoom, opts->align_y, opts->pan_y, &src.y0, &src.y1, &dst.y0, &dst.y1, &osd.mt, &osd.mb); }