avcodec_decode_audio2()

difference to avcodec_decode_audio() is that the user can pass the allocated size of the output buffer to the decoder and the decoder can check if theres enough space

Originally committed as revision 7518 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Michael Niedermayer 18 years ago
parent aeeb0cac3d
commit ac66834c75
  1. 9
      libavcodec/avcodec.h
  2. 10
      libavcodec/flac.c
  3. 4
      libavcodec/pcm.c
  4. 28
      libavcodec/utils.c

@ -2511,18 +2511,21 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v
*/ */
int avcodec_open(AVCodecContext *avctx, AVCodec *codec); int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
attribute_deprecated int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
int *frame_size_ptr,
uint8_t *buf, int buf_size);
/** /**
* Decode an audio frame. * Decode an audio frame.
* *
* @param avctx the codec context. * @param avctx the codec context.
* @param samples output buffer, 16 byte aligned * @param samples output buffer, 16 byte aligned
* @param frame_size_ptr the output buffer size in bytes, zero if no frame could be compressed * @param frame_size_ptr the output buffer size in bytes (you MUST set this to the allocated size before calling avcodec_decode_audio2()), zero if no frame could be compressed
* @param buf input buffer, 16 byte aligned * @param buf input buffer, 16 byte aligned
* @param buf_size the input buffer size * @param buf_size the input buffer size
* @return 0 if successful, -1 if not. * @return 0 if successful, -1 if not.
*/ */
int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,
int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
int *frame_size_ptr, int *frame_size_ptr,
uint8_t *buf, int buf_size); uint8_t *buf, int buf_size);
int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,

@ -454,7 +454,7 @@ static inline int decode_subframe(FLACContext *s, int channel)
return 0; return 0;
} }
static int decode_frame(FLACContext *s) static int decode_frame(FLACContext *s, int alloc_data_size)
{ {
int blocksize_code, sample_rate_code, sample_size_code, assignment, i, crc8; int blocksize_code, sample_rate_code, sample_size_code, assignment, i, crc8;
int decorrelation, bps, blocksize, samplerate; int decorrelation, bps, blocksize, samplerate;
@ -516,6 +516,9 @@ static int decode_frame(FLACContext *s)
return -1; return -1;
} }
if(blocksize * s->channels * sizeof(int16_t) > alloc_data_size)
return -1;
if (sample_rate_code == 0){ if (sample_rate_code == 0){
samplerate= s->samplerate; samplerate= s->samplerate;
}else if ((sample_rate_code > 3) && (sample_rate_code < 12)) }else if ((sample_rate_code > 3) && (sample_rate_code < 12))
@ -579,6 +582,9 @@ static int flac_decode_frame(AVCodecContext *avctx,
FLACContext *s = avctx->priv_data; FLACContext *s = avctx->priv_data;
int tmp = 0, i, j = 0, input_buf_size = 0; int tmp = 0, i, j = 0, input_buf_size = 0;
int16_t *samples = data; int16_t *samples = data;
int alloc_data_size= *data_size;
*data_size=0;
if(s->max_framesize == 0){ if(s->max_framesize == 0){
s->max_framesize= 65536; // should hopefully be enough for the first header s->max_framesize= 65536; // should hopefully be enough for the first header
@ -617,7 +623,7 @@ static int flac_decode_frame(AVCodecContext *avctx,
goto end; // we may not have enough bits left to decode a frame, so try next time goto end; // we may not have enough bits left to decode a frame, so try next time
} }
skip_bits(&s->gb, 16); skip_bits(&s->gb, 16);
if (decode_frame(s) < 0){ if (decode_frame(s, alloc_data_size) < 0){
av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
s->bitstream_size=0; s->bitstream_size=0;
s->bitstream_index=0; s->bitstream_index=0;

@ -410,8 +410,8 @@ static int pcm_decode_frame(AVCodecContext *avctx,
samples = data; samples = data;
src = buf; src = buf;
if(buf_size > AVCODEC_MAX_AUDIO_FRAME_SIZE/2) buf_size= FFMIN(buf_size, *data_size/2);
buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE/2; *data_size=0;
switch(avctx->codec->id) { switch(avctx->codec->id) {
case CODEC_ID_PCM_S32LE: case CODEC_ID_PCM_S32LE:

@ -918,22 +918,44 @@ int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
*number of bytes used. If no frame could be decompressed, *number of bytes used. If no frame could be decompressed,
*frame_size_ptr is zero. Otherwise, it is the decompressed frame *frame_size_ptr is zero. Otherwise, it is the decompressed frame
*size in BYTES. */ *size in BYTES. */
int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,
int *frame_size_ptr, int *frame_size_ptr,
uint8_t *buf, int buf_size) uint8_t *buf, int buf_size)
{ {
int ret; int ret;
*frame_size_ptr= 0; //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough
if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){
av_log(avctx, AV_LOG_ERROR, "buffer smaller then AVCODEC_MAX_AUDIO_FRAME_SIZE\n");
return -1;
}
if(*frame_size_ptr < FF_MIN_BUFFER_SIZE ||
*frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t) ||
*frame_size_ptr < buf_size){
av_log(avctx, AV_LOG_ERROR, "buffer too small\n");
return -1;
}
if((avctx->codec->capabilities & CODEC_CAP_DELAY) || buf_size){ if((avctx->codec->capabilities & CODEC_CAP_DELAY) || buf_size){
ret = avctx->codec->decode(avctx, samples, frame_size_ptr, ret = avctx->codec->decode(avctx, samples, frame_size_ptr,
buf, buf_size); buf, buf_size);
avctx->frame_number++; avctx->frame_number++;
}else }else{
ret= 0; ret= 0;
*frame_size_ptr=0;
}
return ret; return ret;
} }
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
int *frame_size_ptr,
uint8_t *buf, int buf_size){
*frame_size_ptr= AVCODEC_MAX_AUDIO_FRAME_SIZE;
return avcodec_decode_audio2(avctx, samples, frame_size_ptr, buf, buf_size);
}
#endif
/* decode a subtitle message. return -1 if error, otherwise return the /* decode a subtitle message. return -1 if error, otherwise return the
*number of bytes used. If no subtitle could be decompressed, *number of bytes used. If no subtitle could be decompressed,
*got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ *got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */

Loading…
Cancel
Save