[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