From 1bcdb8e4ef6cdbb226d2b8e9b1c763a6cb147bfd Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 12 Apr 2009 13:17:37 +0000 Subject: [PATCH] Add a av_fast_malloc function and replace several uses of av_fast_realloc, thus avoiding potential memleaks and pointless memcpys. git-svn-id: file:///var/local/repositories/ffmpeg/trunk@18470 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b --- libavcodec/4xm.c | 8 ++++++-- libavcodec/asv1.c | 4 +++- libavcodec/avcodec.h | 14 ++++++++++++++ libavcodec/eatqi.c | 2 +- libavcodec/h263dec.c | 6 ++++-- libavcodec/h264.c | 2 +- libavcodec/huffyuv.c | 4 +++- libavcodec/mdec.c | 4 +++- libavcodec/mimic.c | 2 +- libavcodec/motionpixels.c | 4 +++- libavcodec/utils.c | 11 +++++++++++ 11 files changed, 50 insertions(+), 11 deletions(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 400374287..8f6ec3a00 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -378,7 +378,9 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ return -1; } - f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!f->bitstream_buffer) + return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4); init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); @@ -656,7 +658,9 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ prestream_size= length + buf - prestream; - f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!f->bitstream_buffer) + return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4); init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); diff --git a/libavcodec/asv1.c b/libavcodec/asv1.c index c9a346add..0bbf3e63f 100644 --- a/libavcodec/asv1.c +++ b/libavcodec/asv1.c @@ -408,7 +408,9 @@ static int decode_frame(AVCodecContext *avctx, p->pict_type= FF_I_TYPE; p->key_frame= 1; - a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!a->bitstream_buffer) + return AVERROR(ENOMEM); if(avctx->codec_id == CODEC_ID_ASV1) a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 8edcc0134..50c70d6d1 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3540,6 +3540,20 @@ AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); */ void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); +/** + * Allocates a buffer, reusing the given one if large enough. + * + * Contrary to av_fast_realloc the current buffer contents might not be + * preserved and on error the old buffer is freed, thus no special + * handling to avoid memleaks is necessary. + * + * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer + * @param size size of the buffer *ptr points to + * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and + * *size 0 if an error occurred. + */ +void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size); + /** * Copy image 'src' to 'dst'. */ diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index 06dd7148c..2a6240234 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -126,7 +126,7 @@ static int tqi_decode_frame(AVCodecContext *avctx, return -1; } - t->bitstream_buf = av_fast_realloc(t->bitstream_buf, &t->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&t->bitstream_buf, &t->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE); if (!t->bitstream_buf) return AVERROR(ENOMEM); s->dsp.bswap_buf(t->bitstream_buf, (const uint32_t*)buf, (buf_end-buf)/4); diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 2f5757339..fa8fd1f9a 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -687,10 +687,12 @@ retry: } if(startcode_found){ - s->bitstream_buffer= av_fast_realloc( - s->bitstream_buffer, + av_fast_malloc( + &s->bitstream_buffer, &s->allocated_bitstream_buffer_size, buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->bitstream_buffer) + return AVERROR(ENOMEM); memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos); s->bitstream_buffer_size= buf_size - current_pos; } diff --git a/libavcodec/h264.c b/libavcodec/h264.c index b3c01a9ff..ff6ff567b 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -1411,7 +1411,7 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_l } bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data - h->rbsp_buffer[bufidx]= av_fast_realloc(h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE); dst= h->rbsp_buffer[bufidx]; if (dst == NULL){ diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index 59437b1a0..de1118dd1 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -956,7 +956,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac AVFrame *picture = data; - s->bitstream_buffer= av_fast_realloc(s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->bitstream_buffer) + return AVERROR(ENOMEM); s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size/4); diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index ad998649e..e0281ef16 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -174,7 +174,9 @@ static int decode_frame(AVCodecContext *avctx, p->pict_type= FF_I_TYPE; p->key_frame= 1; - a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!a->bitstream_buffer) + return AVERROR(ENOMEM); for(i=0; ibitstream_buffer[i] = buf[i+1]; a->bitstream_buffer[i+1]= buf[i ]; diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 471628457..42ae53e7e 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -334,7 +334,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index], (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]); - ctx->swap_buf = av_fast_realloc(ctx->swap_buf, &ctx->swap_buf_size, + av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!ctx->swap_buf) return AVERROR(ENOMEM); diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index 02ea04986..dcdd5d275 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -297,7 +297,9 @@ static int mp_decode_frame(AVCodecContext *avctx, } /* le32 bitstream msb first */ - mp->bswapbuf = av_fast_realloc(mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!mp->bswapbuf) + AVERROR(ENOMEM); mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4); if (buf_size & 3) memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 7a24a4d24..a37ace9cc 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -80,6 +80,17 @@ void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size) return ptr; } +void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size) +{ + void **p = ptr; + if (min_size < *size) + return; + *size= FFMAX(17*min_size/16 + 32, min_size); + av_free(*p); + *p = av_malloc(*size); + if (!*p) *size = 0; +} + /* encoder management */ static AVCodec *first_avcodec = NULL; -- 2.39.2