summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-08-09 11:58:55 +0200
committerwm4 <wm4@nowhere>2017-08-09 12:00:56 +0200
commitde6d3f8ca10f22901d1cdfb44d117e7ef3eabcc1 (patch)
treef2380e4ae2832c632d5629781cee1131763a063c /video
parent7397e8ab42acd4dcb12943949e902e3df2738085 (diff)
downloadmpv-de6d3f8ca10f22901d1cdfb44d117e7ef3eabcc1.tar.bz2
mpv-de6d3f8ca10f22901d1cdfb44d117e7ef3eabcc1.tar.xz
vd_lavc: fix device leak with copy-mode hwaccels
Apparently this was broken by the "ctx->hwdec" check in the if condition guarding the destroy call, and "ctx->hwdec = NULL;" was moved up earlier, making this always dead code. This should probably be refcounted or so, although that could make it worse as well. For now, add a flag whether the device should be destroyed. Fixes #4735.
Diffstat (limited to 'video')
-rw-r--r--video/decode/lavc.h1
-rw-r--r--video/decode/vd_lavc.c5
2 files changed, 4 insertions, 2 deletions
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 9e27a6e18c..08d4dc1615 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -61,6 +61,7 @@ typedef struct lavc_ctx {
// Set by generic hwaccels.
struct mp_hwdec_ctx *hwdec_dev;
+ bool owns_hwdec_dev;
int hwdec_fmt;
int hwdec_w;
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 9c09d0a9c5..e95f2f5c06 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -592,6 +592,7 @@ 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;
+ ctx->owns_hwdec_dev = !!ctx->hwdec->create_dev;
if (ctx->hwdec_dev->restore_device)
ctx->hwdec_dev->restore_device(ctx->hwdec_dev);
if (!ctx->hwdec->set_hwframes) {
@@ -688,10 +689,10 @@ static void uninit_avctx(struct dec_video *vd)
avcodec_free_context(&ctx->avctx);
- if (ctx->hwdec_dev && ctx->hwdec && ctx->hwdec->generic_hwaccel &&
- ctx->hwdec_dev->destroy)
+ if (ctx->hwdec_dev && ctx->owns_hwdec_dev && ctx->hwdec_dev->destroy)
ctx->hwdec_dev->destroy(ctx->hwdec_dev);
ctx->hwdec_dev = NULL;
+ ctx->owns_hwdec_dev = false;
ctx->hwdec_failed = false;
ctx->hwdec_fail_count = 0;