summaryrefslogtreecommitdiff
path: root/libavcodec/bink.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-12-01 17:25:17 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2021-05-02 05:14:42 +0200
commitbd473d325d6065bf05502afcd663c312702a2ba7 (patch)
tree2f61339385e6cc3275c9f158369c72470cac7e4b /libavcodec/bink.c
parent8903c7f1fee7683db90b6c4fd14671f36d0d2a0f (diff)
avcodec/bink: Make decoder init-threadsafe
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavcodec/bink.c')
-rw-r--r--libavcodec/bink.c38
1 files 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,
};