X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fqdm2.c;h=07dea55a762c76c95cfb52bbb005cacbcd652e10;hb=f34521266ec5816eefa4c10db6098cb91e03c695;hp=1e91f477e8f12aa2241edc708a3a865b23d07a34;hpb=694be24bd6c4cc9c62222f4583260bf79056e4c1;p=ffmpeg diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 1e91f477e8f..07dea55a762 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -36,6 +36,8 @@ #include #include "libavutil/channel_layout.h" +#include "libavutil/mem_internal.h" +#include "libavutil/thread.h" #define BITSTREAM_READER_LE #include "avcodec.h" @@ -205,7 +207,7 @@ static int qdm2_get_vlc(GetBitContext *gb, const VLC *vlc, int flag, int depth) 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 */ @@ -1334,6 +1336,9 @@ static void qdm2_fft_decode_tones(QDM2Context *q, int duration, 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) @@ -1591,22 +1596,14 @@ static void qdm2_synthesis_filter(QDM2Context *q, int index) /** * 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(); } /** @@ -1614,12 +1611,11 @@ static av_cold void qdm2_init_static_data(void) { */ 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: @@ -1704,8 +1700,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) 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; } @@ -1727,6 +1723,11 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) 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; @@ -1760,6 +1761,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_S16; + ff_thread_once(&init_static_once, qdm2_init_static_data); + return 0; } @@ -1875,5 +1878,6 @@ AVCodec ff_qdm2_decoder = { .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, };