X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavcodec%2Fsmacker.c;h=75ab5d71205eb69afa0f7e1c777ca7b4e806cc1d;hb=1ab74bc19354aedfb9afe71515952254753a75cc;hp=ffd24c11e7dd7c16db315aee2048861482e1acc9;hpb=6ffc7be5da0ece247cf26f1d6b94cd1d6af3d338;p=ffmpeg diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index ffd24c11e7d..75ab5d71205 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -62,14 +62,17 @@ typedef struct SmackVContext { int mmap_last[3], mclr_last[3], full_last[3], type_last[3]; } SmackVContext; +typedef struct HuffEntry { + uint8_t value; + uint8_t length; +} HuffEntry; + /** * Context used for code reconstructing */ typedef struct HuffContext { int current; - uint32_t bits[256]; - uint8_t lengths[256]; - uint8_t values[256]; + HuffEntry entries[256]; } HuffContext; /* common parameters used for decode_bigtree */ @@ -105,7 +108,7 @@ enum SmkBlockTypes { * Can read SMKTREE_DECODE_MAX_RECURSION before the first check; * does not overread gb on success. */ -static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) +static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, int length) { if (length > SMKTREE_DECODE_MAX_RECURSION || length > 3 * SMKTREE_BITS) { av_log(NULL, AV_LOG_ERROR, "Maximum tree recursion level exceeded.\n"); @@ -119,18 +122,15 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref } if (get_bits_left(gb) < 8) return AVERROR_INVALIDDATA; - hc->bits[hc->current] = prefix; - hc->lengths[hc->current] = length; - hc->values[hc->current] = get_bits(gb, 8); - hc->current++; + hc->entries[hc->current++] = (HuffEntry){ get_bits(gb, 8), length }; return 0; } else { //Node int r; length++; - r = smacker_decode_tree(gb, hc, prefix, length); + r = smacker_decode_tree(gb, hc, length); if(r) return r; - return smacker_decode_tree(gb, hc, prefix | (1U << (length - 1)), length); + return smacker_decode_tree(gb, hc, length); } } @@ -216,22 +216,21 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int i ? "high" : "low"); continue; } - err = smacker_decode_tree(gb, &h, 0, 0); + err = smacker_decode_tree(gb, &h, 0); if (err < 0) goto error; skip_bits1(gb); if (h.current > 1) { - err = ff_init_vlc_sparse(&vlc[i], SMKTREE_BITS, h.current, - INIT_VLC_DEFAULT_SIZES(h.lengths), - INIT_VLC_DEFAULT_SIZES(h.bits), - INIT_VLC_DEFAULT_SIZES(h.values), - INIT_VLC_LE); + err = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current, + &h.entries[0].length, sizeof(*h.entries), + &h.entries[0].value, sizeof(*h.entries), 1, + 0, INIT_VLC_OUTPUT_LE, smk->avctx); if (err < 0) { av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); goto error; } } else - ctx.vals[i] = h.values[0]; + ctx.vals[i] = h.entries[0].value; } escapes[0] = get_bits(gb, 16); @@ -448,6 +447,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case SMK_BLK_FULL: mode = 0; if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes + if (get_bits_left(&gb) < 1) + return AVERROR_INVALIDDATA; if(get_bits1(&gb)) mode = 1; else if(get_bits1(&gb)) mode = 2; } @@ -648,21 +649,20 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, HuffContext h; h.current = 0; skip_bits1(&gb); - if ((ret = smacker_decode_tree(&gb, &h, 0, 0)) < 0) + if ((ret = smacker_decode_tree(&gb, &h, 0)) < 0) goto error; skip_bits1(&gb); if (h.current > 1) { - ret = ff_init_vlc_sparse(&vlc[i], SMKTREE_BITS, h.current, - INIT_VLC_DEFAULT_SIZES(h.lengths), - INIT_VLC_DEFAULT_SIZES(h.bits), - INIT_VLC_DEFAULT_SIZES(h.values), - INIT_VLC_LE); + ret = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current, + &h.entries[0].length, sizeof(*h.entries), + &h.entries[0].value, sizeof(*h.entries), 1, + 0, INIT_VLC_OUTPUT_LE, avctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); goto error; } } else - values[i] = h.values[0]; + values[i] = h.entries[0].value; } /* this codec relies on wraparound instead of clipping audio */ if(bits) { //decode 16-bit data @@ -720,7 +720,7 @@ error: return ret; } -AVCodec ff_smacker_decoder = { +const AVCodec ff_smacker_decoder = { .name = "smackvid", .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), .type = AVMEDIA_TYPE_VIDEO, @@ -730,10 +730,10 @@ AVCodec ff_smacker_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, }; -AVCodec ff_smackaud_decoder = { +const AVCodec ff_smackaud_decoder = { .name = "smackaud", .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), .type = AVMEDIA_TYPE_AUDIO, @@ -741,4 +741,5 @@ AVCodec ff_smackaud_decoder = { .init = smka_decode_init, .decode = smka_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, };