From 3c26773ae28ebd6a549491d432a6990450b068cf Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Fri, 7 May 2021 04:49:27 +0200 Subject: [PATCH] avcodec/jpeg2000dec: Make decoder init-threadsafe The JPEG-2000 decoder and encoder share common luts; the decoder initializes them once, guarded by a dedicated AVOnce, whereas the encoder initializes them always during init. This means that the decoder is not init-threadsafe; in fact there is a potential data race because these luts can be initialized while an active decoder/encoder is using them. Fix this and make the decoder init-threadsafe by making the initialization function guard initialization itself with a dedicated AVOnce. Signed-off-by: Andreas Rheinhardt --- libavcodec/jpeg2000.c | 9 ++++++++- libavcodec/jpeg2000dec.c | 12 +++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 56d98c8a89..324908d833 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -30,6 +30,7 @@ #include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" +#include "libavutil/thread.h" #include "avcodec.h" #include "internal.h" #include "jpeg2000.h" @@ -157,7 +158,7 @@ static int getsgnctxno(int flag, uint8_t *xorbit) return ctxlbltab[hcontrib][vcontrib]; } -void av_cold ff_jpeg2000_init_tier1_luts(void) +static void av_cold jpeg2000_init_tier1_luts(void) { int i, j; for (i = 0; i < 256; i++) @@ -169,6 +170,12 @@ void av_cold ff_jpeg2000_init_tier1_luts(void) getsgnctxno(i + (j << 8), &ff_jpeg2000_xorbit_lut[i][j]); } +void av_cold ff_jpeg2000_init_tier1_luts(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, jpeg2000_init_tier1_luts); +} + void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1, int x, int y, int negative) { diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 1295c96305..e62f7b19e6 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -34,7 +34,6 @@ #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" -#include "libavutil/thread.h" #include "avcodec.h" #include "bytestream.h" #include "internal.h" @@ -2473,18 +2472,12 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) return 0; } -static av_cold void jpeg2000_init_static_data(void) -{ - ff_jpeg2000_init_tier1_luts(); -} - static av_cold int jpeg2000_decode_init(AVCodecContext *avctx) { - static AVOnce init_static_once = AV_ONCE_INIT; Jpeg2000DecoderContext *s = avctx->priv_data; - ff_thread_once(&init_static_once, jpeg2000_init_static_data); ff_jpeg2000dsp_init(&s->dsp); + ff_jpeg2000_init_tier1_luts(); return 0; } @@ -2588,5 +2581,6 @@ const AVCodec ff_jpeg2000_decoder = { .decode = jpeg2000_decode_frame, .priv_class = &jpeg2000_class, .max_lowres = 5, - .profiles = NULL_IF_CONFIG_SMALL(ff_jpeg2000_profiles) + .profiles = NULL_IF_CONFIG_SMALL(ff_jpeg2000_profiles), + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, };