summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/decode/vd_lavc.c2
-rw-r--r--video/hwdec.h3
-rw-r--r--video/vdpau.c16
3 files changed, 21 insertions, 0 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index fe4409968a..9c1a2a0317 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -603,6 +603,8 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
ctx->hwdec_dev = hwdec_create_dev(vd, ctx->hwdec, false);
if (!ctx->hwdec_dev)
goto error;
+ if (ctx->hwdec_dev->restore_device)
+ ctx->hwdec_dev->restore_device(ctx->hwdec_dev);
if (!ctx->hwdec->set_hwframes) {
#if HAVE_VDPAU_HWACCEL
avctx->hw_device_ctx = av_buffer_ref(ctx->hwdec_dev->av_device_ref);
diff --git a/video/hwdec.h b/video/hwdec.h
index 49fd9895c0..c0ef9b76b6 100644
--- a/video/hwdec.h
+++ b/video/hwdec.h
@@ -66,6 +66,9 @@ struct mp_hwdec_ctx {
struct mp_image *mpi,
struct mp_image_pool *swpool);
+ // Optional. Crap for vdpau. Makes sure preemption recovery is run if needed.
+ void (*restore_device)(struct mp_hwdec_ctx *ctx);
+
// Optional. Do not set for VO-bound devices.
void (*destroy)(struct mp_hwdec_ctx *ctx);
};
diff --git a/video/vdpau.c b/video/vdpau.c
index fa79e9bc67..fabd47c96b 100644
--- a/video/vdpau.c
+++ b/video/vdpau.c
@@ -188,6 +188,14 @@ static int win_x11_init_vdpau_procs(struct mp_vdpau_ctx *ctx, bool probing)
ctx->vdp = vdp;
ctx->get_proc_address = get_proc_address;
+ if (ctx->av_device_ref) {
+ AVHWDeviceContext *hwctx = (void *)ctx->av_device_ref->data;
+ AVVDPAUDeviceContext *vdctx = hwctx->hwctx;
+
+ vdctx->device = ctx->vdp_device;
+ vdctx->get_proc_address = ctx->get_proc_address;
+ }
+
vdp_st = vdp.output_surface_create(ctx->vdp_device, VDP_RGBA_FORMAT_B8G8R8A8,
1, 1, &ctx->preemption_obj);
if (vdp_st != VDP_STATUS_OK) {
@@ -405,6 +413,13 @@ struct mp_image *mp_vdpau_get_video_surface(struct mp_vdpau_ctx *ctx,
return mp_vdpau_get_surface(ctx, chroma, 0, false, w, h);
}
+static void recheck_preemption(struct mp_hwdec_ctx *hwctx)
+{
+ struct mp_vdpau_ctx *ctx = hwctx->ctx;
+
+ mp_vdpau_handle_preemption(ctx, NULL);
+}
+
static bool open_lavu_vdpau_device(struct mp_vdpau_ctx *ctx)
{
ctx->av_device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VDPAU);
@@ -437,6 +452,7 @@ struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log, Display *x11
.type = HWDEC_VDPAU,
.ctx = ctx,
.download_image = download_image,
+ .restore_device = recheck_preemption,
},
.getimg_surface = VDP_INVALID_HANDLE,
};