summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-03-08 00:23:12 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-03-08 17:12:32 -0800
commitc15af6630f8ea7bc17d6041aec89bca59209814a (patch)
tree3be0d53413dbfc01ff975ce6f7409e6d5ad08808
parent2f20168b0b5105566ecb330ea4b83c358e4b4e6d (diff)
downloadmpv-c15af6630f8ea7bc17d6041aec89bca59209814a.tar.bz2
mpv-c15af6630f8ea7bc17d6041aec89bca59209814a.tar.xz
vo_vdpau: fix resizing and rotation problems
The s_size() function, whatever it was supposed to do, caused the surface size to increase indefinitely. Fix by making it always use the maximum size that was last used, which is less optimal (many surface recreations when making the window slowly larger), but at least it works. The rotation code didn't mark the old surface as invalid when it was freed, so it could destroy random other surfaces (let's call it dangling ID). Also, the required rotation surface size depends on the rotation mode, so recreate the surfaces on rotation as well.
-rw-r--r--video/out/vo_vdpau.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c
index 913e0f696a..9871355330 100644
--- a/video/out/vo_vdpau.c
+++ b/video/out/vo_vdpau.c
@@ -86,6 +86,7 @@ struct vdpctx {
int current_duration;
int output_surface_w, output_surface_h;
+ int rotation;
int force_yuv;
struct mp_vdpau_mixer *video_mixer;
@@ -244,8 +245,7 @@ static void forget_frames(struct vo *vo, bool seek_reset)
static int s_size(int max, int s, int disp)
{
disp = MPMAX(1, disp);
- s += s / 2;
- return MPMIN(max, s >= disp ? s : disp);
+ return MPMIN(max, MPMAX(s, disp));
}
static void resize(struct vo *vo)
@@ -285,7 +285,9 @@ static void resize(struct vo *vo)
1000LL * vc->flip_offset_window;
vo_set_queue_params(vo, vc->flip_offset_us, 1);
- if (vc->output_surface_w < vo->dwidth || vc->output_surface_h < vo->dheight) {
+ if (vc->output_surface_w < vo->dwidth || vc->output_surface_h < vo->dheight ||
+ vc->rotation != vo->params->rotate)
+ {
vc->output_surface_w = s_size(max_w, vc->output_surface_w, vo->dwidth);
vc->output_surface_h = s_size(max_h, vc->output_surface_h, vo->dheight);
// Creation of output_surfaces
@@ -309,6 +311,7 @@ static void resize(struct vo *vo)
vdp_st = vdp->output_surface_destroy(vc->rotation_surface);
CHECK_VDP_WARNING(vo, "Error when calling "
"vdp_output_surface_destroy");
+ vc->rotation_surface = VDP_INVALID_HANDLE;
}
if (vo->params->rotate == 90 || vo->params->rotate == 270) {
vdp_st = vdp->output_surface_create(vc->vdp_device,
@@ -327,6 +330,7 @@ static void resize(struct vo *vo)
MP_DBG(vo, "vdpau rotation surface create: %u\n",
vc->rotation_surface);
}
+ vc->rotation = vo->params->rotate;
vo->want_redraw = true;
}