You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
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 <andreas.rheinhardt@outlook.com>
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
#include "libavutil/mem.h"
|
#include "libavutil/mem.h"
|
||||||
|
#include "libavutil/thread.h"
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "jpeg2000.h"
|
#include "jpeg2000.h"
|
||||||
@@ -157,7 +158,7 @@ static int getsgnctxno(int flag, uint8_t *xorbit)
|
|||||||
return ctxlbltab[hcontrib][vcontrib];
|
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;
|
int i, j;
|
||||||
for (i = 0; i < 256; i++)
|
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]);
|
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,
|
void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1, int x, int y,
|
||||||
int negative)
|
int negative)
|
||||||
{
|
{
|
||||||
|
@@ -34,7 +34,6 @@
|
|||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "libavutil/thread.h"
|
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "bytestream.h"
|
#include "bytestream.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
@@ -2473,18 +2472,12 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s)
|
|||||||
return 0;
|
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 av_cold int jpeg2000_decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
static AVOnce init_static_once = AV_ONCE_INIT;
|
|
||||||
Jpeg2000DecoderContext *s = avctx->priv_data;
|
Jpeg2000DecoderContext *s = avctx->priv_data;
|
||||||
|
|
||||||
ff_thread_once(&init_static_once, jpeg2000_init_static_data);
|
|
||||||
ff_jpeg2000dsp_init(&s->dsp);
|
ff_jpeg2000dsp_init(&s->dsp);
|
||||||
|
ff_jpeg2000_init_tier1_luts();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2588,5 +2581,6 @@ const AVCodec ff_jpeg2000_decoder = {
|
|||||||
.decode = jpeg2000_decode_frame,
|
.decode = jpeg2000_decode_frame,
|
||||||
.priv_class = &jpeg2000_class,
|
.priv_class = &jpeg2000_class,
|
||||||
.max_lowres = 5,
|
.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,
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user