diff mbox series

[FFmpeg-devel,199/217] avcodec/dca*: Make decoder init-threadsafe

Message ID 20201202042244.519127-65-andreas.rheinhardt@gmail.com
State Accepted
Commit 7d4f1f4d99a95e30a7d5b85dc591e388b2f9f3bd
Headers show
Series [FFmpeg-devel,01/45] avcodec/a64multienc: Fix memleak upon init failure
Related show

Checks

Context Check Description
andriy/x86 warning Failed to apply patch

Commit Message

Andreas Rheinhardt Dec. 2, 2020, 4:22 a.m. UTC
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/dca_lbr.c | 10 +---------
 libavcodec/dca_lbr.h |  1 +
 libavcodec/dcadec.c  | 14 +++++++++++---
 libavcodec/dcahuff.c |  6 ------
 4 files changed, 13 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/dca_lbr.c b/libavcodec/dca_lbr.c
index 747fdafd3e..1016a0823d 100644
--- a/libavcodec/dca_lbr.c
+++ b/libavcodec/dca_lbr.c
@@ -123,21 +123,15 @@  static const uint16_t channel_layouts[7] = {
 static float    cos_tab[256];
 static float    lpc_tab[16];
 
-static av_cold void init_tables(void)
+av_cold void ff_dca_lbr_init_tables(void)
 {
-    static int initialized;
     int i;
 
-    if (initialized)
-        return;
-
     for (i = 0; i < 256; i++)
         cos_tab[i] = cos(M_PI * i / 128);
 
     for (i = 0; i < 16; i++)
         lpc_tab[i] = sin((i - 8) * (M_PI / ((i < 8) ? 17 : 15)));
-
-    initialized = 1;
 }
 
 static int parse_lfe_24(DCALbrDecoder *s)
@@ -1817,8 +1811,6 @@  av_cold void ff_dca_lbr_flush(DCALbrDecoder *s)
 
 av_cold int ff_dca_lbr_init(DCALbrDecoder *s)
 {
-    init_tables();
-
     if (!(s->fdsp = avpriv_float_dsp_alloc(0)))
         return AVERROR(ENOMEM);
 
diff --git a/libavcodec/dca_lbr.h b/libavcodec/dca_lbr.h
index 6d4c0a8a63..17472d6dee 100644
--- a/libavcodec/dca_lbr.h
+++ b/libavcodec/dca_lbr.h
@@ -129,6 +129,7 @@  typedef struct DCALbrDecoder {
 int ff_dca_lbr_parse(DCALbrDecoder *s, uint8_t *data, DCAExssAsset *asset);
 int ff_dca_lbr_filter_frame(DCALbrDecoder *s, AVFrame *frame);
 av_cold void ff_dca_lbr_flush(DCALbrDecoder *s);
+av_cold void ff_dca_lbr_init_tables(void);
 av_cold int ff_dca_lbr_init(DCALbrDecoder *s);
 av_cold void ff_dca_lbr_close(DCALbrDecoder *s);
 
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 4146a85ec5..be860d4cc7 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -20,6 +20,7 @@ 
 
 #include "libavutil/opt.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/thread.h"
 
 #include "dcadec.h"
 #include "dcahuff.h"
@@ -318,8 +319,15 @@  static av_cold int dcadec_close(AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold void dcadec_init_static(void)
+{
+    ff_dca_lbr_init_tables();
+    ff_dca_init_vlcs();
+}
+
 static av_cold int dcadec_init(AVCodecContext *avctx)
 {
+    static AVOnce init_static_once = AV_ONCE_INIT;
     DCAContext *s = avctx->priv_data;
 
     s->avctx = avctx;
@@ -328,8 +336,6 @@  static av_cold int dcadec_init(AVCodecContext *avctx)
     s->xll.avctx = avctx;
     s->lbr.avctx = avctx;
 
-    ff_dca_init_vlcs();
-
     if (ff_dca_core_init(&s->core) < 0)
         return AVERROR(ENOMEM);
 
@@ -362,6 +368,8 @@  static av_cold int dcadec_init(AVCodecContext *avctx)
         break;
     }
 
+    ff_thread_once(&init_static_once, dcadec_init_static);
+
     return 0;
 }
 
@@ -396,5 +404,5 @@  AVCodec ff_dca_decoder = {
                                                       AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE },
     .priv_class     = &dcadec_class,
     .profiles       = NULL_IF_CONFIG_SMALL(ff_dca_profiles),
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff --git a/libavcodec/dcahuff.c b/libavcodec/dcahuff.c
index 0a3eeb4d22..6197ccfe9b 100644
--- a/libavcodec/dcahuff.c
+++ b/libavcodec/dcahuff.c
@@ -1263,12 +1263,8 @@  VLC     ff_dca_vlc_rsd;
 av_cold void ff_dca_init_vlcs(void)
 {
     static VLC_TYPE dca_table[30214][2];
-    static int vlcs_initialized = 0;
     int i, j, k = 0;
 
-    if (vlcs_initialized)
-        return;
-
 #define DCA_INIT_VLC(vlc, a, b, c, d)                                       \
     do {                                                                    \
         vlc.table           = &dca_table[vlc_offs[k]];                      \
@@ -1331,8 +1327,6 @@  av_cold void ff_dca_init_vlcs(void)
     LBR_INIT_VLC(ff_dca_vlc_grid_2,      grid_2,      9);
     LBR_INIT_VLC(ff_dca_vlc_grid_3,      grid_3,      9);
     LBR_INIT_VLC(ff_dca_vlc_rsd,         rsd,         6);
-
-    vlcs_initialized = 1;
 }
 
 uint32_t ff_dca_vlc_calc_quant_bits(int *values, uint8_t n, uint8_t sel, uint8_t table)