summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-02-05 17:46:46 +0100
committerwm4 <wm4@nowhere>2016-02-05 17:46:46 +0100
commitfd339e3f53996efd2dae9525990da433d1e1bf89 (patch)
tree5bf358cee74510ea995ee0eb2b3418c11d16da8c /video
parentb4f63cbbec563e46ef01899b7292e301e961ec1d (diff)
downloadmpv-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.c15
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;