avfilter: pool draining and self destruction support.

This should fix a memleak.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
pull/3/head
Michael Niedermayer 13 years ago
parent 4fd1e2e432
commit f068ce570f
  1. 52
      libavfilter/avfilter.c
  2. 6
      libavfilter/defaults.c
  3. 2
      libavfilter/internal.h

@ -81,12 +81,41 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
return ret;
}
static void free_pool(AVFilterPool *pool)
{
int i;
av_assert0(pool->refcount > 0);
for (i = 0; i < POOL_SIZE; i++) {
if (pool->pic[i]) {
AVFilterBufferRef *picref = pool->pic[i];
/* free buffer: picrefs stored in the pool are not
* supposed to contain a free callback */
av_freep(&picref->buf->data[0]);
av_freep(&picref->buf);
av_freep(&picref->audio);
av_freep(&picref->video);
av_freep(&pool->pic[i]);
pool->count--;
}
}
pool->draining = 1;
if (!--pool->refcount) {
av_assert0(!pool->count);
av_free(pool);
}
}
static void store_in_pool(AVFilterBufferRef *ref)
{
int i;
AVFilterPool *pool= ref->buf->priv;
av_assert0(ref->buf->data[0]);
av_assert0(pool->refcount>0);
if (pool->count == POOL_SIZE) {
AVFilterBufferRef *ref1 = pool->pic[0];
@ -107,6 +136,10 @@ static void store_in_pool(AVFilterBufferRef *ref)
break;
}
}
if (pool->draining) {
free_pool(pool);
} else
--pool->refcount;
}
void avfilter_unref_buffer(AVFilterBufferRef *ref)
@ -181,24 +214,9 @@ void avfilter_link_free(AVFilterLink **link)
if (!*link)
return;
if ((*link)->pool) {
int i;
for (i = 0; i < POOL_SIZE; i++) {
if ((*link)->pool->pic[i]) {
AVFilterBufferRef *picref = (*link)->pool->pic[i];
/* free buffer: picrefs stored in the pool are not
* supposed to contain a free callback */
av_freep(&picref->buf->data[0]);
av_freep(&picref->buf);
if ((*link)->pool)
free_pool((*link)->pool);
av_freep(&picref->audio);
av_freep(&picref->video);
av_freep(&(*link)->pool->pic[i]);
}
}
(*link)->pool->count = 0;
// av_freep(&(*link)->pool);
}
av_freep(link);
}

@ -57,11 +57,14 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
pic->refcount = 1;
memcpy(picref->data, pic->data, sizeof(picref->data));
memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
pool->refcount++;
return picref;
}
}
} else
} else {
pool = link->pool = av_mallocz(sizeof(AVFilterPool));
pool->refcount = 1;
}
// align: +2 is needed for swscaler, +16 to be SIMD-friendly
if ((i = av_image_alloc(data, linesize, w, h, link->format, 32)) < 0)
@ -77,6 +80,7 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
picref->buf->priv = pool;
picref->buf->free = NULL;
pool->refcount++;
return picref;
}

@ -31,6 +31,8 @@
typedef struct AVFilterPool {
AVFilterBufferRef *pic[POOL_SIZE];
int count;
int refcount;
int draining;
} AVFilterPool;
typedef struct AVFilterCommand {

Loading…
Cancel
Save