]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/commitdiff
avcodec_decode_audio2()
authormichael <michael@9553f0bf-9b14-0410-a0b8-cfaf0461ba5b>
Sun, 14 Jan 2007 23:50:06 +0000 (23:50 +0000)
committermichael <michael@9553f0bf-9b14-0410-a0b8-cfaf0461ba5b>
Sun, 14 Jan 2007 23:50:06 +0000 (23:50 +0000)
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

git-svn-id: file:///var/local/repositories/ffmpeg/trunk@7518 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

libavcodec/avcodec.h
libavcodec/flac.c
libavcodec/pcm.c
libavcodec/utils.c

index 8c908105ccc85e6c6a10601b79b10a818beb5160..ed92f1a980e89c0ea7bfd5029f5b9681f24512ac 100644 (file)
@@ -2511,18 +2511,21 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v
  */
 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.
  *
  * @param avctx the codec context.
  * @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_size the input buffer size
  * @return 0 if successful, -1 if not.
  */
-
-int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
+int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples,
                          int *frame_size_ptr,
                          uint8_t *buf, int buf_size);
 int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
index 6c64ad0a1b83525a0e5894b320dab87692cfa92e..e704d990e39beb0bdcc4bdbc6bfbcbeb1ce34735 100644 (file)
@@ -454,7 +454,7 @@ static inline int decode_subframe(FLACContext *s, int channel)
     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 decorrelation, bps, blocksize, samplerate;
@@ -516,6 +516,9 @@ static int decode_frame(FLACContext *s)
         return -1;
     }
 
+    if(blocksize * s->channels * sizeof(int16_t) > alloc_data_size)
+        return -1;
+
     if (sample_rate_code == 0){
         samplerate= s->samplerate;
     }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;
     int tmp = 0, i, j = 0, input_buf_size = 0;
     int16_t *samples = data;
+    int alloc_data_size= *data_size;
+
+    *data_size=0;
 
     if(s->max_framesize == 0){
         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
         }
         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");
             s->bitstream_size=0;
             s->bitstream_index=0;
index 26c38b329831bbdf7887d730f55d587835bac38a..4011ed3b57c7c67b4afb3f9c19d3607044a5866e 100644 (file)
@@ -410,8 +410,8 @@ static int pcm_decode_frame(AVCodecContext *avctx,
     samples = data;
     src = buf;
 
-    if(buf_size > AVCODEC_MAX_AUDIO_FRAME_SIZE/2)
-        buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE/2;
+    buf_size= FFMIN(buf_size, *data_size/2);
+    *data_size=0;
 
     switch(avctx->codec->id) {
     case CODEC_ID_PCM_S32LE:
index 899061ec2727db3c99c38641be01c71260414a65..f6f06136030a94f82900c77363c580f4a72d4ef4 100644 (file)
@@ -918,22 +918,44 @@ int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
    *number of bytes used. If no frame could be decompressed,
    *frame_size_ptr is zero. Otherwise, it is the decompressed frame
    *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,
                          uint8_t *buf, int buf_size)
 {
     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){
         ret = avctx->codec->decode(avctx, samples, frame_size_ptr,
                                 buf, buf_size);
         avctx->frame_number++;
-    }else
+    }else{
         ret= 0;
+        *frame_size_ptr=0;
+    }
     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
    *number of bytes used. If no subtitle could be decompressed,
    *got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */