[FFmpeg-devel] [PATCH 13/20] avcodec/jpeg2000dec: Make decoder init-threadsafe

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Fri May 7 09:46:40 EEST 2021


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 <andreas.rheinhardt at outlook.com>
---
 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,
 };
-- 
2.27.0



More information about the ffmpeg-devel mailing list