[FFmpeg-devel] [PATCH] add av_fast_malloc

Reimar Döffinger Reimar.Doeffinger
Sun Apr 12 14:57:17 CEST 2009


On Sun, Apr 12, 2009 at 02:42:01PM +0200, Michael Niedermayer wrote:
> On Sun, Apr 12, 2009 at 02:10:58PM +0200, Reimar D?ffinger wrote:
> > Or you could give av_fast_malloc a return value, but IMO that would be
> > a more confusing API.
> 
> i always liked to make it explicit what is changed by using return ...

Well, since there are two things changed that does not really work that
well. Also since the old pointer is invalid you'll basically always want
to assign to the same variable you passed in, this results in what I
consider "boilerplate" code, and I just hate, hate, hate that.

> > In several cases the buffer could be made void *, sometimes avoiding a
> > few more casts in the process.
> > There are many solutions, I just considered this the best...
> 
> make the arg void * and cast inside the function if you dislie the return

Sure, here's a variant with that done.
-------------- 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(&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(&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,17 @@
     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;
 
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(&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(&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(
+                &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(&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