avcodec/dca*: Make decoder init-threadsafe

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
Andreas Rheinhardt 2020-11-30 23:58:56 +01:00 committed by Andreas Rheinhardt
parent e5bc8b6236
commit 7d4f1f4d99
4 changed files with 13 additions and 18 deletions

View File

@ -124,21 +124,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)
@ -1818,8 +1812,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);

View File

@ -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);

View File

@ -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 @@ const 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,
};

View File

@ -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)