From bd473d325d6065bf05502afcd663c312702a2ba7 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Tue, 1 Dec 2020 17:25:17 +0100 Subject: [PATCH] avcodec/bink: Make decoder init-threadsafe Signed-off-by: Andreas Rheinhardt --- libavcodec/bink.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 36d1ab6c0a..3eb767b83e 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -24,6 +24,7 @@ #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/mem_internal.h" +#include "libavutil/thread.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -1309,6 +1310,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac return pkt->size; } +static av_cold void bink_init_vlcs(void) +{ + for (int i = 0; i < 16; i++) { + static VLC_TYPE table[16 * 128][2]; + const int maxbits = bink_tree_lens[i][15]; + bink_trees[i].table = table + i*128; + bink_trees[i].table_allocated = 1 << maxbits; + init_vlc(&bink_trees[i], maxbits, 16, + bink_tree_lens[i], 1, 1, + bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); + } +} + /** * Calculate quantization tables for version b */ @@ -1343,11 +1357,10 @@ static av_cold void binkb_calc_quant(void) static av_cold int decode_init(AVCodecContext *avctx) { + static AVOnce init_static_once = AV_ONCE_INIT; BinkContext * const c = avctx->priv_data; - static VLC_TYPE table[16 * 128][2]; - static int binkb_initialised = 0; HpelDSPContext hdsp; - int i, ret; + int ret; int flags; c->version = avctx->codec_tag >> 24; @@ -1358,16 +1371,6 @@ static av_cold int decode_init(AVCodecContext *avctx) flags = AV_RL32(avctx->extradata); c->has_alpha = flags & BINK_FLAG_ALPHA; c->swap_planes = c->version >= 'h'; - if (!bink_trees[15].table) { - for (i = 0; i < 16; i++) { - const int maxbits = bink_tree_lens[i][15]; - bink_trees[i].table = table + i*128; - bink_trees[i].table_allocated = 1 << maxbits; - init_vlc(&bink_trees[i], maxbits, 16, - bink_tree_lens[i], 1, 1, - bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - } - } c->avctx = avctx; if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) @@ -1389,11 +1392,10 @@ static av_cold int decode_init(AVCodecContext *avctx) return ret; if (c->version == 'b') { - if (!binkb_initialised) { - binkb_calc_quant(); - binkb_initialised = 1; - } + static AVOnce binkb_init_once = AV_ONCE_INIT; + ff_thread_once(&binkb_init_once, binkb_calc_quant); } + ff_thread_once(&init_static_once, bink_init_vlcs); return 0; } @@ -1426,5 +1428,5 @@ const AVCodec ff_bink_decoder = { .decode = decode_frame, .flush = flush, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, };