From: Michael Niedermayer <[email protected]>
Signed-off-by: Anton Khirnov <[email protected]>
---
libavfilter/avfilter.c | 35 ++++++++++++++++++++++++++++++++++-
libavfilter/avfilter.h | 2 ++
libavfilter/defaults.c | 28 +++++++++++++++++++++++++++-
libavfilter/internal.h | 6 ++++++
4 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 86d961b..f04ffce 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -25,6 +25,7 @@
#include "libavutil/rational.h"
#include "libavutil/audioconvert.h"
#include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
#include "avfilter.h"
#include "internal.h"
@@ -69,12 +70,44 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef
*ref, int pmask)
return ret;
}
+static void store_in_pool(AVFilterBufferRef *ref)
+{
+ int i;
+ AVFilterPool *pool = ref->buf->priv;
+
+ av_assert0(ref->buf->data[0]);
+
+ if (pool->count == POOL_SIZE) {
+ AVFilterBufferRef *ref1 = pool->pic[0];
+ av_freep(&ref1->video);
+ av_freep(&ref1->audio);
+ av_freep(&ref1->buf->data[0]);
+ av_freep(&ref1->buf);
+ av_freep(&pool->pic[0]);
+ memmove(&pool->pic[0], &pool->pic[1], sizeof(void*) * (POOL_SIZE - 1));
+ pool->count--;
+ pool->pic[POOL_SIZE-1] = NULL;
+ }
+
+ for (i = 0; i < POOL_SIZE; i++)
+ if (!pool->pic[i]) {
+ pool->pic[i] = ref;
+ pool->count++;
+ break;
+ }
+}
+
void avfilter_unref_buffer(AVFilterBufferRef *ref)
{
if (!ref)
return;
- if (!(--ref->buf->refcount))
+ if (!(--ref->buf->refcount)) {
+ if (!ref->buf->free) {
+ store_in_pool(ref);
+ return;
+ }
ref->buf->free(ref->buf);
+ }
av_freep(&ref->video);
av_freep(&ref->audio);
av_free(ref);
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index f8295e7..55746e6 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -622,6 +622,8 @@ struct AVFilterLink {
* input link is assumed to be an unchangeable property.
*/
AVRational time_base;
+
+ struct AVFilterPool *pool;
};
/**
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index 5532953..c44675f 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -25,7 +25,6 @@
#include "avfilter.h"
#include "internal.h"
-/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
{
av_free(ptr->data[0]);
@@ -39,7 +38,31 @@ AVFilterBufferRef
*avfilter_default_get_video_buffer(AVFilterLink *link, int per
{
int linesize[4], ret;
uint8_t *data[4];
+ int i;
AVFilterBufferRef *picref = NULL;
+ AVFilterPool *pool = link->pool;
+
+ if (pool)
+ for (i = 0; i < POOL_SIZE; i++) {
+ picref = pool->pic[i];
+ if (picref && picref->buf->format == link->format &&
+ picref->buf->w == w && picref->buf->h == h) {
+ AVFilterBuffer *pic = picref->buf;
+
+ pool->pic[i] = NULL;
+ pool->count--;
+ picref->video->w = w;
+ picref->video->h = h;
+ picref->perms = perms | AV_PERM_READ;
+ picref->format = link->format;
+ pic->refcount = 1;
+
+ memcpy(picref->data, pic->data, sizeof(picref->data));
+ memcpy(picref->linesize, pic->linesize,
sizeof(picref->linesize));
+ return picref;
+ }
+ } else
+ pool = link->pool = av_mallocz(sizeof(AVFilterPool));
// +2 is needed for swscaler, +16 to be SIMD-friendly
if ((ret = av_image_alloc(data, linesize, w, h, link->format, 16)) < 0)
@@ -53,6 +76,9 @@ AVFilterBufferRef
*avfilter_default_get_video_buffer(AVFilterLink *link, int per
}
memset(data[0], 128, ret);
+ picref->buf->priv = pool;
+ picref->buf->free = NULL;
+
return picref;
}
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 64b3f3b..4b8d1c4 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -27,6 +27,12 @@
#include "avfilter.h"
#include "avfiltergraph.h"
+#define POOL_SIZE 32
+typedef struct AVFilterPool {
+ AVFilterBufferRef *pic[POOL_SIZE];
+ int count;
+} AVFilterPool;
+
/**
* Check for the validity of graph.
*
--
1.7.5.4
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel