summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-01-23 20:32:30 +0100
committerwm4 <wm4@nowhere>2016-01-28 17:17:46 +0100
commit79da78621aff6013e90bf4757433bc52aee37a7d (patch)
tree635e1f00f13193259cb5b9db7b7c9f81fae7f230
parent946ee29a7ded5edf99942b07227cd81eb1bcc274 (diff)
downloadmpv-79da78621aff6013e90bf4757433bc52aee37a7d.tar.bz2
mpv-79da78621aff6013e90bf4757433bc52aee37a7d.tar.xz
vo_opengl: limit effective queue size
Fixes interpolation behavior should the vo_frame have more frames set than "expected".
-rw-r--r--video/out/opengl/video.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 8636e137a8..880ff31c21 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -2086,6 +2086,28 @@ static void pass_draw_to_screen(struct gl_video *p, int fbo)
finish_pass_direct(p, fbo, p->vp_w, p->vp_h, &p->dst_rect, flags);
}
+static int get_queue_size(struct gl_video *p)
+{
+ int queue_size = 1;
+
+ // Figure out an adequate size for the interpolation queue. The larger
+ // the radius, the earlier we need to queue frames.
+ if (p->opts.interpolation) {
+ const struct filter_kernel *kernel =
+ mp_find_filter_kernel(p->opts.scaler[3].kernel.name);
+ if (kernel) {
+ double radius = kernel->f.radius;
+ radius = radius > 0 ? radius : p->opts.scaler[3].radius;
+ queue_size += 1 + ceil(radius);
+ } else {
+ // Oversample case
+ queue_size += 2;
+ }
+ }
+
+ return queue_size;
+}
+
// Draws an interpolate frame to fbo, based on the frame timing in t
static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t,
int fbo)
@@ -2150,7 +2172,8 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t,
// it only barely matters at the very beginning of playback, and this way
// makes the code much more linear.
int surface_dst = fbosurface_wrap(p->surface_idx+1);
- for (int i = 0; i < t->num_frames; i++) {
+ int queue_size = get_queue_size(p);
+ for (int i = 0; i < MPMIN(queue_size, t->num_frames); i++) {
// Avoid overwriting data we might still need
if (surface_dst == surface_bse - 1)
break;
@@ -3006,24 +3029,7 @@ void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts)
void gl_video_configure_queue(struct gl_video *p, struct vo *vo)
{
- int queue_size = 1;
-
- // Figure out an adequate size for the interpolation queue. The larger
- // the radius, the earlier we need to queue frames.
- if (p->opts.interpolation) {
- const struct filter_kernel *kernel =
- mp_find_filter_kernel(p->opts.scaler[3].kernel.name);
- if (kernel) {
- double radius = kernel->f.radius;
- radius = radius > 0 ? radius : p->opts.scaler[3].radius;
- queue_size += 1 + ceil(radius);
- } else {
- // Oversample case
- queue_size += 2;
- }
- }
-
- vo_set_queue_params(vo, 0, queue_size);
+ vo_set_queue_params(vo, 0, get_queue_size(p));
}
struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p)