From 0f2acd4a80be53638c19bfee2fcac2e72c06fa29 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 21 Jan 2014 23:47:54 +0100 Subject: vo: move vo_get_src_dst_rects to aspect.c The plan is to make all the code in aspect.c independent from vo.c, which should make the code easier to understand, will allow removal of vo->aspdat, and reduces the amount of code that accesses weird mutable struct vo fields. --- video/out/aspect.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++ video/out/vo.c | 128 ---------------------------------------------------- 2 files changed, 130 insertions(+), 128 deletions(-) diff --git a/video/out/aspect.c b/video/out/aspect.c index b7c6c61e07..5262785b16 100644 --- a/video/out/aspect.c +++ b/video/out/aspect.c @@ -25,6 +25,7 @@ #include "options/options.h" #include "vo.h" +#include "sub/osd.h" void aspect_save_videores(struct vo *vo, int w, int h, int d_w, int d_h) { @@ -75,3 +76,132 @@ void aspect_calc_panscan(struct vo *vo, int *out_w, int *out_h) *out_w = fwidth + vo_panscan_area * opts->panscan * fwidth / fheight; *out_h = fheight + vo_panscan_area * opts->panscan; } + + +static void print_video_rect(struct vo *vo, struct mp_rect src, + struct mp_rect dst, struct mp_osd_res osd) +{ + int sw = src.x1 - src.x0, sh = src.y1 - src.y0; + int dw = dst.x1 - dst.x0, dh = dst.y1 - dst.y0; + + MP_VERBOSE(&vo->vo_log, "Window size: %dx%d\n", + vo->dwidth, vo->dheight); + MP_VERBOSE(&vo->vo_log, "Video source: %dx%d (%dx%d)\n", + vo->aspdat.orgw, vo->aspdat.orgh, + vo->aspdat.prew, vo->aspdat.preh); + MP_VERBOSE(&vo->vo_log, "Video display: (%d, %d) %dx%d -> (%d, %d) %dx%d\n", + src.x0, src.y0, sw, sh, dst.x0, dst.y0, dw, dh); + MP_VERBOSE(&vo->vo_log, "Video scale: %f/%f\n", + (double)dw / sw, (double)dh / sh); + MP_VERBOSE(&vo->vo_log, "OSD borders: l=%d t=%d r=%d b=%d\n", + osd.ml, osd.mt, osd.mr, osd.mb); + MP_VERBOSE(&vo->vo_log, "Video borders: l=%d t=%d r=%d b=%d\n", + dst.x0, dst.y0, vo->dwidth - dst.x1, vo->dheight - dst.y1); +} + +// Clamp [start, end) to range [0, size) with various fallbacks. +static void clamp_size(int size, int *start, int *end) +{ + *start = FFMAX(0, *start); + *end = FFMIN(size, *end); + if (*start >= *end) { + *start = 0; + *end = 1; + } +} + +// Round source to a multiple of 2, this is at least needed for vo_direct3d +// and ATI cards. +#define VID_SRC_ROUND_UP(x) (((x) + 1) & ~1) + +static void src_dst_split_scaling(int src_size, int dst_size, + int scaled_src_size, bool unscaled, + 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) +{ + if (unscaled) { + scaled_src_size = src_size; + zoom = 0.0; + } + + scaled_src_size += zoom * scaled_src_size; + align = (align + 1) / 2; + + *src_start = 0; + *src_end = src_size; + *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 + *osd_margin_a = *dst_start; + *osd_margin_b = dst_size - *dst_end; + + // Clip to screen + int s_src = *src_end - *src_start; + int s_dst = *dst_end - *dst_start; + if (*dst_start < 0) { + int border = -(*dst_start) * s_src / s_dst; + *src_start += VID_SRC_ROUND_UP(border); + *dst_start = 0; + } + if (*dst_end > dst_size) { + int border = (*dst_end - dst_size) * s_src / s_dst; + *src_end -= VID_SRC_ROUND_UP(border); + *dst_end = dst_size; + } + + if (unscaled) { + // Force unscaled by reducing the range for src or dst + int src_s = *src_end - *src_start; + int dst_s = *dst_end - *dst_start; + if (src_s > dst_s) { + *src_end = *src_start + dst_s; + } else if (src_s < dst_s) { + *dst_end = *dst_start + src_s; + } + } + + // For sanity: avoid bothering VOs with corner cases + clamp_size(src_size, src_start, src_end); + clamp_size(dst_size, dst_start, dst_end); +} + +// Calculate the appropriate source and destination rectangle to +// get a correctly scaled picture, including pan-scan. +// out_src: visible part of the video +// out_dst: area of screen covered by the video source rectangle +// out_osd: OSD size, OSD margins, etc. +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) +{ + struct mp_vo_opts *opts = vo->opts; + int src_w = vo->aspdat.orgw; + int src_h = vo->aspdat.orgh; + struct mp_rect dst = {0, 0, vo->dwidth, vo->dheight}; + struct mp_rect src = {0, 0, src_w, src_h}; + struct mp_osd_res osd = { + .w = vo->dwidth, + .h = vo->dheight, + .display_par = vo->monitor_par, + }; + if (opts->keepaspect) { + int scaled_width, scaled_height; + aspect_calc_panscan(vo, &scaled_width, &scaled_height); + src_dst_split_scaling(src_w, vo->dwidth, scaled_width, opts->unscaled, + 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->unscaled, + opts->zoom, opts->align_y, opts->pan_y, + &src.y0, &src.y1, &dst.y0, &dst.y1, + &osd.mt, &osd.mb); + } + + *out_src = src; + *out_dst = dst; + *out_osd = osd; + + print_video_rect(vo, src, dst, osd); +} diff --git a/video/out/vo.c b/video/out/vo.c index 1952f14294..4f3e90534d 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -483,134 +483,6 @@ int lookup_keymap_table(const struct mp_keymap *map, int key) { return map->to; } -static void print_video_rect(struct vo *vo, struct mp_rect src, - struct mp_rect dst, struct mp_osd_res osd) -{ - int sw = src.x1 - src.x0, sh = src.y1 - src.y0; - int dw = dst.x1 - dst.x0, dh = dst.y1 - dst.y0; - - MP_VERBOSE(&vo->vo_log, "Window size: %dx%d\n", - vo->dwidth, vo->dheight); - MP_VERBOSE(&vo->vo_log, "Video source: %dx%d (%dx%d)\n", - vo->aspdat.orgw, vo->aspdat.orgh, - vo->aspdat.prew, vo->aspdat.preh); - MP_VERBOSE(&vo->vo_log, "Video display: (%d, %d) %dx%d -> (%d, %d) %dx%d\n", - src.x0, src.y0, sw, sh, dst.x0, dst.y0, dw, dh); - MP_VERBOSE(&vo->vo_log, "Video scale: %f/%f\n", - (double)dw / sw, (double)dh / sh); - MP_VERBOSE(&vo->vo_log, "OSD borders: l=%d t=%d r=%d b=%d\n", - osd.ml, osd.mt, osd.mr, osd.mb); - MP_VERBOSE(&vo->vo_log, "Video borders: l=%d t=%d r=%d b=%d\n", - dst.x0, dst.y0, vo->dwidth - dst.x1, vo->dheight - dst.y1); -} - -// Clamp [start, end) to range [0, size) with various fallbacks. -static void clamp_size(int size, int *start, int *end) -{ - *start = FFMAX(0, *start); - *end = FFMIN(size, *end); - if (*start >= *end) { - *start = 0; - *end = 1; - } -} - -// Round source to a multiple of 2, this is at least needed for vo_direct3d -// and ATI cards. -#define VID_SRC_ROUND_UP(x) (((x) + 1) & ~1) - -static void src_dst_split_scaling(int src_size, int dst_size, - int scaled_src_size, bool unscaled, - 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) -{ - if (unscaled) { - scaled_src_size = src_size; - zoom = 0.0; - } - - scaled_src_size += zoom * scaled_src_size; - align = (align + 1) / 2; - - *src_start = 0; - *src_end = src_size; - *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 - *osd_margin_a = *dst_start; - *osd_margin_b = dst_size - *dst_end; - - // Clip to screen - int s_src = *src_end - *src_start; - int s_dst = *dst_end - *dst_start; - if (*dst_start < 0) { - int border = -(*dst_start) * s_src / s_dst; - *src_start += VID_SRC_ROUND_UP(border); - *dst_start = 0; - } - if (*dst_end > dst_size) { - int border = (*dst_end - dst_size) * s_src / s_dst; - *src_end -= VID_SRC_ROUND_UP(border); - *dst_end = dst_size; - } - - if (unscaled) { - // Force unscaled by reducing the range for src or dst - int src_s = *src_end - *src_start; - int dst_s = *dst_end - *dst_start; - if (src_s > dst_s) { - *src_end = *src_start + dst_s; - } else if (src_s < dst_s) { - *dst_end = *dst_start + src_s; - } - } - - // For sanity: avoid bothering VOs with corner cases - clamp_size(src_size, src_start, src_end); - clamp_size(dst_size, dst_start, dst_end); -} - -// Calculate the appropriate source and destination rectangle to -// get a correctly scaled picture, including pan-scan. -// out_src: visible part of the video -// out_dst: area of screen covered by the video source rectangle -// out_osd: OSD size, OSD margins, etc. -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) -{ - struct mp_vo_opts *opts = vo->opts; - int src_w = vo->aspdat.orgw; - int src_h = vo->aspdat.orgh; - struct mp_rect dst = {0, 0, vo->dwidth, vo->dheight}; - struct mp_rect src = {0, 0, src_w, src_h}; - struct mp_osd_res osd = { - .w = vo->dwidth, - .h = vo->dheight, - .display_par = vo->monitor_par, - }; - if (opts->keepaspect) { - int scaled_width, scaled_height; - aspect_calc_panscan(vo, &scaled_width, &scaled_height); - src_dst_split_scaling(src_w, vo->dwidth, scaled_width, opts->unscaled, - 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->unscaled, - opts->zoom, opts->align_y, opts->pan_y, - &src.y0, &src.y1, &dst.y0, &dst.y1, - &osd.mt, &osd.mb); - } - - *out_src = src; - *out_dst = dst; - *out_osd = osd; - - print_video_rect(vo, src, dst, osd); -} - // Return the window title the VO should set. Always returns a null terminated // string. The string is valid until frontend code is invoked again. Copy it if // you need to keep the string for an extended period of time. -- cgit v1.2.3