summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/mpc7.c11
-rw-r--r--libavcodec/mpc8.c10
-rw-r--r--libavcodec/nellymoserdec.c57
-rw-r--r--libavcodec/w32thread.c6
4 files changed, 62 insertions, 22 deletions
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index ba8828eb52..272e1b28ba 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -197,12 +197,19 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
int i, ch;
int mb = -1;
Band *bands = c->bands;
- int off;
+ int off, out_size;
int bits_used, bits_avail;
memset(bands, 0, sizeof(bands));
if(buf_size <= 4){
av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size);
+ return AVERROR(EINVAL);
+ }
+
+ out_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4;
+ if (*data_size < out_size) {
+ av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
+ return AVERROR(EINVAL);
}
bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -277,7 +284,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
*data_size = 0;
return buf_size;
}
- *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4;
+ *data_size = out_size;
return buf_size;
}
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index 436d7baa84..2f6bde3231 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -243,10 +243,16 @@ static int mpc8_decode_frame(AVCodecContext * avctx,
GetBitContext gb2, *gb = &gb2;
int i, j, k, ch, cnt, res, t;
Band *bands = c->bands;
- int off;
+ int off, out_size;
int maxband, keyframe;
int last[2];
+ out_size = MPC_FRAME_SIZE * 2 * avctx->channels;
+ if (*data_size < out_size) {
+ av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
+ return AVERROR(EINVAL);
+ }
+
keyframe = c->cur_frame == 0;
if(keyframe){
@@ -404,7 +410,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx,
c->last_bits_used = get_bits_count(gb);
if(c->cur_frame >= c->frames)
c->cur_frame = 0;
- *data_size = MPC_FRAME_SIZE * 2 * avctx->channels;
+ *data_size = out_size;
return c->cur_frame ? c->last_bits_used >> 3 : buf_size;
}
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index 23fecbfa26..04d966173a 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -47,8 +47,8 @@
typedef struct NellyMoserDecodeContext {
AVCodecContext* avctx;
- DECLARE_ALIGNED(32, float, float_buf)[NELLY_SAMPLES];
- float state[128];
+ float *float_buf;
+ float state[NELLY_BUF_LEN];
AVLFG random_state;
GetBitContext gb;
float scale_bias;
@@ -137,15 +137,25 @@ static av_cold int decode_init(AVCodecContext * avctx) {
ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
dsputil_init(&s->dsp, avctx);
- ff_fmt_convert_init(&s->fmt_conv, avctx);
- s->scale_bias = 1.0/(1*8);
+ if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
+ s->scale_bias = 1.0/(32768*8);
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ } else {
+ s->scale_bias = 1.0/(1*8);
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ ff_fmt_convert_init(&s->fmt_conv, avctx);
+ s->float_buf = av_mallocz(NELLY_SAMPLES * sizeof(*s->float_buf));
+ if (!s->float_buf) {
+ av_log(avctx, AV_LOG_ERROR, "error allocating float buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ }
/* Generate overlap window */
if (!ff_sine_128[127])
ff_init_ff_sine_windows(7);
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
avctx->channel_layout = AV_CH_LAYOUT_MONO;
return 0;
}
@@ -157,19 +167,25 @@ static int decode_tag(AVCodecContext * avctx,
int buf_size = avpkt->size;
NellyMoserDecodeContext *s = avctx->priv_data;
int data_max = *data_size;
- int blocks, i;
- int16_t* samples;
+ int blocks, i, block_size;
+ int16_t *samples_s16 = data;
+ float *samples_flt = data;
*data_size = 0;
- samples = (int16_t*)data;
- if (buf_size < avctx->block_align)
+ if (buf_size < avctx->block_align) {
return buf_size;
+ }
- if (buf_size % 64) {
+ if (buf_size % NELLY_BLOCK_LEN) {
av_log(avctx, AV_LOG_ERROR, "Tag size %d.\n", buf_size);
return buf_size;
}
- blocks = buf_size / 64;
+ block_size = NELLY_SAMPLES * av_get_bytes_per_sample(avctx->sample_fmt);
+ blocks = FFMIN(buf_size / NELLY_BLOCK_LEN, data_max / block_size);
+ if (blocks <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
+ return AVERROR(EINVAL);
+ }
/* Normal numbers of blocks for sample rates:
* 8000 Hz - 1
* 11025 Hz - 2
@@ -179,12 +195,17 @@ static int decode_tag(AVCodecContext * avctx,
*/
for (i=0 ; i<blocks ; i++) {
- if ((i + 1) * NELLY_SAMPLES * sizeof(int16_t) > data_max)
- return i > 0 ? i * NELLY_BLOCK_LEN : -1;
- nelly_decode_block(s, &buf[i*NELLY_BLOCK_LEN], s->float_buf);
- s->fmt_conv.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES);
- *data_size += NELLY_SAMPLES*sizeof(int16_t);
+ if (avctx->sample_fmt == SAMPLE_FMT_FLT) {
+ nelly_decode_block(s, buf, samples_flt);
+ samples_flt += NELLY_SAMPLES;
+ } else {
+ nelly_decode_block(s, buf, s->float_buf);
+ s->fmt_conv.float_to_int16(samples_s16, s->float_buf, NELLY_SAMPLES);
+ samples_s16 += NELLY_SAMPLES;
+ }
+ buf += NELLY_BLOCK_LEN;
}
+ *data_size = blocks * block_size;
return buf_size;
}
@@ -192,6 +213,7 @@ static int decode_tag(AVCodecContext * avctx,
static av_cold int decode_end(AVCodecContext * avctx) {
NellyMoserDecodeContext *s = avctx->priv_data;
+ av_freep(&s->float_buf);
ff_mdct_end(&s->imdct_ctx);
return 0;
}
@@ -205,5 +227,8 @@ AVCodec ff_nellymoser_decoder = {
.close = decode_end,
.decode = decode_tag,
.long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
};
diff --git a/libavcodec/w32thread.c b/libavcodec/w32thread.c
index 501f0cebf3..def3adc0df 100644
--- a/libavcodec/w32thread.c
+++ b/libavcodec/w32thread.c
@@ -130,8 +130,10 @@ int ff_thread_init(AVCodecContext *s){
ThreadContext *c;
uint32_t threadid;
- if(!(s->thread_type & FF_THREAD_SLICE)){
- av_log(s, AV_LOG_WARNING, "The requested thread algorithm is not supported with this thread library.\n");
+ if (s->thread_type && !(s->thread_type & FF_THREAD_SLICE)) {
+ av_log(s, AV_LOG_WARNING,
+ "This thread library only supports FF_THREAD_SLICE"
+ " threading algorithm.\n");
return 0;
}