summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-11-03 21:48:28 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-12-08 17:51:45 +0100
commitf86dcd007ffac5ab8098e6e222418179fe0ce17a (patch)
tree7ff3fff574ab9e62f01c268151ec67f07a8ecb53
parente67e4d43bdd2fb1b38cd460a7760359ab2d3dcca (diff)
avcodec/clearvideo: Make VLC tables static
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
-rw-r--r--libavcodec/clearvideo.c117
1 files changed, 55 insertions, 62 deletions
diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c
index ff6445b1de..7342557cd2 100644
--- a/libavcodec/clearvideo.c
+++ b/libavcodec/clearvideo.c
@@ -24,6 +24,8 @@
* ClearVideo decoder
*/
+#include "libavutil/thread.h"
+
#include "avcodec.h"
#include "bytestream.h"
#include "get_bits.h"
@@ -73,13 +75,15 @@ typedef struct CLVContext {
MVInfo mvi;
int tile_size;
int tile_shift;
- VLC dc_vlc, ac_vlc;
- LevelCodes lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V
int luma_dc_quant, chroma_dc_quant, ac_quant;
DECLARE_ALIGNED(16, int16_t, block)[64];
int top_dc[3], left_dc[4];
} CLVContext;
+static VLC dc_vlc, ac_vlc;
+static LevelCodes lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V
+static VLC_TYPE vlc_buf[16716][2];
+
static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
int ac_quant)
{
@@ -87,13 +91,13 @@ static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
int idx = 1, last = 0, val, skip;
memset(blk, 0, sizeof(*blk) * 64);
- blk[0] = get_vlc2(gb, ctx->dc_vlc.table, CLV_VLC_BITS, 3);
+ blk[0] = get_vlc2(gb, dc_vlc.table, CLV_VLC_BITS, 3);
if (!has_ac)
return 0;
while (idx < 64 && !last) {
- val = get_vlc2(gb, ctx->ac_vlc.table, CLV_VLC_BITS, 2);
+ val = get_vlc2(gb, ac_vlc.table, CLV_VLC_BITS, 2);
if (val < 0)
return AVERROR_INVALIDDATA;
if (val != 0x1BFF) {
@@ -356,7 +360,7 @@ static void mvi_update_row(MVInfo *mvi)
}
}
-static TileInfo* decode_tile_info(GetBitContext *gb, LevelCodes *lc, int level)
+static TileInfo *decode_tile_info(GetBitContext *gb, const LevelCodes *lc, int level)
{
TileInfo *ti;
int i, flags = 0;
@@ -593,7 +597,7 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data,
TileInfo *tile;
MV mv, cmv;
- tile = decode_tile_info(&c->gb, &c->lev[0], 0); // Y
+ tile = decode_tile_info(&c->gb, &lev[0], 0); // Y
if (!tile)
return AVERROR(ENOMEM);
mv = mvi_predict(&c->mvi, i, j, tile->mv);
@@ -608,14 +612,14 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data,
cmv.x /= 2;
cmv.y /= 2;
av_freep(&tile);
- tile = decode_tile_info(&c->gb, &c->lev[4], 0); // U
+ tile = decode_tile_info(&c->gb, &lev[4], 0); // U
if (!tile)
return AVERROR(ENOMEM);
ret = restore_tree(avctx, c->pic, c->prev, 1, x, y, size, tile, cmv);
if (ret < 0)
mb_ret = ret;
av_freep(&tile);
- tile = decode_tile_info(&c->gb, &c->lev[7], 0); // V
+ tile = decode_tile_info(&c->gb, &lev[7], 0); // V
if (!tile)
return AVERROR(ENOMEM);
ret = restore_tree(avctx, c->pic, c->prev, 2, x, y, size, tile, cmv);
@@ -645,12 +649,11 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data,
return mb_ret < 0 ? mb_ret : buf_size;
}
-static av_cold int build_vlc(VLC *vlc, const uint8_t counts[16],
- const uint16_t **syms)
+static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16],
+ const uint16_t **syms, unsigned *offset)
{
uint8_t lens[MAX_VLC_ENTRIES];
unsigned num = 0;
- int ret;
for (int i = 0; i < 16; i++) {
unsigned count = counts[i];
@@ -659,18 +662,51 @@ static av_cold int build_vlc(VLC *vlc, const uint8_t counts[16],
for (count += num; num < count; num++)
lens[num] = i + 1;
}
- ret = ff_init_vlc_from_lengths(vlc, CLV_VLC_BITS, num, lens, 1,
- *syms, 2, 2, 0, 0, NULL);
- if (ret < 0)
- return ret;
+ vlc->table = &vlc_buf[*offset];
+ vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset;
+ ff_init_vlc_from_lengths(vlc, CLV_VLC_BITS, num, lens, 1,
+ *syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL);
*syms += num;
- return 0;
+ *offset += vlc->table_size;
+}
+
+static av_cold void clv_init_static(void)
+{
+ const uint16_t *mv_syms = clv_mv_syms, *bias_syms = clv_bias_syms;
+
+ INIT_VLC_STATIC_FROM_LENGTHS(&dc_vlc, CLV_VLC_BITS, NUM_DC_CODES,
+ clv_dc_lens, 1,
+ clv_dc_syms, 1, 1, -63, 0, 1104);
+ INIT_VLC_STATIC_FROM_LENGTHS(&ac_vlc, CLV_VLC_BITS, NUM_AC_CODES,
+ clv_ac_bits, 1,
+ clv_ac_syms, 2, 2, 0, 0, 554);
+ for (unsigned i = 0, j = 0, k = 0, offset = 0;; i++) {
+ if (0x36F & (1 << i)) {
+ build_vlc(&lev[i].mv_cb, clv_mv_len_counts[k], &mv_syms, &offset);
+ k++;
+ }
+ if (i == FF_ARRAY_ELEMS(lev) - 1)
+ break;
+ if (0x1B7 & (1 << i)) {
+ lev[i].flags_cb.table = &vlc_buf[offset];
+ lev[i].flags_cb.table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset;
+ ff_init_vlc_from_lengths(&lev[i].flags_cb, CLV_VLC_BITS, 16,
+ clv_flags_bits[j], 1,
+ clv_flags_syms[j], 1, 1,
+ 0, INIT_VLC_STATIC_OVERLONG, NULL);
+ offset += lev[i].flags_cb.table_size;
+
+ build_vlc(&lev[i + 1].bias_cb, clv_bias_len_counts[j],
+ &bias_syms, &offset);
+ j++;
+ }
+ }
}
static av_cold int clv_decode_init(AVCodecContext *avctx)
{
+ static AVOnce init_static_once = AV_ONCE_INIT;
CLVContext *const c = avctx->priv_data;
- const uint16_t *mv_syms = clv_mv_syms, *bias_syms = clv_bias_syms;
int ret, w, h;
if (avctx->extradata_size == 110) {
@@ -711,44 +747,9 @@ static av_cold int clv_decode_init(AVCodecContext *avctx)
return AVERROR(ENOMEM);
ff_idctdsp_init(&c->idsp, avctx);
- ret = ff_init_vlc_from_lengths(&c->dc_vlc, CLV_VLC_BITS, NUM_DC_CODES,
- clv_dc_lens, 1,
- clv_dc_syms, 1, 1, -63, 0, avctx);
- if (ret) {
- av_log(avctx, AV_LOG_ERROR, "Error initialising DC VLC\n");
- return ret;
- }
- ret = ff_init_vlc_from_lengths(&c->ac_vlc, CLV_VLC_BITS, NUM_AC_CODES,
- clv_ac_bits, 1,
- clv_ac_syms, 2, 2, 0, 0, avctx);
- if (ret) {
- av_log(avctx, AV_LOG_ERROR, "Error initialising AC VLC\n");
- return ret;
- }
- for (int i = 0, j = 0, k = 0;; i++) {
- if (0x36F & (1 << i)) {
- ret = build_vlc(&c->lev[i].mv_cb, clv_mv_len_counts[k], &mv_syms);
- if (ret < 0)
- return ret;
- k++;
- }
- if (i == FF_ARRAY_ELEMS(c->lev) - 1)
- break;
- if (0x1B7 & (1 << i)) {
- ret = ff_init_vlc_from_lengths(&c->lev[i].flags_cb, CLV_VLC_BITS, 16,
- clv_flags_bits[j], 1,
- clv_flags_syms[j], 1, 1, 0, 0, avctx);
- if (ret < 0)
- return ret;
-
- ret = build_vlc(&c->lev[i + 1].bias_cb,
- clv_bias_len_counts[j], &bias_syms);
- if (ret < 0)
- return ret;
- j++;
- }
- }
+ ff_thread_once(&init_static_once, clv_init_static);
+
return 0;
}
@@ -761,14 +762,6 @@ static av_cold int clv_decode_end(AVCodecContext *avctx)
av_freep(&c->mvi.mv);
- ff_free_vlc(&c->dc_vlc);
- ff_free_vlc(&c->ac_vlc);
- for (int i = 0; i < FF_ARRAY_ELEMS(c->lev); i++) {
- ff_free_vlc(&c->lev[i].mv_cb);
- ff_free_vlc(&c->lev[i].flags_cb);
- ff_free_vlc(&c->lev[i].bias_cb);
- }
-
return 0;
}