#include <stdio.h>
#include "libavutil/channel_layout.h"
+#include "libavutil/mem_internal.h"
+#include "libavutil/thread.h"
#define BITSTREAM_READER_LE
#include "avcodec.h"
value = get_vlc2(gb, vlc->table, vlc->bits, depth);
/* stage-2, 3 bits exponent escape sequence */
- if (value-- == 0)
+ if (value < 0)
value = get_bits(gb, get_bits(gb, 3) + 1);
/* stage-3, optional */
}
for (k = 0; k < run; k++) {
if (j + k < 128) {
- if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) {
+ int sbjk = sb + (j + k) / 64;
+ if (sbjk > 29) {
+ SAMPLES_NEEDED
+ continue;
+ }
+ if (coding_method[ch][sbjk][(j + k) % 64] > coding_method[ch][sb][j]) {
if (k > 0) {
SAMPLES_NEEDED
//not debugged, almost never used
}
offset += (n - 2);
} else {
+ if (local_int_10 <= 2) {
+ av_log(NULL, AV_LOG_ERROR, "qdm2_fft_decode_tones() stuck\n");
+ return;
+ }
offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2);
while (offset >= (local_int_10 - 1)) {
offset += (1 - (local_int_10 - 1));
if (q->frequency_range > (local_int_14 + 1)) {
int sub_packet = (local_int_20 + local_int_28);
+ if (q->fft_coefs_index + stereo >= FF_ARRAY_ELEMS(q->fft_coefs))
+ return;
+
qdm2_fft_init_coefficient(q, sub_packet, offset, duration,
channel, exp, phase);
if (stereo)
/**
* Init static data (does not depend on specific file)
- *
- * @param q context
*/
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;
+ ff_mpa_synth_init_float();
}
/**
*/
static av_cold int qdm2_decode_init(AVCodecContext *avctx)
{
+ static AVOnce init_static_once = AV_ONCE_INIT;
QDM2Context *s = avctx->priv_data;
int tmp_val, tmp, size;
GetByteContext gb;
- qdm2_init_static_data();
-
/* extradata parsing
Structure:
s->group_size = bytestream2_get_be32(&gb);
s->fft_size = bytestream2_get_be32(&gb);
s->checksum_size = bytestream2_get_be32(&gb);
- if (s->checksum_size >= 1U << 28) {
- av_log(avctx, AV_LOG_ERROR, "data block size too large (%u)\n", s->checksum_size);
+ if (s->checksum_size >= 1U << 28 || s->checksum_size <= 1) {
+ av_log(avctx, AV_LOG_ERROR, "data block size invalid (%u)\n", s->checksum_size);
return AVERROR_INVALIDDATA;
}
s->fft_order = av_log2(s->fft_size) + 1;
+ // Fail on unknown fft order
+ if ((s->fft_order < 7) || (s->fft_order > 9)) {
+ avpriv_request_sample(avctx, "Unknown FFT order %d", s->fft_order);
+ return AVERROR_PATCHWELCOME;
+ }
+
// 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
s->sub_sampling = s->fft_order - 7;
s->frequency_range = 255 / (1 << (2 - s->sub_sampling));
+ if (s->frame_size * 4 >> s->sub_sampling > MPA_FRAME_SIZE) {
+ avpriv_request_sample(avctx, "large frames");
+ return AVERROR_PATCHWELCOME;
+ }
+
switch ((s->sub_sampling * 2 + s->channels - 1)) {
case 0: tmp = 40; break;
case 1: tmp = 48; break;
else
s->coeff_per_sb_select = 2;
- // Fail on unknown fft order
- if ((s->fft_order < 7) || (s->fft_order > 9)) {
- avpriv_request_sample(avctx, "Unknown FFT order %d", s->fft_order);
- return AVERROR_PATCHWELCOME;
- }
if (s->fft_size != (1 << (s->fft_order - 1))) {
av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size);
return AVERROR_INVALIDDATA;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ ff_thread_once(&init_static_once, qdm2_init_static_data);
+
return 0;
}
return s->checksum_size;
}
-AVCodec ff_qdm2_decoder = {
+const AVCodec ff_qdm2_decoder = {
.name = "qdm2",
.long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"),
.type = AVMEDIA_TYPE_AUDIO,
.init = qdm2_decode_init,
.close = qdm2_decode_close,
.decode = qdm2_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};