From 5ba8c3a0ed0e43e6418eabdf8af9549c9e806382 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 27 Mar 2017 11:24:43 -0400 Subject: [PATCH] dirac: make initialization of arithmetic coder tables threadsafe. --- libavcodec/dirac_arith.c | 15 ++++++++++----- libavcodec/dirac_arith.h | 1 + libavcodec/diracdec.c | 9 ++++++++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libavcodec/dirac_arith.c b/libavcodec/dirac_arith.c index bf913928b3..7eb9bd60b2 100644 --- a/libavcodec/dirac_arith.c +++ b/libavcodec/dirac_arith.c @@ -83,6 +83,16 @@ const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT] = { int16_t ff_dirac_prob_branchless[256][2]; +av_cold void ff_dirac_init_arith_tables(void) +{ + int i; + + for (i = 0; i < 256; i++) { + ff_dirac_prob_branchless[i][0] = ff_dirac_prob[255-i]; + ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i]; + } +} + void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length) { int i; @@ -106,11 +116,6 @@ void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length) c->counter = -16; c->range = 0xffff; - for (i = 0; i < 256; i++) { - ff_dirac_prob_branchless[i][0] = ff_dirac_prob[255-i]; - ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i]; - } - for (i = 0; i < DIRAC_CTX_COUNT; i++) c->contexts[i] = 0x8000; } diff --git a/libavcodec/dirac_arith.h b/libavcodec/dirac_arith.h index 003430a48d..24a7ca390e 100644 --- a/libavcodec/dirac_arith.h +++ b/libavcodec/dirac_arith.h @@ -190,6 +190,7 @@ static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ct return ret; } +void ff_dirac_init_arith_tables(void); void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length); #endif /* AVCODEC_DIRAC_ARITH_H */ diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index e0604af103..202ae94922 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -26,6 +26,7 @@ * @author Marco Gerards , David Conrad, Jordi Ortiz */ +#include "libavutil/thread.h" #include "avcodec.h" #include "get_bits.h" #include "bytestream.h" @@ -379,10 +380,12 @@ static void free_sequence_buffers(DiracContext *s) av_freep(&s->mcscratch); } +static AVOnce dirac_arith_init = AV_ONCE_INIT; + static av_cold int dirac_decode_init(AVCodecContext *avctx) { DiracContext *s = avctx->priv_data; - int i; + int i, ret; s->avctx = avctx; s->frame_number = -1; @@ -404,6 +407,9 @@ static av_cold int dirac_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } } + ret = ff_thread_once(&dirac_arith_init, ff_dirac_init_arith_tables); + if (ret != 0) + return AVERROR_UNKNOWN; return 0; } @@ -2299,5 +2305,6 @@ AVCodec ff_dirac_decoder = { .close = dirac_decode_end, .decode = dirac_decode_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .flush = dirac_decode_flush, };