[FFmpeg-devel] [PATCH 11/17] avcodec/ituh263dec: Make initializing VLCs thread-safe

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Sat Feb 12 08:41:25 EET 2022


This automatically makes the FLV, H.263, H.263+, Intel H.263,
MPEG-4, RealVideo 1.0 and RealVideo 2.0 decoders init-threadsafe.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 libavcodec/flvdec.c        |  3 ++-
 libavcodec/h263dec.c       |  6 ++++--
 libavcodec/intelh263dec.c  |  3 ++-
 libavcodec/ituh263dec.c    | 15 ++++++++-------
 libavcodec/mpeg4videodec.c |  3 ++-
 libavcodec/rv10.c          |  2 ++
 6 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index 2bd86b5b47..587cbb3ca5 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -122,7 +122,8 @@ const AVCodec ff_flv_decoder = {
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
-    .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
+                      FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .max_lowres     = 3,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
                                                      AV_PIX_FMT_NONE },
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 3466027286..27f9c2932c 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -772,7 +772,8 @@ const AVCodec ff_h263_decoder = {
                       AV_CODEC_CAP_TRUNCATED |
 #endif
                       AV_CODEC_CAP_DELAY,
-    .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
+                      FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
     .pix_fmts       = ff_h263_hwaccel_pixfmt_list_420,
@@ -793,7 +794,8 @@ const AVCodec ff_h263p_decoder = {
                       AV_CODEC_CAP_TRUNCATED |
 #endif
                       AV_CODEC_CAP_DELAY,
-    .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
+                      FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
     .pix_fmts       = ff_h263_hwaccel_pixfmt_list_420,
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index 9dde247298..b0009f00d7 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -138,7 +138,8 @@ const AVCodec ff_h263i_decoder = {
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
-    .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
+                      FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUV420P,
         AV_PIX_FMT_NONE
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index 445d5f3f36..6fa5249569 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -35,6 +35,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/mem_internal.h"
+#include "libavutil/thread.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -104,12 +105,8 @@ static VLC cbpc_b_vlc;
 
 /* init vlcs */
 
-/* XXX: find a better solution to handle static init */
-av_cold void ff_h263_decode_init_vlc(void)
+static av_cold void h263_decode_init_vlc(void)
 {
-    static volatile int done = 0;
-
-    if (!done) {
         INIT_VLC_STATIC(&ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9,
                  ff_h263_intra_MCBPC_bits, 1, 1,
                  ff_h263_intra_MCBPC_code, 1, 1, 72);
@@ -131,8 +128,12 @@ av_cold void ff_h263_decode_init_vlc(void)
         INIT_VLC_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4,
                  &ff_cbpc_b_tab[0][1], 2, 1,
                  &ff_cbpc_b_tab[0][0], 2, 1, 8);
-        done = 1;
-    }
+}
+
+av_cold void ff_h263_decode_init_vlc(void)
+{
+    static AVOnce init_static_once = AV_ONCE_INIT;
+    ff_thread_once(&init_static_once, h263_decode_init_vlc);
 }
 
 int ff_h263_decode_mba(MpegEncContext *s)
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 655be5697d..432d3c418c 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3672,7 +3672,8 @@ const AVCodec ff_mpeg4_decoder = {
                              AV_CODEC_CAP_TRUNCATED |
 #endif
                              AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS,
-    .caps_internal         = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
+    .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE |
+                             FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
                              FF_CODEC_CAP_ALLOCATE_PROGRESS,
     .flush                 = ff_mpeg_flush,
     .max_lowres            = 3,
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 4dfaa3460d..34f9dbf80a 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -690,6 +690,7 @@ const AVCodec ff_rv10_decoder = {
     .close          = rv10_decode_end,
     .decode         = rv10_decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .max_lowres     = 3,
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUV420P,
@@ -707,6 +708,7 @@ const AVCodec ff_rv20_decoder = {
     .close          = rv10_decode_end,
     .decode         = rv10_decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
     .pix_fmts       = (const enum AVPixelFormat[]) {
-- 
2.32.0



More information about the ffmpeg-devel mailing list