diff options
author | wm4 <wm4@nowhere> | 2015-06-05 19:33:09 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-06-05 22:34:16 +0200 |
commit | 2bf2254248c4366040eae8724181f325ce28480b (patch) | |
tree | 87f8795373e91b997d115c24fc3f6c247fbff20d /video/out/vo_vdpau.c | |
parent | e0f0f6f3e9820150a5c188e4e78f001617449f82 (diff) | |
download | mpv-2bf2254248c4366040eae8724181f325ce28480b.tar.bz2 mpv-2bf2254248c4366040eae8724181f325ce28480b.tar.xz |
vo_vdpau: limit output surfaces to allowed maximum dimensions
We can't do much in this case, but at least we can not call the vdpau
API functions with too large sizes. Apparently the API considers this
undefined behavior, and random stuff might happen.
Diffstat (limited to 'video/out/vo_vdpau.c')
-rw-r--r-- | video/out/vo_vdpau.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index 934fe6c944..c211b558ab 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -214,11 +214,11 @@ static void forget_frames(struct vo *vo, bool seek_reset) vc->dropped_frame = false; } -static int s_size(int s, int disp) +static int s_size(int max, int s, int disp) { disp = MPMAX(1, disp); s += s / 2; - return s >= disp ? s : disp; + return MPMIN(max, s >= disp ? s : disp); } static void resize(struct vo *vo) @@ -238,14 +238,22 @@ static void resize(struct vo *vo) vc->src_rect_vid.y0 = src_rect.y0; vc->src_rect_vid.y1 = src_rect.y1; + VdpBool ok; + uint32_t max_w, max_h; + vdp_st = vdp->output_surface_query_capabilities(vc->vdp_device, + OUTPUT_RGBA_FORMAT, + &ok, &max_w, &max_h); + if (vdp_st != VDP_STATUS_OK || !ok) + return; + vc->flip_offset_us = vo->opts->fullscreen ? 1000LL * vc->flip_offset_fs : 1000LL * vc->flip_offset_window; vo_set_flip_queue_params(vo, vc->flip_offset_us, false); if (vc->output_surface_w < vo->dwidth || vc->output_surface_h < vo->dheight) { - vc->output_surface_w = s_size(vc->output_surface_w, vo->dwidth); - vc->output_surface_h = s_size(vc->output_surface_h, vo->dheight); + 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 for (int i = 0; i < vc->num_output_surfaces; i++) if (vc->output_surfaces[i] != VDP_INVALID_HANDLE) { |