dirac: make initialization of arithmetic coder tables threadsafe.

pull/131/merge
Ronald S. Bultje 8 years ago
parent 64b5539985
commit 5ba8c3a0ed
  1. 15
      libavcodec/dirac_arith.c
  2. 1
      libavcodec/dirac_arith.h
  3. 9
      libavcodec/diracdec.c

@ -83,6 +83,16 @@ const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT] = {
int16_t ff_dirac_prob_branchless[256][2]; 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) void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length)
{ {
int i; int i;
@ -106,11 +116,6 @@ void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length)
c->counter = -16; c->counter = -16;
c->range = 0xffff; 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++) for (i = 0; i < DIRAC_CTX_COUNT; i++)
c->contexts[i] = 0x8000; c->contexts[i] = 0x8000;
} }

@ -190,6 +190,7 @@ static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ct
return ret; return ret;
} }
void ff_dirac_init_arith_tables(void);
void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length); void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
#endif /* AVCODEC_DIRAC_ARITH_H */ #endif /* AVCODEC_DIRAC_ARITH_H */

@ -26,6 +26,7 @@
* @author Marco Gerards <marco@gnu.org>, David Conrad, Jordi Ortiz <nenjordi@gmail.com> * @author Marco Gerards <marco@gnu.org>, David Conrad, Jordi Ortiz <nenjordi@gmail.com>
*/ */
#include "libavutil/thread.h"
#include "avcodec.h" #include "avcodec.h"
#include "get_bits.h" #include "get_bits.h"
#include "bytestream.h" #include "bytestream.h"
@ -379,10 +380,12 @@ static void free_sequence_buffers(DiracContext *s)
av_freep(&s->mcscratch); av_freep(&s->mcscratch);
} }
static AVOnce dirac_arith_init = AV_ONCE_INIT;
static av_cold int dirac_decode_init(AVCodecContext *avctx) static av_cold int dirac_decode_init(AVCodecContext *avctx)
{ {
DiracContext *s = avctx->priv_data; DiracContext *s = avctx->priv_data;
int i; int i, ret;
s->avctx = avctx; s->avctx = avctx;
s->frame_number = -1; s->frame_number = -1;
@ -404,6 +407,9 @@ static av_cold int dirac_decode_init(AVCodecContext *avctx)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
} }
ret = ff_thread_once(&dirac_arith_init, ff_dirac_init_arith_tables);
if (ret != 0)
return AVERROR_UNKNOWN;
return 0; return 0;
} }
@ -2299,5 +2305,6 @@ AVCodec ff_dirac_decoder = {
.close = dirac_decode_end, .close = dirac_decode_end,
.decode = dirac_decode_frame, .decode = dirac_decode_frame,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DR1, .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, .flush = dirac_decode_flush,
}; };

Loading…
Cancel
Save