diff options
author | wm4 <wm4@nowhere> | 2017-07-10 14:52:32 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-07-10 14:56:48 +0200 |
commit | ba921e26171df3a59adbb8b945aac1a529be3a17 (patch) | |
tree | 242dd0e877881e29e5d1115eacaeadf66b03337a | |
parent | f76f37991fc964fdb14632d1bd8da63487ea1063 (diff) |
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.
-rw-r--r-- | video/decode/vd_lavc.c | 12 |
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; |