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.)
This commit is contained in:
wm4 2013-06-15 00:15:32 +02:00
parent 67704e2977
commit 216e8320b0
6 changed files with 62 additions and 5 deletions

View File

@ -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``

View File

@ -2458,6 +2458,39 @@
``--vid=<ID|auto|no>``
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=<value>``, ``--video-pan-y=<value>``
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=<value>``
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=<driver1[:suboption1[=value]:...],driver2,...[,]>``
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

View File

@ -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,

View File

@ -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},

View File

@ -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;

View File

@ -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);
}