[MPlayer-dev-eng] [PATCH] Fix muxer memory leak

Tobias Diedrich ranma at tdiedrich.de
Tue Feb 8 15:33:34 CET 2011


This adds the missing free() and moves the flushing logic into a
seperate function, which we then also call from mencoder to make
really sure everything has been flushed.

Original patch by Sang-Uok Kum.

Signed-off-by: Tobias Diedrich <ranma at google.com>

Index: mplayer-patchset1/libmpdemux/muxer.c
===================================================================
--- mplayer-patchset1.orig/libmpdemux/muxer.c	2011-02-08 14:46:11.549276000 +0100
+++ mplayer-patchset1/libmpdemux/muxer.c	2011-02-08 15:31:18.076970000 +0100
@@ -69,6 +69,57 @@
     return NULL;
 }
 
+/* Flush the internal muxer buffer.
+ * This is normally called from muxer_write_chunk() once all streams
+ * have seen frames. */
+void muxer_flush(muxer_t *m) {
+    int num;
+
+    if (!m->muxbuf)
+        return;
+
+    mp_msg(MSGT_MUXER, MSGL_V, MSGTR_MuxbufSending, m->muxbuf_num);
+
+    /* fix parameters for all streams */
+    for (num = 0; m->streams[num]; ++num) {
+      muxer_stream_t *str = m->streams[num];
+      if(str->muxer->fix_stream_parameters)
+        muxer_stream_fix_parameters(str->muxer, str);
+    }
+
+    /* write header */
+    if (m->cont_write_header)
+      muxer_write_header(m);
+
+    /* send all buffered frames to muxer */
+    for (num = 0; num < m->muxbuf_num; ++num) {
+      muxbuf_t tmp_buf;
+      muxbuf_t *buf;
+      muxer_stream_t *s;
+      buf = m->muxbuf + num;
+      s = buf->stream;
+
+      /* 1. save timer and buffer (might have changed by now) */
+      tmp_buf.dts = s->timer;
+      tmp_buf.buffer = s->buffer;
+
+      /* 2. move stored timer and buffer into stream and mux it */
+      s->timer = buf->dts;
+      s->buffer = buf->buffer;
+      m->cont_write_chunk(s, buf->len, buf->flags, buf->dts, buf->pts);
+      free(buf->buffer);
+      buf->buffer = NULL;
+
+      /* 3. restore saved timer and buffer */
+      s->timer = tmp_buf.dts;
+      s->buffer = tmp_buf.buffer;
+    }
+
+    free(m->muxbuf);
+    m->muxbuf = NULL;
+    m->muxbuf_num = 0;
+}
+
 /* buffer frames until we either:
  * (a) have at least one frame from each stream
  * (b) run out of memory */
@@ -112,44 +163,8 @@
           s->muxer->muxbuf_skip_buffer = 0;
 
       /* see if we can flush buffer now */
-      if (s->muxer->muxbuf_skip_buffer) {
-        mp_msg(MSGT_MUXER, MSGL_V, MSGTR_MuxbufSending, s->muxer->muxbuf_num);
-
-        /* fix parameters for all streams */
-        for (num = 0; s->muxer->streams[num]; ++num) {
-          muxer_stream_t *str = s->muxer->streams[num];
-          if(str->muxer->fix_stream_parameters)
-            muxer_stream_fix_parameters(str->muxer, str);
-        }
-
-        /* write header */
-        if (s->muxer->cont_write_header)
-          muxer_write_header(s->muxer);
-
-        /* send all buffered frames to muxer */
-        for (num = 0; num < s->muxer->muxbuf_num; ++num) {
-          muxbuf_t tmp_buf;
-          buf = s->muxer->muxbuf + num;
-          s = buf->stream;
-
-          /* 1. save timer and buffer (might have changed by now) */
-          tmp_buf.dts = s->timer;
-          tmp_buf.buffer = s->buffer;
-
-          /* 2. move stored timer and buffer into stream and mux it */
-          s->timer = buf->dts;
-          s->buffer = buf->buffer;
-          s->muxer->cont_write_chunk(s, buf->len, buf->flags, buf->dts, buf->pts);
-
-          /* 3. restore saved timer and buffer */
-          s->timer = tmp_buf.dts;
-          s->buffer = tmp_buf.buffer;
-        }
-
-        free(s->muxer->muxbuf);
-        s->muxer->muxbuf = NULL;
-        s->muxer->muxbuf_num = 0;
-      }
+      if (s->muxer->muxbuf_skip_buffer)
+          muxer_flush(s->muxer);
     }
 
     /* this code moved directly from muxer_avi.c */
Index: mplayer-patchset1/libmpdemux/muxer.h
===================================================================
--- mplayer-patchset1.orig/libmpdemux/muxer.h	2011-02-08 15:14:47.394204000 +0100
+++ mplayer-patchset1/libmpdemux/muxer.h	2011-02-08 15:15:11.765203000 +0100
@@ -133,6 +133,7 @@
 extern const m_option_t nuvopts_conf[];
 
 muxer_t *muxer_new_muxer(int type,stream_t *stream);
+void muxer_flush(muxer_t *m);
 #define muxer_new_stream(muxer,a) muxer->cont_new_stream(muxer,a)
 #define muxer_stream_fix_parameters(muxer, a) muxer->fix_stream_parameters(a)
 void muxer_write_chunk(muxer_stream_t *s, size_t len, unsigned int flags, double dts, double pts);
Index: mplayer-patchset1/mencoder.c
===================================================================
--- mplayer-patchset1.orig/mencoder.c	2011-02-08 15:19:15.113011000 +0100
+++ mplayer-patchset1/mencoder.c	2011-02-08 15:21:58.396138000 +0100
@@ -1670,6 +1670,9 @@
     if(aencoder->fixup)
         aencoder->fixup(aencoder);
 
+/* flush muxer just in case, this is a no-op unless
+ * we created a stream but never wrote frames to it... */
+muxer_flush(muxer);
 if (muxer->cont_write_index) muxer_write_index(muxer);
 muxer_f_size=stream_tell(muxer->stream);
 stream_seek(muxer->stream,0);


More information about the MPlayer-dev-eng mailing list