[FFmpeg-devel] [PATCH] add av_fast_malloc
Reimar Döffinger
Reimar.Doeffinger
Sun Apr 12 14:38:48 CEST 2009
On Sun, Apr 12, 2009 at 02:01:03PM +0200, Michael Niedermayer wrote:
> On Sun, Apr 12, 2009 at 11:39:13AM +0200, Reimar D?ffinger wrote:
> > Hello,
> > this adds and uses where possible a function named av_fast_malloc.
> > It is very similar to av_fast_realloc and allows reusing an existing
> > buffer to reduce the number of actual, slow mallocs.
> > However it does not try to preserve the previous buffers contents
> > (particularly with large buffers this may be faster, if we need and come
> > up with a clever way to use realloc only where it is faster this can be
> > added later) and it also is easier to use since handling the error case
> > without creating a memleak is not as painful by far.
> > Simply replacing av_fast_realloc with av_fast_malloc fixes quite a few
> > memleaks...
>
> > Index: libavcodec/motionpixels.c
> > ===================================================================
> > --- libavcodec/motionpixels.c (revision 18467)
> > +++ libavcodec/motionpixels.c (working copy)
> > @@ -297,7 +297,9 @@
> > }
> >
> > /* le32 bitstream msb first */
> > - mp->bswapbuf = av_fast_realloc(mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
> > + av_fast_malloc((void **)&mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
> > + if (!mp->bswapbuf)
> > + AVERROR(ENOMEM);
>
> _Every_ single use of av_fast_malloc() uses a void** cast, av_fast_realloc()
> managed it without ...
There you are, a version with 4 cases where it isn't needed.
For quite a few other files it would be simple to change the type to
void *, saving casts both here and in other places with minor additional
changes (e.g. an additional temporary pointer variable) and the code
would probably be better overall.
Of course I could also use the same "hack" as av_freep, i.e. using void *
instead of void ** in the function declaration...
-------------- next part --------------
Index: libavcodec/motionpixels.c
===================================================================
--- libavcodec/motionpixels.c (revision 18467)
+++ libavcodec/motionpixels.c (working copy)
@@ -297,7 +297,9 @@
}
/* le32 bitstream msb first */
- mp->bswapbuf = av_fast_realloc(mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_malloc((void **)&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);
Index: libavcodec/mimic.c
===================================================================
--- libavcodec/mimic.c (revision 18469)
+++ libavcodec/mimic.c (working copy)
@@ -334,7 +334,7 @@
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);
Index: libavcodec/asv1.c
===================================================================
--- libavcodec/asv1.c (revision 18467)
+++ libavcodec/asv1.c (working copy)
@@ -408,7 +408,9 @@
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((void **)&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);
Index: libavcodec/utils.c
===================================================================
--- libavcodec/utils.c (revision 18467)
+++ libavcodec/utils.c (working copy)
@@ -80,6 +80,16 @@
return ptr;
}
+void av_fast_malloc(void **ptr, unsigned int *size, unsigned int min_size)
+{
+ if (min_size < *size)
+ return;
+ *size= FFMAX(17*min_size/16 + 32, min_size);
+ av_free(*ptr);
+ *ptr = av_malloc(*size);
+ if (!*ptr) *size = 0;
+}
+
/* encoder management */
static AVCodec *first_avcodec = NULL;
Index: libavcodec/h264.c
===================================================================
--- libavcodec/h264.c (revision 18467)
+++ libavcodec/h264.c (working copy)
@@ -1411,7 +1411,7 @@
}
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((void **)&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE);
dst= h->rbsp_buffer[bufidx];
if (dst == NULL){
Index: libavcodec/mdec.c
===================================================================
--- libavcodec/mdec.c (revision 18467)
+++ libavcodec/mdec.c (working copy)
@@ -174,7 +174,9 @@
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((void **)&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!a->bitstream_buffer)
+ return AVERROR(ENOMEM);
for(i=0; i<buf_size; i+=2){
a->bitstream_buffer[i] = buf[i+1];
a->bitstream_buffer[i+1]= buf[i ];
Index: libavcodec/h263dec.c
===================================================================
--- libavcodec/h263dec.c (revision 18467)
+++ libavcodec/h263dec.c (working copy)
@@ -687,10 +687,12 @@
}
if(startcode_found){
- s->bitstream_buffer= av_fast_realloc(
- s->bitstream_buffer,
+ av_fast_malloc(
+ (void **)&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;
}
Index: libavcodec/eatqi.c
===================================================================
--- libavcodec/eatqi.c (revision 18469)
+++ libavcodec/eatqi.c (working copy)
@@ -126,7 +126,7 @@
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);
Index: libavcodec/4xm.c
===================================================================
--- libavcodec/4xm.c (revision 18469)
+++ libavcodec/4xm.c (working copy)
@@ -378,7 +378,9 @@
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 @@
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);
Index: libavcodec/avcodec.h
===================================================================
--- libavcodec/avcodec.h (revision 18467)
+++ libavcodec/avcodec.h (working copy)
@@ -3541,6 +3549,20 @@
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'.
*/
void av_picture_copy(AVPicture *dst, const AVPicture *src,
Index: libavcodec/huffyuv.c
===================================================================
--- libavcodec/huffyuv.c (revision 18467)
+++ libavcodec/huffyuv.c (working copy)
@@ -956,7 +956,9 @@
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((void **)&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);
More information about the ffmpeg-devel
mailing list