#include "libavutil/channel_layout.h"
#include "libavutil/intfloat.h"
+#include "libavutil/mem_internal.h"
#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "rdft.h"
#include "wma_freqs.h"
-static float quant_table[96];
-
#define MAX_CHANNELS 2
#define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11)
int overlap_len; ///< overlap size (samples)
int block_size;
int num_bands;
- unsigned int *bands;
float root;
- DECLARE_ALIGNED(32, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE];
+ unsigned int bands[26];
float previous[MAX_CHANNELS][BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block
+ float quant_table[96];
AVPacket *pkt;
union {
RDFTContext rdft;
BinkAudioContext *s = avctx->priv_data;
int sample_rate = avctx->sample_rate;
int sample_rate_half;
- int i;
+ int i, ret;
int frame_len_bits;
/* determine frame length */
if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
// audio is already interleaved for the RDFT format variant
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ if (sample_rate > INT_MAX / avctx->channels)
+ return AVERROR_INVALIDDATA;
sample_rate *= avctx->channels;
s->channels = 1;
if (!s->version_b)
s->frame_len = 1 << frame_len_bits;
s->overlap_len = s->frame_len / 16;
s->block_size = (s->frame_len - s->overlap_len) * s->channels;
- sample_rate_half = (sample_rate + 1) / 2;
+ sample_rate_half = (sample_rate + 1LL) / 2;
if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
s->root = 2.0 / (sqrt(s->frame_len) * 32768.0);
else
s->root = s->frame_len / (sqrt(s->frame_len) * 32768.0);
for (i = 0; i < 96; i++) {
/* constant is result of 0.066399999/log10(M_E) */
- quant_table[i] = expf(i * 0.15289164787221953823f) * s->root;
+ s->quant_table[i] = expf(i * 0.15289164787221953823f) * s->root;
}
/* calculate number of bands */
if (sample_rate_half <= ff_wma_critical_freqs[s->num_bands - 1])
break;
- s->bands = av_malloc((s->num_bands + 1) * sizeof(*s->bands));
- if (!s->bands)
- return AVERROR(ENOMEM);
-
/* populate bands data */
s->bands[0] = 2;
for (i = 1; i < s->num_bands; i++)
s->first = 1;
if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
- ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R);
+ ret = ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R);
else if (CONFIG_BINKAUDIO_DCT_DECODER)
- ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III);
+ ret = ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III);
else
av_assert0(0);
+ if (ret < 0)
+ return ret;
s->pkt = av_packet_alloc();
if (!s->pkt)
static float get_float(GetBitContext *gb)
{
int power = get_bits(gb, 5);
- float f = ldexpf(get_bits_long(gb, 23), power - 23);
+ float f = ldexpf(get_bits(gb, 23), power - 23);
if (get_bits1(gb))
f = -f;
return f;
return AVERROR_INVALIDDATA;
for (i = 0; i < s->num_bands; i++) {
int value = get_bits(gb, 8);
- quant[i] = quant_table[FFMIN(value, 95)];
+ quant[i] = s->quant_table[FFMIN(value, 95)];
}
k = 0;
static av_cold int decode_end(AVCodecContext *avctx)
{
BinkAudioContext * s = avctx->priv_data;
- av_freep(&s->bands);
if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
ff_rdft_end(&s->trans.rdft);
else if (CONFIG_BINKAUDIO_DCT_DECODER)
.close = decode_end,
.receive_frame = binkaudio_receive_frame,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
AVCodec ff_binkaudio_dct_decoder = {
.close = decode_end,
.receive_frame = binkaudio_receive_frame,
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};