summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-01-22 13:28:31 +0100
committerwm4 <wm4@nowhere>2013-01-23 10:55:00 +0100
commitf2dcdca0c2dc5f904323659b65b29a2b6f00fd88 (patch)
tree0ae1f6d9f1ef82e34795965327bb8ab076eb7b2c /video
parentc9396c0aabb6c1b710e1cdaa3fb123182dc91279 (diff)
downloadmpv-f2dcdca0c2dc5f904323659b65b29a2b6f00fd88.tar.bz2
mpv-f2dcdca0c2dc5f904323659b65b29a2b6f00fd88.tar.xz
video: move handling of -x/-y/-xy options to VO
Now the calculations of the final display size are done after the filter chain. This makes the difference between display aspect ratio and window size a bit more clear, especially in the -xy case. With an empty filter chain, the behavior of the options should be the same, except that they don't affect vo_image and vo_lavc anymore.
Diffstat (limited to 'video')
-rw-r--r--video/decode/vd.c71
-rw-r--r--video/filter/vf.c14
-rw-r--r--video/filter/vf.h4
-rw-r--r--video/filter/vf_crop.c2
-rw-r--r--video/filter/vf_expand.c2
-rw-r--r--video/filter/vf_mirror.c2
-rw-r--r--video/filter/vf_rotate.c2
-rw-r--r--video/filter/vf_scale.c4
-rw-r--r--video/filter/vf_stereo3d.c8
-rw-r--r--video/filter/vf_sub.c2
-rw-r--r--video/out/vo.c71
11 files changed, 94 insertions, 88 deletions
diff --git a/video/decode/vd.c b/video/decode/vd.c
index 7cdd25f55a..a9c0d21821 100644
--- a/video/decode/vd.c
+++ b/video/decode/vd.c
@@ -55,8 +55,6 @@ const vd_functions_t * const mpcodecs_vd_drivers[] = {
int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
{
struct MPOpts *opts = sh->opts;
- int screen_size_x = 0;
- int screen_size_y = 0;
vf_instance_t *vf = sh->vfilter;
int vocfg_flags = 0;
@@ -130,53 +128,25 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
else if (sh->stream_aspect != 0.0)
sh->aspect = sh->stream_aspect;
- if (opts->screen_size_x || opts->screen_size_y) {
- screen_size_x = opts->screen_size_x;
- screen_size_y = opts->screen_size_y;
- if (!opts->vidmode) {
- if (!screen_size_x)
- screen_size_x = 1;
- if (!screen_size_y)
- screen_size_y = 1;
- if (screen_size_x <= 8)
- screen_size_x *= sh->disp_w;
- if (screen_size_y <= 8)
- screen_size_y *= sh->disp_h;
- }
- } else {
- // check source format aspect, calculate prescale ::atmos
- screen_size_x = sh->disp_w;
- screen_size_y = sh->disp_h;
- if (opts->screen_size_xy >= 0.001) {
- if (opts->screen_size_xy <= 8) {
- // -xy means x+y scale
- screen_size_x *= opts->screen_size_xy;
- screen_size_y *= opts->screen_size_xy;
- } else {
- // -xy means forced width while keeping correct aspect
- screen_size_x = opts->screen_size_xy;
- screen_size_y = opts->screen_size_xy * sh->disp_h / sh->disp_w;
- }
+ int d_w = sh->disp_w;
+ int d_h = sh->disp_h;
+
+ if (sh->aspect > 0.01) {
+ int new_w = d_h * sh->aspect;
+ int new_h = d_h;
+ // we don't like horizontal downscale
+ if (new_w < d_w) {
+ new_w = d_w;
+ new_h = d_w / sh->aspect;
}
- if (sh->aspect > 0.01) {
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n",
- sh->aspect);
- int w = screen_size_y * sh->aspect;
- int h = screen_size_y;
- // we don't like horizontal downscale || user forced width:
- if (w < screen_size_x || opts->screen_size_xy > 8) {
- w = screen_size_x;
- h = screen_size_x / sh->aspect;
- }
- if (abs(screen_size_x - w) >= 4 || abs(screen_size_y - h) >= 4) {
- screen_size_x = w;
- screen_size_y = h;
- mp_tmsg(MSGT_CPLAYER, MSGL_V, "Aspect ratio is %.2f:1 - "
- "scaling to correct movie aspect.\n", sh->aspect);
- }
- } else {
- mp_tmsg(MSGT_CPLAYER, MSGL_V, "Movie-Aspect is undefined - no prescaling applied.\n");
+ if (abs(d_w - new_w) >= 4 || abs(d_h - new_h) >= 4) {
+ d_w = new_w;
+ d_h = new_h;
+ mp_tmsg(MSGT_CPLAYER, MSGL_V, "Aspect ratio is %.2f:1 - "
+ "scaling to correct movie aspect.\n", sh->aspect);
}
+
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ASPECT=%1.4f\n", sh->aspect);
}
vocfg_flags = (opts->fullscreen ? VOFLAG_FULLSCREEN : 0)
@@ -186,11 +156,10 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int out_fmt)
// Time to config libvo!
mp_msg(MSGT_CPLAYER, MSGL_V,
"VO Config (%dx%d->%dx%d,flags=%d,0x%X)\n", sh->disp_w,
- sh->disp_h, screen_size_x, screen_size_y, vocfg_flags, out_fmt);
+ sh->disp_h, d_w, d_h, vocfg_flags, out_fmt);
- if (vf_config_wrapper
- (vf, sh->disp_w, sh->disp_h, screen_size_x, screen_size_y, vocfg_flags,
- out_fmt) == 0) {
+ if (vf_config_wrapper(vf, sh->disp_w, sh->disp_h, d_w, d_h, vocfg_flags,
+ out_fmt) == 0) {
mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "FATAL: Cannot initialize video driver.\n");
sh->vf_initialized = -1;
return 0;
diff --git a/video/filter/vf.c b/video/filter/vf.c
index a4b78ab5ab..5b466031c7 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -514,16 +514,12 @@ void vf_uninit_filter_chain(vf_instance_t *vf)
}
}
-// When cropping an image that had old_w/old_h/*d_width/*d_height to the new
-// size new_w/new_h, adjust *d_width/*d_height such that the new image has
-// the same pixel aspect ratio.
-void vf_rescale_dsize(struct vf_instance *vf, int *d_width, int *d_height,
- int old_w, int old_h, int new_w, int new_h)
+// When changing the size of an image that had old_w/old_h with
+// DAR *d_width/*d_height to the new size new_w/new_h, adjust
+// *d_width/*d_height such that the new image has the same pixel aspect ratio.
+void vf_rescale_dsize(int *d_width, int *d_height, int old_w, int old_h,
+ int new_w, int new_h)
{
- // No idea what this is about
- if (vf->opts->screen_size_x || vf->opts->screen_size_y)
- return;
-
*d_width = *d_width * new_w / old_w;
*d_height = *d_height * new_h / old_h;
}
diff --git a/video/filter/vf.h b/video/filter/vf.h
index 4398abebc7..44b820c04a 100644
--- a/video/filter/vf.h
+++ b/video/filter/vf.h
@@ -144,8 +144,8 @@ int vf_config_wrapper(struct vf_instance *vf,
unsigned int flags, unsigned int outfmt);
void vf_print_filter_chain(int msglevel, struct vf_instance *vf);
-void vf_rescale_dsize(struct vf_instance *vf, int *d_width, int *d_height,
- int old_w, int old_h, int new_w, int new_h);
+void vf_rescale_dsize(int *d_width, int *d_height, int old_w, int old_h,
+ int new_w, int new_h);
static inline int norm_qscale(int qscale, int type)
{
diff --git a/video/filter/vf_crop.c b/video/filter/vf_crop.c
index 6ef0d8d0c1..49b4e7e55b 100644
--- a/video/filter/vf_crop.c
+++ b/video/filter/vf_crop.c
@@ -63,7 +63,7 @@ static int config(struct vf_instance *vf,
mp_tmsg(MSGT_VFILTER, MSGL_WARN, "[CROP] Bad position/width/height - cropped area outside of the original!\n");
return 0;
}
- vf_rescale_dsize(vf, &d_width, &d_height, width, height,
+ vf_rescale_dsize(&d_width, &d_height, width, height,
vf->priv->crop_w, vf->priv->crop_h);
return vf_next_config(vf,vf->priv->crop_w,vf->priv->crop_h,d_width,d_height,flags,outfmt);
}
diff --git a/video/filter/vf_expand.c b/video/filter/vf_expand.c
index ff84d7670c..efe3f9dbb3 100644
--- a/video/filter/vf_expand.c
+++ b/video/filter/vf_expand.c
@@ -101,7 +101,7 @@ static int config(struct vf_instance *vf,
vf->priv->exp_x = MP_ALIGN_DOWN(vf->priv->exp_x, fmt.align_x);
vf->priv->exp_y = MP_ALIGN_DOWN(vf->priv->exp_y, fmt.align_y);
- vf_rescale_dsize(vf, &d_width, &d_height, width, height,
+ vf_rescale_dsize(&d_width, &d_height, width, height,
vf->priv->exp_w, vf->priv->exp_h);
return vf_next_config(vf,vf->priv->exp_w,vf->priv->exp_h,d_width,d_height,flags,outfmt);
diff --git a/video/filter/vf_mirror.c b/video/filter/vf_mirror.c
index 301583594f..65e467a9cb 100644
--- a/video/filter/vf_mirror.c
+++ b/video/filter/vf_mirror.c
@@ -34,7 +34,7 @@ static int config(struct vf_instance *vf, int width, int height,
{
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
int a_w = MP_ALIGN_DOWN(width, desc.align_x);
- vf_rescale_dsize(vf, &d_width, &d_height, width, height, a_w, height);
+ vf_rescale_dsize(&d_width, &d_height, width, height, a_w, height);
return vf_next_config(vf, a_w, height, d_width, d_height, flags, fmt);
}
diff --git a/video/filter/vf_rotate.c b/video/filter/vf_rotate.c
index 1d80725ba3..9cdbafd94d 100644
--- a/video/filter/vf_rotate.c
+++ b/video/filter/vf_rotate.c
@@ -77,7 +77,7 @@ static int config(struct vf_instance *vf, int width, int height,
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(outfmt);
int a_w = MP_ALIGN_DOWN(width, desc.align_x);
int a_h = MP_ALIGN_DOWN(height, desc.align_y);
- vf_rescale_dsize(vf, &d_width, &d_height, width, height, a_w, a_h);
+ vf_rescale_dsize(&d_width, &d_height, width, height, a_w, a_h);
return vf_next_config(vf, a_h, a_w, d_height, d_width, flags, outfmt);
}
diff --git a/video/filter/vf_scale.c b/video/filter/vf_scale.c
index ca06436dd5..a81ed8c0cd 100644
--- a/video/filter/vf_scale.c
+++ b/video/filter/vf_scale.c
@@ -303,9 +303,6 @@ static int config(struct vf_instance *vf,
return 0;
}
vf->priv->fmt=best;
-
- if (!opts->screen_size_x && !opts->screen_size_y
- && !(opts->screen_size_xy >= 0.001)) {
// Compute new d_width and d_height, preserving aspect
// while ensuring that both are >= output size in pixels.
if (vf->priv->h * d_width > vf->priv->w * d_height) {
@@ -317,7 +314,6 @@ static int config(struct vf_instance *vf,
}
//d_width=d_width*vf->priv->w/width;
//d_height=d_height*vf->priv->h/height;
- }
return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,best);
}
diff --git a/video/filter/vf_stereo3d.c b/video/filter/vf_stereo3d.c
index 3e055b22ea..37c66e77d9 100644
--- a/video/filter/vf_stereo3d.c
+++ b/video/filter/vf_stereo3d.c
@@ -148,8 +148,6 @@ static inline uint8_t ana_convert(int coeff[6], uint8_t left[3], uint8_t right[3
static int config(struct vf_instance *vf, int width, int height, int d_width,
int d_height, unsigned int flags, unsigned int outfmt)
{
- struct MPOpts *opts = vf->opts;
-
if ((width & 1) || (height & 1)) {
mp_msg(MSGT_VFILTER, MSGL_WARN, "[stereo3d] invalid height or width\n");
return 0;
@@ -271,10 +269,8 @@ static int config(struct vf_instance *vf, int width, int height, int d_width,
return 0;
break;
}
- if (!opts->screen_size_x && !opts->screen_size_y) {
- d_width = d_width * vf->priv->out.width / width;
- d_height = d_height * vf->priv->out.height / height;
- }
+ vf_rescale_dsize(&d_width, &d_height, width, height,
+ vf->priv->out.width, vf->priv->out.height);
return vf_next_config(vf, vf->priv->out.width, vf->priv->out.height,
d_width, d_height, flags, outfmt);
}
diff --git a/video/filter/vf_sub.c b/video/filter/vf_sub.c
index 49214685ef..a1f25efd6d 100644
--- a/video/filter/vf_sub.c
+++ b/video/filter/vf_sub.c
@@ -68,7 +68,7 @@ static int config(struct vf_instance *vf,
double dar = (double)d_width / d_height;
double sar = (double)width / height;
- vf_rescale_dsize(vf, &d_width, &d_height, width, height,
+ vf_rescale_dsize(&d_width, &d_height, width, height,
vf->priv->outw, vf->priv->outh);
vf->priv->dim = (struct mp_osd_res) {
diff --git a/video/out/vo.c b/video/out/vo.c
index 9a75ccb789..9163367eb9 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -356,6 +356,63 @@ struct vo *init_best_video_out(struct MPOpts *opts,
return NULL;
}
+// Set window size (vo->dwidth/dheight) and position (vo->dx/dy) according to
+// the video display size d_w/d_h.
+// NOTE: currently, all GUI backends do their own handling of window geometry
+// additional to this code. This is to deal with initial window placement,
+// fullscreen handling, avoiding resize on config() with no size change,
+// multi-monitor stuff, and possibly more.
+static void determine_window_geometry(struct vo *vo, int d_w, int d_h)
+{
+ struct MPOpts *opts = vo->opts;
+
+ int vid_w = vo->aspdat.orgw;
+ int vid_h = vo->aspdat.orgh;
+
+ if (opts->screen_size_x || opts->screen_size_y) {
+ d_w = opts->screen_size_x;
+ d_h = opts->screen_size_y;
+ if (!opts->vidmode) {
+ if (!d_w)
+ d_w = 1;
+ if (!d_h)
+ d_h = 1;
+ if (d_w <= 8)
+ d_w *= vid_w;
+ if (d_h <= 8)
+ d_h *= vid_h;
+ }
+ }
+
+ // This is only for applying monitor pixel aspect
+ // Store d_w/d_h, because aspect() uses it
+ aspect_save_videores(vo, vid_w, vid_h, d_w, d_h);
+ aspect(vo, &d_w, &d_h, A_NOZOOM);
+
+ if (opts->screen_size_xy >= 0.001) {
+ if (opts->screen_size_xy <= 8) {
+ // -xy means x+y scale
+ d_w *= opts->screen_size_xy;
+ d_h *= opts->screen_size_xy;
+ } else {
+ // -xy means forced width while keeping correct aspect
+ d_h = opts->screen_size_xy * d_h / d_w;
+ d_w = opts->screen_size_xy;
+ }
+ }
+
+ vo->dx = (int)(opts->vo_screenwidth - d_w) / 2;
+ vo->dy = (int)(opts->vo_screenheight - d_h) / 2;
+ geometry(&vo->dx, &vo->dy, &d_w, &d_h,
+ opts->vo_screenwidth, opts->vo_screenheight);
+ geometry_xy_changed |= xinerama_screen >= 0;
+
+ vo->dx += xinerama_x;
+ vo->dy += xinerama_y;
+ vo->dwidth = d_w;
+ vo->dheight = d_h;
+}
+
static int event_fd_callback(void *ctx, int fd)
{
struct vo *vo = ctx;
@@ -367,21 +424,13 @@ int vo_config(struct vo *vo, uint32_t width, uint32_t height,
uint32_t d_width, uint32_t d_height, uint32_t flags,
uint32_t format)
{
- struct MPOpts *opts = vo->opts;
panscan_init(vo);
aspect_save_videores(vo, width, height, d_width, d_height);
if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
- aspect(vo, &d_width, &d_height, A_NOZOOM);
- vo->dx = (int)(opts->vo_screenwidth - d_width) / 2;
- vo->dy = (int)(opts->vo_screenheight - d_height) / 2;
- geometry(&vo->dx, &vo->dy, &d_width, &d_height,
- opts->vo_screenwidth, opts->vo_screenheight);
- geometry_xy_changed |= xinerama_screen >= 0;
- vo->dx += xinerama_x;
- vo->dy += xinerama_y;
- vo->dwidth = d_width;
- vo->dheight = d_height;
+ determine_window_geometry(vo, d_width, d_height);
+ d_width = vo->dwidth;
+ d_height = vo->dheight;
}
vo->default_caps = vo->driver->query_format(vo, format);