[FFmpeg-devel] [PATCH] add av_fast_malloc

Reimar Döffinger Reimar.Doeffinger
Sun Apr 12 11:39:13 CEST 2009


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...
-------------- 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 18467)
+++ 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((void **)&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 18467)
+++ 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((void **)&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((uint32_t*)t->bitstream_buf, (const uint32_t*)buf, (buf_end-buf)/4);
Index: libavcodec/4xm.c
===================================================================
--- libavcodec/4xm.c	(revision 18467)
+++ 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((void **)&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((uint32_t*)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((void **)&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((uint32_t*)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 +3541,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