mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avfilter: pool draining and self destruction support.
This should fix a memleak. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
4fd1e2e432
commit
f068ce570f
@ -81,12 +81,41 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
|
|||||||
return ret;
|
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)
|
static void store_in_pool(AVFilterBufferRef *ref)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
AVFilterPool *pool= ref->buf->priv;
|
AVFilterPool *pool= ref->buf->priv;
|
||||||
|
|
||||||
av_assert0(ref->buf->data[0]);
|
av_assert0(ref->buf->data[0]);
|
||||||
|
av_assert0(pool->refcount>0);
|
||||||
|
|
||||||
if (pool->count == POOL_SIZE) {
|
if (pool->count == POOL_SIZE) {
|
||||||
AVFilterBufferRef *ref1 = pool->pic[0];
|
AVFilterBufferRef *ref1 = pool->pic[0];
|
||||||
@ -107,6 +136,10 @@ static void store_in_pool(AVFilterBufferRef *ref)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pool->draining) {
|
||||||
|
free_pool(pool);
|
||||||
|
} else
|
||||||
|
--pool->refcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void avfilter_unref_buffer(AVFilterBufferRef *ref)
|
void avfilter_unref_buffer(AVFilterBufferRef *ref)
|
||||||
@ -181,24 +214,9 @@ void avfilter_link_free(AVFilterLink **link)
|
|||||||
if (!*link)
|
if (!*link)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((*link)->pool) {
|
if ((*link)->pool)
|
||||||
int i;
|
free_pool((*link)->pool);
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
av_freep(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +57,14 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
|
|||||||
pic->refcount = 1;
|
pic->refcount = 1;
|
||||||
memcpy(picref->data, pic->data, sizeof(picref->data));
|
memcpy(picref->data, pic->data, sizeof(picref->data));
|
||||||
memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
|
memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
|
||||||
|
pool->refcount++;
|
||||||
return picref;
|
return picref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
pool = link->pool = av_mallocz(sizeof(AVFilterPool));
|
pool = link->pool = av_mallocz(sizeof(AVFilterPool));
|
||||||
|
pool->refcount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// align: +2 is needed for swscaler, +16 to be SIMD-friendly
|
// align: +2 is needed for swscaler, +16 to be SIMD-friendly
|
||||||
if ((i = av_image_alloc(data, linesize, w, h, link->format, 32)) < 0)
|
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->priv = pool;
|
||||||
picref->buf->free = NULL;
|
picref->buf->free = NULL;
|
||||||
|
pool->refcount++;
|
||||||
|
|
||||||
return picref;
|
return picref;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
typedef struct AVFilterPool {
|
typedef struct AVFilterPool {
|
||||||
AVFilterBufferRef *pic[POOL_SIZE];
|
AVFilterBufferRef *pic[POOL_SIZE];
|
||||||
int count;
|
int count;
|
||||||
|
int refcount;
|
||||||
|
int draining;
|
||||||
} AVFilterPool;
|
} AVFilterPool;
|
||||||
|
|
||||||
typedef struct AVFilterCommand {
|
typedef struct AVFilterCommand {
|
||||||
|
Loading…
Reference in New Issue
Block a user