summaryrefslogtreecommitdiff
path: root/libavcodec/mpeg4videodec.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-01-04 06:12:27 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-01-09 09:32:53 +0100
commit832ead2ec40392e73422f9a9d3ab1f21ea025207 (patch)
tree533eaacbea16cba0b48dda2d1369da09c55d59ac /libavcodec/mpeg4videodec.c
parentf0194e860e33cb60a80305eae2262b2e7977c908 (diff)
avcodec/mpeg4videodec: Fix data race when initializing VLCs
Both the MPEG-4 parser as well as the decoder initialized several VLCs. There is a "static int done = 0;" in order to guard against initializing these multiple times, but this does not work when several threads try to initialize these VLCs concurrently, which can happen when initializing several parsers at the same time (they don't use the global lock that is used for codecs without the FF_CODEC_CAP_INIT_THREADSAFE cap; actually, they don't use any lock at all). Since ff_mpeg4_decode_picture_header() now aborts early when called from the parser, it no longer needs to have these VLCs initialized at all. This commit therefore does exactly this. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec/mpeg4videodec.c')
-rw-r--r--libavcodec/mpeg4videodec.c50
1 files changed, 21 insertions, 29 deletions
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index ab8d2e8236..325593a795 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3386,34 +3386,6 @@ end:
return decode_vop_header(ctx, gb, parse_only);
}
-av_cold void ff_mpeg4videodec_static_init(void) {
- static int done = 0;
-
- if (!done) {
- 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);
- INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
- &ff_mpeg4_DCtab_lum[0][1], 2, 1,
- &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
- INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */,
- &ff_mpeg4_DCtab_chrom[0][1], 2, 1,
- &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512);
- INIT_VLC_STATIC_FROM_LENGTHS(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15,
- ff_sprite_trajectory_lens, 1,
- NULL, 0, 0, 0, 0, 128);
- INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4,
- &ff_mb_type_b_tab[0][1], 2, 1,
- &ff_mb_type_b_tab[0][0], 2, 1, 16);
- done = 1;
- }
-}
-
int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
{
Mpeg4DecContext *ctx = avctx->priv_data;
@@ -3525,6 +3497,8 @@ static int mpeg4_update_thread_context_for_user(AVCodecContext *dst,
static av_cold void mpeg4_init_static(void)
{
+ static uint8_t mpeg4_rvlc_rl_tables[2][2][2 * MAX_RUN + MAX_LEVEL + 3];
+
INIT_VLC_STATIC_FROM_LENGTHS(&studio_luma_dc, STUDIO_INTRA_BITS, 19,
&ff_mpeg4_studio_dc_luma[0][1], 2,
&ff_mpeg4_studio_dc_luma[0][0], 2, 1,
@@ -3547,7 +3521,25 @@ static av_cold void mpeg4_init_static(void)
0, INIT_VLC_STATIC_OVERLONG, NULL);
offset += studio_intra_tab[i].table_size;
}
- ff_mpeg4videodec_static_init();
+
+ 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);
+ INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
+ &ff_mpeg4_DCtab_lum[0][1], 2, 1,
+ &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
+ INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */,
+ &ff_mpeg4_DCtab_chrom[0][1], 2, 1,
+ &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512);
+ INIT_VLC_STATIC_FROM_LENGTHS(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15,
+ ff_sprite_trajectory_lens, 1,
+ NULL, 0, 0, 0, 0, 128);
+ INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4,
+ &ff_mb_type_b_tab[0][1], 2, 1,
+ &ff_mb_type_b_tab[0][0], 2, 1, 16);
}
static av_cold int decode_init(AVCodecContext *avctx)