summaryrefslogtreecommitdiff
path: root/libavcodec/hevcdec.c
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2021-02-10 14:26:59 -0300
committerJames Almer <jamrial@gmail.com>2021-02-11 13:15:45 -0300
commit089706e009240ce3dc76f09ae9eee0ba98e65bd1 (patch)
treeab6d236cbe6b09f9872f5fb702712744ec22e7ea /libavcodec/hevcdec.c
parent44facfb845563b3fc2a12cc3fbefc86ea72dea0b (diff)
avcodec/hevcdec: check that the local context list was allocated before dereferencing it
Since the decoder is not flagged as init cleanup capable, hevc_decode_free() is being called manually if the hevc_decode_extradata() call fails at the end of hevc_decode_init(). In a frame threading scenario, however, if AVCodec->init() returns an error, ff_frame_thread_free() will be called regardless of the above flag being set or not, resulting in hevc_decode_free() being called a second time for the same context. Workaround this by ensuring pointers are not dereferenced if they are NULL, and set the decoder as init cleanup capable while at it. Fixes ticket #9099. Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/hevcdec.c')
-rw-r--r--libavcodec/hevcdec.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 92eb888033..2dbbc6d2b3 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3417,16 +3417,13 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
av_freep(&s->sh.offset);
av_freep(&s->sh.size);
- for (i = 1; i < s->threads_number; i++) {
- HEVCLocalContext *lc = s->HEVClcList[i];
- if (lc) {
+ if (s->HEVClcList && s->sList) {
+ for (i = 1; i < s->threads_number; i++) {
av_freep(&s->HEVClcList[i]);
av_freep(&s->sList[i]);
}
}
- if (s->HEVClc == s->HEVClcList[0])
- s->HEVClc = NULL;
- av_freep(&s->HEVClcList[0]);
+ av_freep(&s->HEVClc);
av_freep(&s->HEVClcList);
av_freep(&s->sList);
@@ -3622,7 +3619,6 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
if (avctx->extradata_size > 0 && avctx->extradata) {
ret = hevc_decode_extradata(s, avctx->extradata, avctx->extradata_size, 1);
if (ret < 0) {
- hevc_decode_free(avctx);
return ret;
}
}
@@ -3673,7 +3669,7 @@ AVCodec ff_hevc_decoder = {
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING |
- FF_CODEC_CAP_ALLOCATE_PROGRESS,
+ FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP,
.profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
.hw_configs = (const AVCodecHWConfigInternal *const []) {
#if CONFIG_HEVC_DXVA2_HWACCEL