Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Subject: [FFmpeg-devel] [PATCH 06/10] avcodec/mpeg4videodec: Fix data race when initializing VLCs
Date: Wed,  5 Jan 2022 22:56:06 +0100
Message-ID: <AM7PR03MB66602AC5F7535E669BA16F858F4B9@AM7PR03MB6660.eurprd03.prod.outlook.com> (raw)
In-Reply-To: <AM7PR03MB6660E16D4E4345D825454C178F4B9@AM7PR03MB6660.eurprd03.prod.outlook.com>

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>
---
 libavcodec/mpeg4video.h        |  1 -
 libavcodec/mpeg4video_parser.c |  2 --
 libavcodec/mpeg4videodec.c     | 50 ++++++++++++++--------------------
 3 files changed, 21 insertions(+), 32 deletions(-)

diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index ee8eea7121..cec8b30c32 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -173,7 +173,6 @@ int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s);
 int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx);
 int ff_mpeg4_decode_studio_slice_header(Mpeg4DecContext *ctx);
 void ff_mpeg4_init_direct_mv(MpegEncContext *s);
-void ff_mpeg4videodec_static_init(void);
 int ff_mpeg4_workaround_bugs(AVCodecContext *avctx);
 int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
 
diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c
index 9e96619a12..1f89bae490 100644
--- a/libavcodec/mpeg4video_parser.c
+++ b/libavcodec/mpeg4video_parser.c
@@ -129,8 +129,6 @@ static av_cold int mpeg4video_parse_init(AVCodecParserContext *s)
 {
     struct Mp4vParseContext *pc = s->priv_data;
 
-    ff_mpeg4videodec_static_init();
-
     pc->first_picture           = 1;
     pc->dec_ctx.m.quant_precision     = 5;
     pc->dec_ctx.m.slice_context_count = 1;
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)
-- 
2.32.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2022-01-05 21:57 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-05 21:53 [FFmpeg-devel] [PATCH 01/10] avcodec/mpeg12dec: Don't set write-only variable Andreas Rheinhardt
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 02/10] avcodec/mpegvideo: Don't unnecessarily allocate buffers Andreas Rheinhardt
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 03/10] avcodec/mpegvideo: Avoid macro/av_calloc for ordinary allocations Andreas Rheinhardt
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 04/10] avcodec/h263: Move functions only used once to their caller Andreas Rheinhardt
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 05/10] avcodec/mpeg4video: Skip unneeded element when parsing picture header Andreas Rheinhardt
2022-01-05 21:56 ` Andreas Rheinhardt [this message]
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 07/10] avcodec/rl: Don't pretend ff_rl_init() initializes a RLTable twice Andreas Rheinhardt
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 08/10] avcodec/bitstream: Don't pretend VLCs to be initialized concurrently Andreas Rheinhardt
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 09/10] avcodec: Remove unnecessary h263.h inclusions Andreas Rheinhardt
2022-01-05 21:56 ` [FFmpeg-devel] [PATCH 10/10] avcodec/avcodec: Remove outdated comment Andreas Rheinhardt
2022-01-05 22:21   ` Marvin Scholz
2022-01-06  7:08     ` Andreas Rheinhardt
2022-01-08 13:08 ` [FFmpeg-devel] [PATCH 01/10] avcodec/mpeg12dec: Don't set write-only variable Andreas Rheinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AM7PR03MB66602AC5F7535E669BA16F858F4B9@AM7PR03MB6660.eurprd03.prod.outlook.com \
    --to=andreas.rheinhardt@outlook.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git