summaryrefslogtreecommitdiffstats
path: root/video/vdpau.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-09 21:49:29 +0200
committerwm4 <wm4@nowhere>2014-05-10 10:44:16 +0200
commit203be26588798e7ecb22e02f116fc4fbec438a61 (patch)
tree19ef97c3e9550414527e20c56f1ca4eba239f88f /video/vdpau.c
parent66391dbb642fe08fea59d4c2e3c36b69d9db7446 (diff)
downloadmpv-203be26588798e7ecb22e02f116fc4fbec438a61.tar.bz2
mpv-203be26588798e7ecb22e02f116fc4fbec438a61.tar.xz
vdpau: handle display preemption during decoding
This was broken for some time, and it didn't recover correctly. Redo decoder display preemption. Instead of trying to reinitialize the hw decoder, simply fallback to software decoding. I consider display preemption a bug in the vdpau API, so being able to _somehow_ recover playback is good enough. The approach taking here will probably also make it easier to handle multithreading.
Diffstat (limited to 'video/vdpau.c')
-rw-r--r--video/vdpau.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/video/vdpau.c b/video/vdpau.c
index 35f5cf457d..2e21c80a56 100644
--- a/video/vdpau.c
+++ b/video/vdpau.c
@@ -127,6 +127,30 @@ bool mp_vdpau_status_ok(struct mp_vdpau_ctx *ctx)
return handle_preemption(ctx) >= 0;
}
+// Check whether vdpau display preemption happened. The caller provides a
+// preemption counter, which contains the logical timestamp of the last
+// preemption handled by the caller. The counter can be 0 for init.
+// Return values:
+// -1: the display is currently preempted, and vdpau can't be used
+// 0: a preemption event happened, and the caller must recover
+// (*counter is updated, and a second call will report status ok)
+// 1: everything is fine, no preemption happened
+int mp_vdpau_handle_preemption(struct mp_vdpau_ctx *ctx, uint64_t *counter)
+{
+ // First time init
+ if (!*counter)
+ *counter = ctx->preemption_counter;
+
+ if (handle_preemption(ctx) < 0)
+ return -1;
+
+ if (*counter < ctx->preemption_counter) {
+ *counter = ctx->preemption_counter;
+ return 0; // signal recovery after preemption
+ }
+ return 1;
+}
+
static void release_decoder_surface(void *ptr)
{
bool *in_use_ptr = ptr;
@@ -205,6 +229,7 @@ struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log,
*ctx = (struct mp_vdpau_ctx) {
.log = log,
.x11 = x11,
+ .preemption_counter = 1,
};
mark_vdpau_objects_uninitialized(ctx);