Mercurial > mplayer.hg
changeset 32795:801dc49c6f33
Fix muxer memory leak.
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@google.com>
author | ranma |
---|---|
date | Thu, 10 Feb 2011 21:31:24 +0000 |
parents | 77d81e27a176 |
children | 48ffe13dd1ee |
files | libmpdemux/muxer.c libmpdemux/muxer.h mencoder.c |
diffstat | 3 files changed, 57 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpdemux/muxer.c Thu Feb 10 21:25:38 2011 +0000 +++ b/libmpdemux/muxer.c Thu Feb 10 21:31:24 2011 +0000 @@ -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 */
--- a/libmpdemux/muxer.h Thu Feb 10 21:25:38 2011 +0000 +++ b/libmpdemux/muxer.h Thu Feb 10 21:31:24 2011 +0000 @@ -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);
--- a/mencoder.c Thu Feb 10 21:25:38 2011 +0000 +++ b/mencoder.c Thu Feb 10 21:31:24 2011 +0000 @@ -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);