* 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
*/
/// 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;
/* stage-3, optional */
if (flag) {
- int tmp = vlc_stage3_values[value];
+ int tmp;
+
+ if (value >= 60) {
+ av_log(0, 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));
* @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, int length, int sb_min, int sb_max)
+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;
int joined_stereo, zero_encoding, chs;
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++) {
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);
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);
} // j loop
} // channel loop
} // subband loop
+ return 0;
}
* @param quantized_coeffs pointer to quantized_coeffs[ch][0]
* @param gb bitreader context
*/
-static void init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb)
+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++)
level += diff;
i += run;
}
+ return 0;
}
* @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;
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));
for (ch = 0; ch < q->nb_channels; ch++)
for (i = 0; i < 8; i++)
q->quantized_coeffs[ch][0][i] = 0;
+
+ return 0;
}
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(0, AV_LOG_ERROR, "overread in qdm2_fft_decode_tones()\n");
+ return;
+ }
offset = 1;
if (n == 0) {
local_int_4 += local_int_10;
}
-#if 0
-static void dump_context(QDM2Context *q)
-{
- int i;
-#define PRINT(a,b) av_log(NULL,AV_LOG_DEBUG," %s = %d\n", a, b);
- PRINT("compressed_data",q->compressed_data);
- PRINT("compressed_size",q->compressed_size);
- PRINT("frame_size",q->frame_size);
- PRINT("checksum_size",q->checksum_size);
- PRINT("channels",q->channels);
- PRINT("nb_channels",q->nb_channels);
- PRINT("fft_size",q->fft_size);
- PRINT("sub_sampling",q->sub_sampling);
- PRINT("fft_order",q->fft_order);
- PRINT("group_order",q->group_order);
- PRINT("group_size",q->group_size);
- PRINT("sub_packet",q->sub_packet);
- PRINT("frequency_range",q->frequency_range);
- PRINT("has_errors",q->has_errors);
- PRINT("fft_tone_end",q->fft_tone_end);
- PRINT("fft_tone_start",q->fft_tone_start);
- PRINT("fft_coefs_index",q->fft_coefs_index);
- PRINT("coeff_per_sb_select",q->coeff_per_sb_select);
- PRINT("cm_table_select",q->cm_table_select);
- PRINT("noise_idx",q->noise_idx);
-
- for (i = q->fft_tone_start; i < q->fft_tone_end; i++)
- {
- FFTTone *t = &q->fft_tones[i];
-
- av_log(NULL,AV_LOG_DEBUG,"Tone (%d) dump:\n", i);
- av_log(NULL,AV_LOG_DEBUG," level = %f\n", t->level);
-// PRINT(" level", t->level);
- PRINT(" phase", t->phase);
- PRINT(" phase_shift", t->phase_shift);
- PRINT(" duration", t->duration);
- PRINT(" samples_im", t->samples_im);
- PRINT(" samples_re", t->samples_re);
- PRINT(" table", t->table);
- }
-
-}
-#endif
-
-
/**
* Init parameters from codec extradata
*/
avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata);
extradata += 4;
- if (s->channels > MPA_MAX_CHANNELS)
+ if (s->channels > MPA_MAX_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
return AVERROR_INVALIDDATA;
+ }
avctx->sample_rate = AV_RB32(extradata);
extradata += 4;
// 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;
avcodec_get_frame_defaults(&s->frame);
avctx->coded_frame = &s->frame;
-// dump_context(s);
return 0;
}
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;
-// dump_context(q);
-
/* copy old block, clear new block of output samples */
memmove(q->output_buffer, &q->output_buffer[frame_size], frame_size * sizeof(float));
memset(&q->output_buffer[frame_size], 0, frame_size * sizeof(float));