From d99707b42a55b2fcfc17b8c9bf3f38c1879dbaa7 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Thu, 10 Dec 2020 04:32:17 +0100 Subject: [PATCH] avcodec/mpeg4video: Make initializing RLTable thread-safe Up until now the RLTable ff_mpeg4_rl_intra was initialized by both mpeg4 decoder and encoder (except the VLCs that are only used by the decoder). This is an obstacle to making these codecs init-threadsafe, so move initializing this to a single function that is guarded by a dedicated AVOnce. Reviewed-by: Anton Khirnov Signed-off-by: Andreas Rheinhardt --- libavcodec/mpeg4video.c | 14 +++++++++++++- libavcodec/mpeg4video.h | 3 +-- libavcodec/mpeg4videodec.c | 8 +++++--- libavcodec/mpeg4videoenc.c | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c index 2aaa9f734cd..ffeaf822b2d 100644 --- a/libavcodec/mpeg4video.c +++ b/libavcodec/mpeg4video.c @@ -20,12 +20,24 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/thread.h" + #include "mpegutils.h" #include "mpegvideo.h" #include "mpeg4video.h" #include "mpeg4data.h" -uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3]; +static av_cold void mpeg4_init_rl_intra(void) +{ + static uint8_t mpeg4_rl_intra_table[2][2 * MAX_RUN + MAX_LEVEL + 3]; + ff_rl_init(&ff_mpeg4_rl_intra, mpeg4_rl_intra_table); +} + +av_cold void ff_mpeg4_init_rl_intra(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, mpeg4_init_rl_intra); +} int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s) { diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h index e919db87a50..3db6f85153d 100644 --- a/libavcodec/mpeg4video.h +++ b/libavcodec/mpeg4video.h @@ -129,6 +129,7 @@ extern const int8_t ff_mpeg4_intra_level[102]; extern const int8_t ff_mpeg4_intra_run[102]; extern RLTable ff_mpeg4_rl_intra; +void ff_mpeg4_init_rl_intra(void); /* Note this is identical to the intra rvlc except that it is reordered. */ extern RLTable ff_rvlc_rl_inter; @@ -180,8 +181,6 @@ int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size); */ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my); -extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3]; - #if 0 //3IV1 is quite rare and it slows things down a tiny bit #define IS_3IV1 s->codec_tag == AV_RL32("3IV1") #else diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index de66fe8b835..fc76485dbe6 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3378,9 +3378,11 @@ av_cold void ff_mpeg4videodec_static_init(void) { static int done = 0; if (!done) { - ff_rl_init(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); - ff_rl_init(&ff_rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); - ff_rl_init(&ff_rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); + static uint8_t mpeg4_rvlc_rl_tables[2][2][2 * MAX_RUN + MAX_LEVEL + 3]; + + ff_mpeg4_init_rl_intra(); + ff_rl_init(&ff_rvlc_rl_inter, mpeg4_rvlc_rl_tables[0]); + ff_rl_init(&ff_rvlc_rl_intra, mpeg4_rvlc_rl_tables[1]); INIT_FIRST_VLC_RL(ff_mpeg4_rl_intra, 554); INIT_VLC_RL(ff_rvlc_rl_inter, 1072); INIT_FIRST_VLC_RL(ff_rvlc_rl_intra, 1072); diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index 7145bfe8ced..4593fe6096c 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -1285,7 +1285,7 @@ static av_cold int encode_init(AVCodecContext *avctx) init_uni_dc_tab(); - ff_rl_init(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); + ff_mpeg4_init_rl_intra(); init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len); init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); -- 2.39.5