diff options
Diffstat (limited to 'libavcodec/qdm2.c')
-rw-r--r-- | libavcodec/qdm2.c | 135 |
1 files changed, 90 insertions, 45 deletions
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 94bda91..339fe4b 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -5,20 +5,20 @@ * Copyright (c) 2005 Alex Beregszaszi * Copyright (c) 2005 Roberto Togni * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -168,7 +168,7 @@ typedef struct { /// I/O data const uint8_t *compressed_data; int compressed_size; - float output_buffer[QDM2_MAX_FRAME_SIZE * 2]; + float output_buffer[QDM2_MAX_FRAME_SIZE * MPA_MAX_CHANNELS * 2]; /// Synthesis filter MPADSPContext mpadsp; @@ -375,7 +375,14 @@ static int qdm2_get_vlc(GetBitContext *gb, VLC *vlc, int flag, int depth) /* stage-3, optional */ if (flag) { - int tmp = vlc_stage3_values[value]; + int tmp; + + if (value >= 60) { + av_log(NULL, AV_LOG_ERROR, "value %d in qdm2_get_vlc too large\n", value); + return 0; + } + + tmp= vlc_stage3_values[value]; if ((value & ~3) > 0) tmp += get_bits(gb, (value >> 2)); @@ -694,7 +701,8 @@ static void fill_coding_method_array(sb_int8_array tone_level_idx, if (!superblocktype_2_3) { /* This case is untested, no samples available */ - SAMPLES_NEEDED + avpriv_request_sample(NULL, "!superblocktype_2_3"); + return; for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) { for (j = 1; j < 63; j++) { // The loop only iterates to 63 so the code doesn't overflow the buffer @@ -730,7 +738,7 @@ static void fill_coding_method_array(sb_int8_array tone_level_idx, for (j = 0; j < 64; j++) acc += tone_level_idx_temp[ch][sb][j]; - multres = 0x66666667 * (acc * 10); + multres = 0x66666667LL * (acc * 10); esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); for (ch = 0; ch < nb_channels; ch++) for (sb = 0; sb < 30; sb++) @@ -806,7 +814,7 @@ static void fill_coding_method_array(sb_int8_array tone_level_idx, * @param sb_min lower subband processed (sb_min included) * @param sb_max higher subband processed (sb_max excluded) */ -static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, +static int synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max) { int sb, j, k, n, ch, run, channels; @@ -814,14 +822,15 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, int type34_first; float type34_div = 0; float type34_predictor; - float samples[10], sign_bits[16]; + float samples[10]; + int sign_bits[16] = {0}; if (length == 0) { // If no data use noise for (sb=sb_min; sb < sb_max; sb++) build_sb_samples_from_noise(q, sb); - return; + return 0; } for (sb = sb_min; sb < sb_max; sb++) { @@ -845,6 +854,7 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, if (fix_coding_method_array(sb, q->nb_channels, q->coding_method)) { + av_log(NULL, AV_LOG_ERROR, "coding method invalid\n"); build_sb_samples_from_noise(q, sb); continue; } @@ -869,6 +879,11 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, } } else { n = get_bits(gb, 8); + if (n >= 243) { + av_log(NULL, AV_LOG_ERROR, "Invalid 8bit codeword\n"); + return AVERROR_INVALIDDATA; + } + for (k = 0; k < 5; k++) samples[2 * k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; } @@ -905,6 +920,11 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, } } else { n = get_bits (gb, 8); + if (n >= 243) { + av_log(NULL, AV_LOG_ERROR, "Invalid 8bit codeword\n"); + return AVERROR_INVALIDDATA; + } + for (k = 0; k < 5; k++) samples[k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; } @@ -918,6 +938,11 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, case 24: if (get_bits_left(gb) >= 7) { n = get_bits(gb, 7); + if (n >= 125) { + av_log(NULL, AV_LOG_ERROR, "Invalid 7bit codeword\n"); + return AVERROR_INVALIDDATA; + } + for (k = 0; k < 3; k++) samples[k] = (random_dequant_type24[n][k] - 2.0) * 0.5; } else { @@ -930,10 +955,11 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, case 30: if (get_bits_left(gb) >= 4) { unsigned index = qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1); - if (index < FF_ARRAY_ELEMS(type30_dequant)) { - samples[0] = type30_dequant[index]; - } else - samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + if (index >= FF_ARRAY_ELEMS(type30_dequant)) { + av_log(NULL, AV_LOG_ERROR, "index %d out of type30_dequant array\n", index); + return AVERROR_INVALIDDATA; + } + samples[0] = type30_dequant[index]; } else samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); @@ -949,11 +975,12 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, type34_first = 0; } else { unsigned index = qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1); - if (index < FF_ARRAY_ELEMS(type34_delta)) { - samples[0] = type34_delta[index] / type34_div + type34_predictor; - type34_predictor = samples[0]; - } else - samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + if (index >= FF_ARRAY_ELEMS(type34_delta)) { + av_log(NULL, AV_LOG_ERROR, "index %d out of type34_delta array\n", index); + return AVERROR_INVALIDDATA; + } + samples[0] = type34_delta[index] / type34_div + type34_predictor; + type34_predictor = samples[0]; } } else { samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); @@ -990,6 +1017,7 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, } // j loop } // channel loop } // subband loop + return 0; } /** @@ -1002,24 +1030,27 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, * @param quantized_coeffs pointer to quantized_coeffs[ch][0] * @param gb bitreader context */ -static void init_quantized_coeffs_elem0(int8_t *quantized_coeffs, +static int init_quantized_coeffs_elem0(int8_t *quantized_coeffs, GetBitContext *gb) { int i, k, run, level, diff; if (get_bits_left(gb) < 16) - return; + return -1; level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2); quantized_coeffs[0] = level; for (i = 0; i < 7; ) { if (get_bits_left(gb) < 16) - break; + return -1; run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1) + 1; + if (i + run >= 8) + return -1; + if (get_bits_left(gb) < 16) - break; + return -1; diff = qdm2_get_se_vlc(&vlc_tab_diff, gb, 2); for (k = 1; k <= run; k++) @@ -1028,6 +1059,7 @@ static void init_quantized_coeffs_elem0(int8_t *quantized_coeffs, level += diff; i += run; } + return 0; } /** @@ -1102,7 +1134,7 @@ static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb) * @param q context * @param node pointer to node with packet */ -static void process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) +static int process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) { GetBitContext gb; int i, j, k, n, ch, run, level, diff; @@ -1120,6 +1152,9 @@ static void process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2); + if (j + run >= 8) + return -1; + for (k = 1; k <= run; k++) q->quantized_coeffs[ch][i][j + k] = (level + ((k * diff) / run)); @@ -1131,6 +1166,8 @@ static void process_subpacket_9(QDM2Context *q, QDM2SubPNode *node) for (ch = 0; ch < q->nb_channels; ch++) for (i = 0; i < 8; i++) q->quantized_coeffs[ch][0][i] = 0; + + return 0; } /** @@ -1200,7 +1237,7 @@ static void process_subpacket_12(QDM2Context *q, QDM2SubPNode *node) synthfilt_build_sb_samples(q, &gb, length, 8, QDM2_SB_USED(q->sub_sampling)); } -/* +/** * Process new subpackets for synthesis filter * * @param q context @@ -1233,7 +1270,7 @@ static void process_synthesis_subpackets(QDM2Context *q, QDM2SubPNode *list) process_subpacket_12(q, NULL); } -/* +/** * Decode superblock, fill packet lists. * * @param q context @@ -1393,9 +1430,14 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, local_int_10 = 1 << (q->group_order - duration - 1); offset = 1; - while (1) { + while (get_bits_left(gb)>0) { if (q->superblocktype_2_3) { while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { + if (get_bits_left(gb)<0) { + if(local_int_4 < q->group_size) + av_log(NULL, AV_LOG_ERROR, "overread in qdm2_fft_decode_tones()\n"); + return; + } offset = 1; if (n == 0) { local_int_4 += local_int_10; @@ -1708,12 +1750,19 @@ static void qdm2_synthesis_filter(QDM2Context *q, int index) * * @param q context */ -static av_cold void qdm2_init_static_data(AVCodec *codec) { +static av_cold void qdm2_init_static_data(void) { + static int done; + + if(done) + return; + qdm2_init_vlc(); ff_mpa_synth_init_float(ff_mpa_synth_window_float); softclip_table_init(); rnd_table_init(); init_noise_samples(); + + done = 1; } /** @@ -1726,6 +1775,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) int extradata_size; int tmp_val, tmp, size; + qdm2_init_static_data(); + /* extradata parsing Structure: @@ -1814,8 +1865,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata); extradata += 4; - if (s->channels <= 0 || s->channels > MPA_MAX_CHANNELS) + if (s->channels <= 0 || s->channels > MPA_MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); return AVERROR_INVALIDDATA; + } avctx->channel_layout = avctx->channels == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; @@ -1842,6 +1895,7 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) // something like max decodable tones s->group_order = av_log2(s->group_size) + 1; s->frame_size = s->group_size / 16; // 16 iterations per super block + if (s->frame_size > QDM2_MAX_FRAME_SIZE) return AVERROR_INVALIDDATA; @@ -1864,18 +1918,9 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) if ((tmp * 2240) < avctx->bit_rate) tmp_val = 4; s->cm_table_select = tmp_val; - if (s->sub_sampling == 0) - tmp = 7999; - else - tmp = ((-(s->sub_sampling -1)) & 8000) + 20000; - /* - 0: 7999 -> 0 - 1: 20000 -> 2 - 2: 28000 -> 2 - */ - if (tmp < 8000) + if (avctx->bit_rate <= 8000) s->coeff_per_sb_select = 0; - else if (tmp <= 16000) + else if (avctx->bit_rate < 16000) s->coeff_per_sb_select = 1; else s->coeff_per_sb_select = 2; @@ -1912,6 +1957,9 @@ static int qdm2_decode(QDM2Context *q, const uint8_t *in, int16_t *out) int ch, i; const int frame_size = (q->frame_size * q->channels); + if((unsigned)frame_size > FF_ARRAY_ELEMS(q->output_buffer)/2) + return -1; + /* select input buffer */ q->compressed_data = in; q->compressed_size = q->checksum_size; @@ -1983,10 +2031,8 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = 16 * s->frame_size; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; - } out = (int16_t *)frame->data[0]; for (i = 0; i < 16; i++) { @@ -2007,7 +2053,6 @@ AVCodec ff_qdm2_decoder = { .id = AV_CODEC_ID_QDM2, .priv_data_size = sizeof(QDM2Context), .init = qdm2_decode_init, - .init_static_data = qdm2_init_static_data, .close = qdm2_decode_close, .decode = qdm2_decode_frame, .capabilities = CODEC_CAP_DR1, |