@@ -26,6 +26,8 @@
#include <inttypes.h>
+#include "libavutil/thread.h"
+
#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "bytestream.h"
@@ -34,6 +36,8 @@
#include "mathops.h"
#include "tscc2data.h"
+#define TSCC2_VLC_BITS 9
+
typedef struct TSCC2Context {
AVCodecContext *avctx;
AVFrame *pic;
@@ -43,52 +47,43 @@ typedef struct TSCC2Context {
int q[2][3];
GetBitContext gb;
- VLC dc_vlc, nc_vlc[NUM_VLC_SETS], ac_vlc[NUM_VLC_SETS];
int block[16];
} TSCC2Context;
-static av_cold void free_vlcs(TSCC2Context *c)
-{
- int i;
+static VLC dc_vlc, nc_vlc[NUM_VLC_SETS], ac_vlc[NUM_VLC_SETS];
- ff_free_vlc(&c->dc_vlc);
- for (i = 0; i < NUM_VLC_SETS; i++) {
- ff_free_vlc(c->nc_vlc + i);
- ff_free_vlc(c->ac_vlc + i);
- }
+static av_cold void tscc2_init_vlc(VLC *vlc, int *offset, int nb_codes,
+ const uint8_t *lens, const void *syms,
+ int sym_length)
+{
+ static VLC_TYPE vlc_buf[15442][2];
+
+ vlc->table = &vlc_buf[*offset];
+ vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset;
+ ff_init_vlc_from_lengths(vlc, TSCC2_VLC_BITS, nb_codes,
+ lens, 1, syms, sym_length, sym_length, 0,
+ INIT_VLC_STATIC_OVERLONG | INIT_VLC_OUTPUT_LE, NULL);
+ *offset += vlc->table_size;
}
-static av_cold int init_vlcs(TSCC2Context *c)
+static av_cold void tscc2_init_vlcs(void)
{
const uint16_t *ac_vlc_syms = tscc2_ac_vlc_syms;
const uint8_t *ac_vlc_lens = tscc2_ac_vlc_lens;
- int i, ret;
+ int i, offset = 0;
- ret = ff_init_vlc_from_lengths(&c->dc_vlc, 9, DC_VLC_COUNT,
- tscc2_dc_vlc_lens, 1,
- tscc2_dc_vlc_syms, 2, 2,
- 0, INIT_VLC_OUTPUT_LE, c->avctx);
- if (ret)
- return ret;
+ tscc2_init_vlc(&dc_vlc, &offset, DC_VLC_COUNT,
+ tscc2_dc_vlc_lens, tscc2_dc_vlc_syms, 2);
for (i = 0; i < NUM_VLC_SETS; i++) {
- ret = ff_init_vlc_from_lengths(c->nc_vlc + i, 9, 16,
- tscc2_nc_vlc_lens[i], 1,
- tscc2_nc_vlc_syms[i], 1, 1,
- 0, INIT_VLC_OUTPUT_LE, c->avctx);
- if (ret)
- return ret;
- ret = ff_init_vlc_from_lengths(c->ac_vlc + i, 9, tscc2_ac_vlc_sizes[i],
- ac_vlc_lens, 1,
- ac_vlc_syms, 2, 2,
- 0, INIT_VLC_OUTPUT_LE, c->avctx);
- if (ret)
- return ret;
+ tscc2_init_vlc(&nc_vlc[i], &offset, 16,
+ tscc2_nc_vlc_lens[i], tscc2_nc_vlc_syms[i], 1);
+
+ tscc2_init_vlc(&ac_vlc[i], &offset, tscc2_ac_vlc_sizes[i],
+ ac_vlc_lens, ac_vlc_syms, 2);
ac_vlc_lens += tscc2_ac_vlc_sizes[i];
ac_vlc_syms += tscc2_ac_vlc_sizes[i];
}
-
- return 0;
}
#define DEQUANT(val, q) (((q) * (val) + 0x80) >> 8)
@@ -154,7 +149,7 @@ static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set,
if (!(j | k)) {
dc = get_bits(gb, 8);
} else {
- dc = get_vlc2(gb, c->dc_vlc.table, 9, 2);
+ dc = get_vlc2(gb, dc_vlc.table, TSCC2_VLC_BITS, 2);
if (dc == 0x100)
dc = get_bits(gb, 8);
}
@@ -162,12 +157,12 @@ static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set,
prev_dc = dc;
c->block[0] = dc;
- nc = get_vlc2(gb, c->nc_vlc[vlc_set].table, 9, 1);
+ nc = get_vlc2(gb, nc_vlc[vlc_set].table, TSCC2_VLC_BITS, 1);
bpos = 1;
memset(c->block + 1, 0, 15 * sizeof(*c->block));
for (l = 0; l < nc; l++) {
- ac = get_vlc2(gb, c->ac_vlc[vlc_set].table, 9, 2);
+ ac = get_vlc2(gb, ac_vlc[vlc_set].table, TSCC2_VLC_BITS, 2);
if (ac == 0x1000)
ac = get_bits(gb, 12);
bpos += ac & 0xF;
@@ -330,7 +325,6 @@ static av_cold int tscc2_decode_end(AVCodecContext *avctx)
av_frame_free(&c->pic);
av_freep(&c->slice_quants);
- free_vlcs(c);
return 0;
}
@@ -338,17 +332,12 @@ static av_cold int tscc2_decode_end(AVCodecContext *avctx)
static av_cold int tscc2_decode_init(AVCodecContext *avctx)
{
TSCC2Context * const c = avctx->priv_data;
- int ret;
+ static AVOnce init_static_once = AV_ONCE_INIT;
c->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
- if ((ret = init_vlcs(c)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n");
- return ret;
- }
-
c->mb_width = FFALIGN(avctx->width, 16) >> 4;
c->mb_height = FFALIGN(avctx->height, 8) >> 3;
c->slice_quants = av_malloc(c->mb_width * c->mb_height);
@@ -361,6 +350,8 @@ static av_cold int tscc2_decode_init(AVCodecContext *avctx)
if (!c->pic)
return AVERROR(ENOMEM);
+ ff_thread_once(&init_static_once, tscc2_init_vlcs);
+
return 0;
}
Also use a named constant for the number of bits of the VLC tables. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> --- Now using ff_thread_once(). libavcodec/tscc2.c | 73 ++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 41 deletions(-)