summaryrefslogtreecommitdiff
path: root/libavcodec/clearvideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/clearvideo.c')
-rw-r--r--libavcodec/clearvideo.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c
index f1dcb03f0e..39e3991053 100644
--- a/libavcodec/clearvideo.c
+++ b/libavcodec/clearvideo.c
@@ -646,9 +646,31 @@ 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)
+{
+ uint8_t lens[MAX_VLC_ENTRIES];
+ unsigned num = 0;
+ int ret;
+
+ for (int i = 0; i < 16; i++) {
+ unsigned count = counts[i];
+ if (count == 255) /* Special case for Y_3 table */
+ count = 303;
+ for (count += num; num < count; num++)
+ lens[num] = i + 1;
+ }
+ ret = ff_init_vlc_from_lengths(vlc, 9, num, lens, 1, *syms, 2, 2, 0, 0, NULL);
+ if (ret < 0)
+ return ret;
+ *syms += num;
+ return 0;
+}
+
static av_cold int clv_decode_init(AVCodecContext *avctx)
{
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) {
@@ -704,14 +726,13 @@ static av_cold int clv_decode_init(AVCodecContext *avctx)
return ret;
}
- for (int i = 0, j = 0;; i++) {
+ for (int i = 0, j = 0, k = 0;; i++) {
if (0x36F & (1 << i)) {
c->lev[i].mv_esc = clv_mv_escape[i];
- ret = ff_init_vlc_from_lengths(&c->lev[i].mv_cb, 9, clv_mv_sizes[i],
- clv_mv_bits[i], 1,
- clv_mv_syms[i], 2, 2, 0, 0, avctx);
+ 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;
@@ -723,9 +744,8 @@ static av_cold int clv_decode_init(AVCodecContext *avctx)
return ret;
c->lev[i + 1].bias_esc = 0x100;
- ret = ff_init_vlc_from_lengths(&c->lev[i + 1].bias_cb, 9, clv_bias_sizes[j],
- clv_bias_bits[j], 1,
- clv_bias_syms[j], 2, 2, 0, 0, avctx);
+ ret = build_vlc(&c->lev[i + 1].bias_cb,
+ clv_bias_len_counts[j], &bias_syms);
if (ret < 0)
return ret;
j++;