diff options
Diffstat (limited to 'video/out/vo.c')
-rw-r--r-- | video/out/vo.c | 133 |
1 files changed, 76 insertions, 57 deletions
diff --git a/video/out/vo.c b/video/out/vo.c index 753feaefeb..e05b1ae8a6 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -26,6 +26,8 @@ #include <unistd.h> +#include <libavutil/common.h> + #include "talloc.h" #include "config.h" @@ -35,7 +37,6 @@ #include "vo.h" #include "aspect.h" #include "core/input/input.h" -#include "core/mp_fifo.h" #include "core/m_config.h" #include "core/mp_msg.h" #include "video/mp_image.h" @@ -228,28 +229,13 @@ void vo_flip_page(struct vo *vo, unsigned int pts_us, int duration) void vo_check_events(struct vo *vo) { - vo->next_wakeup_time = GetTimerMS() + 60 * 1000; if (!vo->config_ok) { if (vo->registered_fd != -1) mp_input_rm_key_fd(vo->input_ctx, vo->registered_fd); vo->registered_fd = -1; return; } - vo->driver->check_events(vo); -} - -// Return the amount of time vo_check_events() should be called in milliseconds. -// Note: video timing is completely separate from this. -unsigned int vo_get_sleep_time(struct vo *vo) -{ - unsigned int sleep = 60 * 1000; - if (vo->config_ok && vo->next_wakeup_time) { - unsigned int now = GetTimerMS(); - sleep = 0; - if (vo->next_wakeup_time >= now) - sleep = vo->next_wakeup_time - now; - } - return sleep; + vo_control(vo, VOCTRL_CHECK_EVENTS, NULL); } void vo_seek_reset(struct vo *vo) @@ -298,7 +284,6 @@ static void replace_legacy_vo_name(bstr *name) } struct vo *init_best_video_out(struct mp_vo_opts *opts, - struct mp_fifo *key_fifo, struct input_ctx *input_ctx, struct encode_lavc_context *encode_lavc_ctx) { @@ -307,7 +292,6 @@ struct vo *init_best_video_out(struct mp_vo_opts *opts, struct vo *vo = talloc_ptrtype(NULL, vo); struct vo initial_values = { .opts = opts, - .key_fifo = key_fifo, .encode_lavc_ctx = encode_lavc_ctx, .input_ctx = input_ctx, .event_fd = -1, @@ -419,21 +403,34 @@ static int event_fd_callback(void *ctx, int fd) return MP_INPUT_NOTHING; } -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) +int vo_reconfig(struct vo *vo, struct mp_image_params *params, int flags) { - aspect_save_videores(vo, width, height, d_width, d_height); + int d_width = params->d_w; + int d_height = params->d_h; + aspect_save_videores(vo, params->w, params->h, d_width, d_height); if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) { - determine_window_geometry(vo, d_width, d_height); + determine_window_geometry(vo, params->d_w, params->d_h); d_width = vo->dwidth; d_height = vo->dheight; } + vo->dwidth = d_width; + vo->dheight = d_height; - int ret = vo->driver->config(vo, width, height, d_width, d_height, flags, - format); - vo->config_ok = (ret == 0); + struct mp_image_params p2 = *params; + p2.d_w = vo->aspdat.prew; + p2.d_h = vo->aspdat.preh; + + int ret; + if (vo->driver->reconfig) { + ret = vo->driver->reconfig(vo, &p2, flags); + } else { + // Old config() takes window size, while reconfig() takes aspect (!) + ret = vo->driver->config(vo, p2.w, p2.h, d_width, d_height, flags, + p2.imgfmt); + ret = ret ? -1 : 0; + } + vo->config_ok = (ret >= 0); vo->config_count += vo->config_ok; if (vo->registered_fd == -1 && vo->event_fd != -1 && vo->config_ok) { mp_input_add_key_fd(vo->input_ctx, vo->event_fd, 1, event_fd_callback, @@ -481,25 +478,53 @@ static void print_video_rect(struct vo *vo, struct mp_rect src, 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, int *src_start, - int *src_end, int *dst_start, int *dst_end) + int scaled_src_size, + int *src_start, int *src_end, + int *dst_start, int *dst_end, + int *osd_margin_a, int *osd_margin_b) { - if (scaled_src_size > dst_size) { - int border = src_size * (scaled_src_size - dst_size) / scaled_src_size; - // round to a multiple of 2, this is at least needed for vo_direct3d - // and ATI cards - border = (border / 2 + 1) & ~1; - *src_start = border; - *src_end = src_size - border; + *src_start = 0; + *src_end = src_size; + *dst_start = (dst_size - scaled_src_size) / 2; + *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; - *dst_end = dst_size; - } else { - *src_start = 0; - *src_end = src_size; - *dst_start = (dst_size - scaled_src_size) / 2; - *dst_end = *dst_start + scaled_src_size; } + 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; + } + + // 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 @@ -510,6 +535,7 @@ static void src_dst_split_scaling(int src_size, int dst_size, 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}; @@ -520,19 +546,15 @@ void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src, .display_par = vo->aspdat.monitor_par, .video_par = vo->aspdat.par, }; - if (vo->opts->keepaspect) { + if (opts->keepaspect) { 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; - osd.mt = border_h / 2; - osd.mr = border_w - osd.ml; - osd.mb = border_h - osd.mt; src_dst_split_scaling(src_w, vo->dwidth, scaled_width, - &src.x0, &src.x1, &dst.x0, &dst.x1); + &src.x0, &src.x1, &dst.x0, &dst.x1, + &osd.ml, &osd.mr); src_dst_split_scaling(src_h, vo->dheight, scaled_height, - &src.y0, &src.y1, &dst.y0, &dst.y1); + &src.y0, &src.y1, &dst.y0, &dst.y1, + &osd.mt, &osd.mb); } *out_src = src; @@ -561,10 +583,7 @@ const char *vo_get_window_title(struct vo *vo) */ void vo_mouse_movement(struct vo *vo, int posx, int posy) { - char cmd_str[40]; - if (!vo->opts->enable_mouse_movements) - return; - snprintf(cmd_str, sizeof(cmd_str), "set_mouse_pos %i %i", posx, posy); - mp_input_queue_cmd(vo->input_ctx, mp_input_parse_cmd(bstr0(cmd_str), "")); + if (!vo->opts->enable_mouse_movements) + return; + mp_input_set_mouse_pos(vo->input_ctx, posx, posy); } - |