1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-23 16:36:56 +00:00

video: simplify aspect calculation stuff

Remove lots of weird logic and dead code.

The only difference is that when specifying a monitor aspect ratio, it
will always upscale and never downscale.
This commit is contained in:
wm4 2013-03-14 16:21:37 +01:00
parent 59960baa7f
commit 4b87cb39a3
4 changed files with 38 additions and 93 deletions

View File

@ -43,25 +43,33 @@ void aspect_save_screenres(struct vo *vo, int scrw, int scrh)
scrh = (scrw * 3 + 3) / 4;
if (scrw <= 0)
scrw = (scrh * 4 + 2) / 3;
vo->aspdat.scrw = scrw;
vo->aspdat.scrh = scrh;
if (opts->force_monitor_aspect)
vo->monitor_par = opts->force_monitor_aspect * scrh / scrw;
vo->aspdat.monitor_par = opts->force_monitor_aspect * scrh / scrw;
else
vo->monitor_par = 1.0 / opts->monitor_pixel_aspect;
vo->aspdat.monitor_par = 1.0 / opts->monitor_pixel_aspect;
}
/* aspect is called with the source resolution and the
* resolution, that the scaled image should fit into
*/
void aspect_calc_monitor(struct vo *vo, int *w, int *h)
{
float pixelaspect = vo->aspdat.monitor_par;
void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith)
if (pixelaspect < 1) {
*h /= pixelaspect;
} else {
*w *= pixelaspect;
}
}
static void aspect_calc(struct vo *vo, int *srcw, int *srch)
{
struct aspect_data *aspdat = &vo->aspdat;
float pixelaspect = vo->monitor_par;
float pixelaspect = aspdat->monitor_par;
int fitw = vo->dwidth;
int fith = vo->dheight;
mp_msg(MSGT_VO, MSGL_DBG2, "aspect(0) fitin: %dx%d monitor_par: %.2f\n",
fitw, fith, vo->monitor_par);
fitw, fith, aspdat->monitor_par);
*srcw = fitw;
*srch = (float)fitw / aspdat->prew * aspdat->preh / pixelaspect;
*srch += *srch % 2; // round
@ -83,65 +91,22 @@ void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith)
*srcw, *srch, aspdat->prew, aspdat->preh);
}
static void get_max_dims(struct vo *vo, int *w, int *h, int zoom)
void aspect_calc_panscan(struct vo *vo, int *out_w, int *out_h)
{
struct aspect_data *aspdat = &vo->aspdat;
*w = zoom ? aspdat->scrw : aspdat->prew;
*h = zoom ? aspdat->scrh : aspdat->preh;
if (zoom && vo->opts->WinID >= 0)
zoom = A_WINZOOM;
if (zoom == A_WINZOOM) {
*w = vo->dwidth;
*h = vo->dheight;
}
}
void aspect(struct vo *vo, int *srcw, int *srch, int zoom)
{
int fitw;
int fith;
get_max_dims(vo, &fitw, &fith, zoom);
if (!zoom && vo->opts->geometry.wh_valid) {
mp_msg(MSGT_VO, MSGL_DBG2, "aspect(0) no aspect forced!\n");
return; // the user doesn't want to fix aspect
}
aspect_fit(vo, srcw, srch, fitw, fith);
}
void panscan_init(struct vo *vo)
{
vo->panscan_x = 0;
vo->panscan_y = 0;
vo->panscan_amount = 0.0f;
}
static void panscan_calc_internal(struct vo *vo, int zoom)
{
int fwidth, fheight;
int vo_panscan_area;
int max_w, max_h;
get_max_dims(vo, &max_w, &max_h, zoom);
struct mp_vo_opts *opts = vo->opts;
int fwidth, fheight;
aspect_calc(vo, &fwidth, &fheight);
int vo_panscan_area;
if (opts->panscanrange > 0) {
aspect(vo, &fwidth, &fheight, zoom);
vo_panscan_area = max_h - fheight;
vo_panscan_area = vo->dheight - fheight;
if (!vo_panscan_area)
vo_panscan_area = max_w - fwidth;
vo_panscan_area = vo->dwidth - fwidth;
vo_panscan_area *= opts->panscanrange;
} else
vo_panscan_area = -opts->panscanrange * max_h;
vo_panscan_area = -opts->panscanrange * vo->dheight;
vo->panscan_amount = opts->fs || zoom == A_WINZOOM ? opts->panscan : 0;
vo->panscan_x = vo_panscan_area * vo->panscan_amount * vo->aspdat.asp;
vo->panscan_y = vo_panscan_area * vo->panscan_amount;
}
/**
* vos that set vo_dwidth and v_dheight correctly should call this to update
* vo_panscan_x and vo_panscan_y
*/
void panscan_calc_windowed(struct vo *vo)
{
panscan_calc_internal(vo, A_WINZOOM);
float panscan_amount = opts->fs ? opts->panscan : 0;
*out_w = fwidth + vo_panscan_area * panscan_amount * vo->aspdat.asp;
*out_h = fheight + vo_panscan_area * panscan_amount;
}

View File

@ -21,17 +21,11 @@
/* Stuff for correct aspect scaling. */
struct vo;
void panscan_init(struct vo *vo);
void panscan_calc_windowed(struct vo *vo);
void aspect_save_videores(struct vo *vo, int w, int h, int d_w, int d_h);
void aspect_save_screenres(struct vo *vo, int scrw, int scrh);
#define A_WINZOOM 2 ///< zoom to fill window size
#define A_ZOOM 1
#define A_NOZOOM 0
void aspect(struct vo *vo, int *srcw, int *srch, int zoom);
void aspect_fit(struct vo *vo, int *srcw, int *srch, int fitw, int fith);
void aspect_calc_monitor(struct vo *vo, int *w, int *h);
void aspect_calc_panscan(struct vo *vo, int *out_w, int *out_h);
#endif /* MPLAYER_ASPECT_H */

View File

@ -308,6 +308,7 @@ struct vo *init_best_video_out(struct mp_vo_opts *opts,
.input_ctx = input_ctx,
.event_fd = -1,
.registered_fd = -1,
.aspdat = { .monitor_par = 1 },
};
// first try the preferred drivers, with their optional subdevice param:
if (vo_list && vo_list[0])
@ -391,8 +392,7 @@ static void determine_window_geometry(struct vo *vo, int d_w, int d_h)
int scr_w = opts->screenwidth;
int scr_h = opts->screenheight;
// This is only for applying monitor pixel aspect
aspect(vo, &d_w, &d_h, A_NOZOOM);
aspect_calc_monitor(vo, &d_w, &d_h);
apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit, true);
apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit_larger, false);
@ -419,7 +419,6 @@ 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)
{
panscan_init(vo);
aspect_save_videores(vo, width, height, d_width, d_height);
if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
@ -514,15 +513,12 @@ void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src,
struct mp_osd_res osd = {
.w = vo->dwidth,
.h = vo->dheight,
.display_par = vo->monitor_par,
.display_par = vo->aspdat.monitor_par,
.video_par = vo->aspdat.par,
};
if (aspect_scaling(vo)) {
int scaled_width = 0, scaled_height = 0;
aspect(vo, &scaled_width, &scaled_height, A_WINZOOM);
panscan_calc_windowed(vo);
scaled_width += vo->panscan_x;
scaled_height += vo->panscan_y;
if (vo->opts->keepaspect || vo->opts->fs) {
int scaled_width, scaled_height;
aspect_calc_panscan(vo, &scaled_width, &scaled_height);
int border_w = vo->dwidth - scaled_width;
int border_h = vo->dheight - scaled_height;
osd.ml = border_w / 2;

View File

@ -264,19 +264,14 @@ struct vo {
int xinerama_x;
int xinerama_y;
int panscan_x;
int panscan_y;
float panscan_amount;
float monitor_par;
struct aspect_data {
float monitor_par; // out of screen size or from options
int orgw; // real width
int orgh; // real height
int prew; // prescaled width
int preh; // prescaled height
float par; // pixel aspect ratio out of orgw/orgh and prew/preh
int scrw; // horizontal resolution
int scrh; // vertical resolution
float asp;
float asp; // final video display aspect
} aspdat;
char *window_title;
@ -322,9 +317,4 @@ struct mp_osd_res;
void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src,
struct mp_rect *out_dst, struct mp_osd_res *out_osd);
static inline int aspect_scaling(struct vo *vo)
{
return vo->opts->keepaspect || vo->opts->fs;
}
#endif /* MPLAYER_VIDEO_OUT_H */