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, };