X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fatrac9dec.c;h=c7c6a12f010c564433c3ec81f162b0e7b5cd063b;hb=76a4356a75fd1bb79101ac00bfb73303c369dfc8;hp=805d46f3b8089d0f4842cdf3e988532d3f190c0d;hpb=ecb5546e97c479378e057f527cc1d79a46c31cb1;p=ffmpeg diff --git a/libavcodec/atrac9dec.c b/libavcodec/atrac9dec.c index 805d46f3b80..c7c6a12f010 100644 --- a/libavcodec/atrac9dec.c +++ b/libavcodec/atrac9dec.c @@ -26,6 +26,8 @@ #include "libavutil/lfg.h" #include "libavutil/float_dsp.h" +#define ATRAC9_SF_VLC_BITS 8 + typedef struct ATRAC9ChannelData { int band_ext; int q_unit_cnt; @@ -71,6 +73,8 @@ typedef struct ATRAC9BlockData { int cpe_base_channel; int is_signs[30]; + int reuseable; + } ATRAC9BlockData; typedef struct ATRAC9Context { @@ -119,10 +123,7 @@ static inline int parse_gradient(ATRAC9Context *s, ATRAC9BlockData *b, } b->grad_boundary = get_bits(gb, 4); - if (grad_range[0] >= grad_range[1] || grad_range[1] > 47) - return AVERROR_INVALIDDATA; - - if (grad_value[0] > 31 || grad_value[1] > 31) + if (grad_range[0] >= grad_range[1] || grad_range[1] > 31) return AVERROR_INVALIDDATA; if (b->grad_boundary > b->q_unit_cnt) @@ -188,7 +189,7 @@ static inline void calc_precision(ATRAC9Context *s, ATRAC9BlockData *b, for (int i = 0; i < b->q_unit_cnt; i++) { c->precision_fine[i] = 0; if (c->precision_coarse[i] > 15) { - c->precision_fine[i] = c->precision_coarse[i] - 15; + c->precision_fine[i] = FFMIN(c->precision_coarse[i], 30) - 15; c->precision_coarse[i] = 15; } } @@ -200,6 +201,8 @@ static inline int parse_band_ext(ATRAC9Context *s, ATRAC9BlockData *b, int ext_band = 0; if (b->has_band_ext) { + if (b->q_unit_cnt < 13 || b->q_unit_cnt > 20) + return AVERROR_INVALIDDATA; ext_band = at9_tab_band_ext_group[b->q_unit_cnt - 13][2]; if (stereo) { b->channel[1].band_ext = get_bits(gb, 2); @@ -222,8 +225,18 @@ static inline int parse_band_ext(ATRAC9Context *s, ATRAC9BlockData *b, b->channel[0].band_ext = get_bits(gb, 2); b->channel[0].band_ext = ext_band > 2 ? b->channel[0].band_ext : 4; - if (!get_bits(gb, 5)) + if (!get_bits(gb, 5)) { + for (int i = 0; i <= stereo; i++) { + ATRAC9ChannelData *c = &b->channel[i]; + const int count = at9_tab_band_ext_cnt[c->band_ext][ext_band]; + for (int j = 0; j < count; j++) { + int len = at9_tab_band_ext_lengths[c->band_ext][ext_band][j]; + c->band_ext_data[j] = av_clip_uintp2_c(c->band_ext_data[j], len); + } + } + return 0; + } for (int i = 0; i <= stereo; i++) { ATRAC9ChannelData *c = &b->channel[i]; @@ -241,7 +254,7 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, ATRAC9ChannelData *c, GetBitContext *gb, int channel_idx, int first_in_pkt) { - static const int mode_map[2][4] = { { 0, 1, 2, 3 }, { 0, 2, 3, 4 } }; + static const uint8_t mode_map[2][4] = { { 0, 1, 2, 3 }, { 0, 2, 3, 4 } }; const int mode = mode_map[channel_idx][get_bits(gb, 2)]; memset(c->scalefactors, 0, sizeof(c->scalefactors)); @@ -261,7 +274,8 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, c->scalefactors[0] = get_bits(gb, len); for (int i = 1; i < b->band_ext_q_unit; i++) { - int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, 9, 2); + int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, + ATRAC9_SF_VLC_BITS, 1); c->scalefactors[i] = val & ((1 << len) - 1); } @@ -291,7 +305,7 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, const VLC *tab = &s->sf_vlc[1][len]; for (int i = 0; i < unit_cnt; i++) { - int dist = get_vlc2(gb, tab->table, 9, 2); + int dist = get_vlc2(gb, tab->table, ATRAC9_SF_VLC_BITS, 1); c->scalefactors[i] = baseline[i] + dist; } @@ -314,7 +328,8 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, c->scalefactors[0] = get_bits(gb, len); for (int i = 1; i < unit_cnt; i++) { - int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, 9, 2); + int val = c->scalefactors[i - 1] + get_vlc2(gb, tab->table, + ATRAC9_SF_VLC_BITS, 1); c->scalefactors[i] = val & ((1 << len) - 1); } @@ -400,7 +415,7 @@ static inline void read_coeffs_coarse(ATRAC9Context *s, ATRAC9BlockData *b, const int groups = bands >> huff->value_cnt_pow; for (int j = 0; j < groups; j++) { - uint16_t val = get_vlc2(gb, tab->table, 9, huff->max_bit_size); + uint16_t val = get_vlc2(gb, tab->table, 9, 2); for (int k = 0; k < huff->value_cnt; k++) { coeffs[k] = sign_extend(val, huff->value_bits); @@ -535,9 +550,6 @@ static inline void apply_band_extension(ATRAC9Context *s, ATRAC9BlockData *b, at9_q_unit_to_coeff_idx[g_units[3]], }; - if (!b->has_band_ext || !b->has_band_ext_data) - return; - for (int ch = 0; ch <= stereo; ch++) { ATRAC9ChannelData *c = &b->channel[ch]; @@ -668,6 +680,7 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, if (!reuse_params) { int stereo_band, ext_band; const int min_band_count = s->samplerate_idx > 7 ? 1 : 3; + b->reuseable = 0; b->band_count = get_bits(gb, 4) + min_band_count; b->q_unit_cnt = at9_tab_band_q_unit_map[b->band_count]; @@ -699,6 +712,11 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, } b->band_ext_q_unit = at9_tab_band_q_unit_map[ext_band]; } + b->reuseable = 1; + } + if (!b->reuseable) { + av_log(s->avctx, AV_LOG_ERROR, "invalid block reused!\n"); + return AVERROR_INVALIDDATA; } /* Calculate bit alloc gradient */ @@ -741,7 +759,9 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, apply_intensity_stereo(s, b, stereo); apply_scalefactors (s, b, stereo); - apply_band_extension (s, b, stereo); + + if (b->has_band_ext && b->has_band_ext_data) + apply_band_extension (s, b, stereo); imdct: for (int i = 0; i <= stereo; i++) { @@ -818,7 +838,7 @@ static av_cold int atrac9_decode_close(AVCodecContext *avctx) ff_free_vlc(&s->coeff_vlc[i][j][k]); ff_mdct_end(&s->imdct); - av_free(s->fdsp); + av_freep(&s->fdsp); return 0; } @@ -828,11 +848,18 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx) GetBitContext gb; ATRAC9Context *s = avctx->priv_data; int version, block_config_idx, superframe_idx, alloc_c_len; + const uint8_t (*tab)[2]; + int ret; s->avctx = avctx; av_lfg_init(&s->lfg, 0xFBADF00D); + if (avctx->block_align <= 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid block align\n"); + return AVERROR_INVALIDDATA; + } + if (avctx->extradata_size != 12) { av_log(avctx, AV_LOG_ERROR, "Invalid extradata length!\n"); return AVERROR_INVALIDDATA; @@ -862,6 +889,7 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx) s->block_config = &at9_block_layout[block_config_idx]; avctx->channel_layout = s->block_config->channel_layout; + avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout); avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (get_bits1(&gb)) { @@ -905,33 +933,46 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx) s->alloc_curve[i - 1][j] = at9_tab_b_dist[(j * alloc_c_len) / i]; /* Unsigned scalefactor VLCs */ + tab = at9_sfb_a_tab; for (int i = 1; i < 7; i++) { const HuffmanCodebook *hf = &at9_huffman_sf_unsigned[i]; - init_vlc(&s->sf_vlc[0][i], 9, hf->size, hf->bits, 1, 1, hf->codes, - 2, 2, 0); + ret = ff_init_vlc_from_lengths(&s->sf_vlc[0][i], ATRAC9_SF_VLC_BITS, + hf->size, &tab[0][1], 2, + &tab[0][0], 2, 1, 0, 0, avctx); + if (ret < 0) + return ret; + tab += hf->size; } /* Signed scalefactor VLCs */ + tab = at9_sfb_b_tab; for (int i = 2; i < 6; i++) { const HuffmanCodebook *hf = &at9_huffman_sf_signed[i]; - int nums = hf->size; - int16_t sym[32]; - for (int j = 0; j < nums; j++) - sym[j] = sign_extend(j, hf->value_bits); - - ff_init_vlc_sparse(&s->sf_vlc[1][i], 9, hf->size, hf->bits, 1, 1, - hf->codes, 2, 2, sym, sizeof(*sym), sizeof(*sym), 0); + /* The symbols are signed integers in the range -16..15; + * the values in the source table are offset by 16 to make + * them fit into an uint8_t; the -16 reverses this shift. */ + ret = ff_init_vlc_from_lengths(&s->sf_vlc[1][i], ATRAC9_SF_VLC_BITS, + hf->size, &tab[0][1], 2, + &tab[0][0], 2, 1, -16, 0, avctx); + if (ret < 0) + return ret; + tab += hf->size; } /* Coefficient VLCs */ + tab = at9_coeffs_tab; for (int i = 0; i < 2; i++) { - for (int j = 0; j < 8; j++) { - for (int k = 0; k < 4; k++) { + for (int j = 2; j < 8; j++) { + for (int k = i; k < 4; k++) { const HuffmanCodebook *hf = &at9_huffman_coeffs[i][j][k]; - init_vlc(&s->coeff_vlc[i][j][k], 9, hf->size, hf->bits, 1, 1, - hf->codes, 2, 2, 0); + ret = ff_init_vlc_from_lengths(&s->coeff_vlc[i][j][k], 9, + hf->size, &tab[0][1], 2, + &tab[0][0], 2, 1, 0, 0, avctx); + if (ret < 0) + return ret; + tab += hf->size; } } }