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:
parent
59960baa7f
commit
4b87cb39a3
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user