[FFmpeg-devel] Memory leak in h264

Jeff Downs heydowns
Tue Jan 22 20:46:46 CET 2008


On Tue, 22 Jan 2008, Michael Niedermayer wrote:

> i suspect that will break multithreaded decoding by using the same buffer
> for all threads
> 
> the fix might be to always let init_duplicate_context allocate all
> the *edge_emu_buffer, instead of just for the first context and then
> allocate the H264Contexts and copy the MpegEncContexts into them

I'd already started on fixing it differently when I saw this, so here's 
what I came up with. 

	-Jeff

-------------- next part --------------
Index: libavcodec/h264.c
===================================================================
--- libavcodec/h264.c	(revision 11597)
+++ libavcodec/h264.c	(working copy)
@@ -2091,17 +2106,21 @@
 /**
  * Init context
  * Allocate buffers which are not shared amongst multiple threads.
+ * @param is_duplicate zero for master context, non-zero for duplicated
+ *                     (thread) contexts
  */
-static int context_init(H264Context *h){
+static int context_init(H264Context *h, int is_duplicate){
     MpegEncContext * const s = &h->s;
 
     CHECKED_ALLOCZ(h->top_borders[0], h->s.mb_width * (16+8+8) * sizeof(uint8_t))
     CHECKED_ALLOCZ(h->top_borders[1], h->s.mb_width * (16+8+8) * sizeof(uint8_t))
 
     // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)
-    CHECKED_ALLOCZ(s->allocated_edge_emu_buffer,
-                   (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance
-    s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;
+    if (is_duplicate) {
+        CHECKED_ALLOCZ(s->allocated_edge_emu_buffer,
+                       (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance
+        s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;
+    }
     return 0;
 fail:
     return -1; // free_tables will clean up for us
@@ -3913,12 +3935,13 @@
             memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
             c->sps = h->sps;
             c->pps = h->pps;
+            c->s.allocated_edge_emu_buffer = NULL;
             init_scan_tables(c);
             clone_tables(c, h);
         }
 
         for(i = 0; i < s->avctx->thread_count; i++)
-            if(context_init(h->thread_context[i]) < 0)
+            if(context_init(h->thread_context[i], i) < 0)
                 return -1;
 
         s->avctx->width = s->width;



More information about the ffmpeg-devel mailing list