diff options
author | wm4 <wm4@nowhere> | 2016-02-05 17:46:46 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-02-05 17:46:46 +0100 |
commit | fd339e3f53996efd2dae9525990da433d1e1bf89 (patch) | |
tree | 5bf358cee74510ea995ee0eb2b3418c11d16da8c /video | |
parent | b4f63cbbec563e46ef01899b7292e301e961ec1d (diff) | |
download | mpv-fd339e3f53996efd2dae9525990da433d1e1bf89.tar.bz2 mpv-fd339e3f53996efd2dae9525990da433d1e1bf89.tar.xz |
vd_lavc: avoid calling flush on an unopened AVCodecContext
It can be "dangerous". In particular, the decoder might have failed to
initialize, and is now in a broken state. avcodec_flush_buffers() is not
expected to be called in this state, and could trigger undefined
behavior.
Diffstat (limited to 'video')
-rw-r--r-- | video/decode/vd_lavc.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 19b335d037..0e8cbb1967 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -457,6 +457,11 @@ static void init_avctx(struct dec_video *vd, const char *decoder, error: MP_ERR(vd, "Could not open codec.\n"); + // Free it here to avoid attempting to flush+close. + if (ctx->avctx) { + av_freep(&ctx->avctx->extradata); + av_freep(&ctx->avctx); + } uninit_avctx(vd); } @@ -483,24 +488,22 @@ static void flush_all(struct dec_video *vd) static void uninit_avctx(struct dec_video *vd) { vd_ffmpeg_ctx *ctx = vd->priv; - AVCodecContext *avctx = ctx->avctx; flush_all(vd); av_frame_free(&ctx->pic); - if (avctx) { - if (avctx->codec && avcodec_close(avctx) < 0) + if (ctx->avctx) { + if (avcodec_close(ctx->avctx) < 0) MP_ERR(vd, "Could not close codec.\n"); - av_freep(&avctx->extradata); + av_freep(&ctx->avctx->extradata); + av_freep(&ctx->avctx); } if (ctx->hwdec && ctx->hwdec->uninit) ctx->hwdec->uninit(ctx); ctx->hwdec = NULL; - av_freep(&ctx->avctx); - ctx->hwdec_failed = false; ctx->hwdec_fail_count = 0; ctx->max_delay_queue = 0; |