summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-07-10 14:52:32 +0200
committerwm4 <wm4@nowhere>2017-07-10 14:56:48 +0200
commitba921e26171df3a59adbb8b945aac1a529be3a17 (patch)
tree242dd0e877881e29e5d1115eacaeadf66b03337a /video
parentf76f37991fc964fdb14632d1bd8da63487ea1063 (diff)
downloadmpv-ba921e26171df3a59adbb8b945aac1a529be3a17.tar.bz2
mpv-ba921e26171df3a59adbb8b945aac1a529be3a17.tar.xz
vd_lavc: fix crashes with old hwaccels
Commit d5702d3b95 messed up the order of destruction of the elements: it destroyed the avctx before the hwaccel uninit, even though the hwaccel uninit could access avctx. This could happen with some old hwaccels only, such as D3D ones before the new libavcodec hwaccel API. Fix this by making use of the fact that avcodec_flush_buffers() will uninit the underlying hwaccel. Thus we can be sure avctx is not using any hwaccel objects anymore, and it's safe to uninit the hwaccel. Move the hwdec_dev dstruction code with it, because otherwise we would in theory potentially create some dangling pointers in avctx.
Diffstat (limited to 'video')
-rw-r--r--video/decode/vd_lavc.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index e5de69499d..27861171f5 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -664,6 +664,11 @@ static void uninit_avctx(struct dec_video *vd)
av_frame_free(&ctx->pic);
av_buffer_unref(&ctx->cached_hw_frames_ctx);
+ if (ctx->hwdec && ctx->hwdec->uninit)
+ ctx->hwdec->uninit(ctx);
+ ctx->hwdec = NULL;
+ assert(ctx->hwdec_priv == NULL);
+
avcodec_free_context(&ctx->avctx);
if (ctx->hwdec_dev && ctx->hwdec && ctx->hwdec->generic_hwaccel &&
@@ -671,13 +676,6 @@ static void uninit_avctx(struct dec_video *vd)
ctx->hwdec_dev->destroy(ctx->hwdec_dev);
ctx->hwdec_dev = NULL;
- if (ctx->hwdec && ctx->hwdec->uninit)
- ctx->hwdec->uninit(ctx);
- ctx->hwdec = NULL;
- assert(ctx->hwdec_priv == NULL);
-
- av_freep(&ctx->avctx);
-
ctx->hwdec_failed = false;
ctx->hwdec_fail_count = 0;
ctx->max_delay_queue = 0;