Browse code

AVFilter: use picture pool to avoid malloc(). Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2011/05/07 06:53:06
Showing 4 changed files
... ...
@@ -25,6 +25,7 @@
25 25
 #include "libavutil/rational.h"
26 26
 #include "libavutil/audioconvert.h"
27 27
 #include "libavutil/imgutils.h"
28
+#include "libavutil/avassert.h"
28 29
 #include "avfilter.h"
29 30
 #include "internal.h"
30 31
 
... ...
@@ -69,12 +70,50 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
69 69
     return ret;
70 70
 }
71 71
 
72
+static void store_in_pool(AVFilterBufferRef *ref)
73
+{
74
+    int i;
75
+    AVFilterLink *link= ref->buf->priv;
76
+    AVFilterPool *pool;
77
+
78
+    av_assert0(ref->buf->data[0]);
79
+
80
+    if(!link->pool)
81
+        link->pool = av_mallocz(sizeof(AVFilterPool));
82
+    pool= link->pool;
83
+
84
+    if(pool->count == POOL_SIZE){
85
+        AVFilterBufferRef *ref1= pool->pic[0];
86
+        av_freep(&ref1->video);
87
+        av_freep(&ref1->audio);
88
+        av_freep(&ref1->buf->data[0]);
89
+        av_freep(&ref1->buf);
90
+        av_free(ref1);
91
+        memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1));
92
+        pool->count--;
93
+        pool->pic[POOL_SIZE-1] = NULL;
94
+    }
95
+
96
+    for(i=0; i<POOL_SIZE; i++){
97
+        if(!pool->pic[i]){
98
+            pool->pic[i]= ref;
99
+            pool->count++;
100
+            break;
101
+        }
102
+    }
103
+}
104
+
72 105
 void avfilter_unref_buffer(AVFilterBufferRef *ref)
73 106
 {
74 107
     if (!ref)
75 108
         return;
76
-    if (!(--ref->buf->refcount))
109
+    if (!(--ref->buf->refcount)){
110
+        if(!ref->buf->free){
111
+            store_in_pool(ref);
112
+            return;
113
+        }
77 114
         ref->buf->free(ref->buf);
115
+    }
78 116
     av_freep(&ref->video);
79 117
     av_freep(&ref->audio);
80 118
     av_free(ref);
... ...
@@ -646,6 +685,7 @@ void avfilter_free(AVFilterContext *filter)
646 646
         if ((link = filter->inputs[i])) {
647 647
             if (link->src)
648 648
                 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
649
+            av_freep(&link->pool);
649 650
             avfilter_formats_unref(&link->in_formats);
650 651
             avfilter_formats_unref(&link->out_formats);
651 652
         }
... ...
@@ -655,6 +695,7 @@ void avfilter_free(AVFilterContext *filter)
655 655
         if ((link = filter->outputs[i])) {
656 656
             if (link->dst)
657 657
                 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
658
+            av_freep(&link->pool);
658 659
             avfilter_formats_unref(&link->in_formats);
659 660
             avfilter_formats_unref(&link->out_formats);
660 661
         }
... ...
@@ -619,6 +619,8 @@ struct AVFilterLink {
619 619
      * input link is assumed to be an unchangeable property.
620 620
      */
621 621
     AVRational time_base;
622
+
623
+    struct AVFilterPool *pool;
622 624
 };
623 625
 
624 626
 /**
... ...
@@ -25,7 +25,6 @@
25 25
 #include "avfilter.h"
26 26
 #include "internal.h"
27 27
 
28
-/* TODO: buffer pool.  see comment for avfilter_default_get_video_buffer() */
29 28
 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
30 29
 {
31 30
     av_free(ptr->data[0]);
... ...
@@ -39,7 +38,26 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
39 39
 {
40 40
     int linesize[4];
41 41
     uint8_t *data[4];
42
+    int i;
42 43
     AVFilterBufferRef *picref = NULL;
44
+    AVFilterPool *pool= link->pool;
45
+
46
+    if(pool) for(i=0; i<POOL_SIZE; i++){
47
+        picref= pool->pic[i];
48
+        if(picref && picref->buf->format == link->format && picref->buf->w == w && picref->buf->h == h){
49
+            AVFilterBuffer *pic= picref->buf;
50
+            pool->pic[i]= NULL;
51
+            pool->count--;
52
+            picref->video->w = w;
53
+            picref->video->h = h;
54
+            picref->perms = perms | AV_PERM_READ;
55
+            picref->format= link->format;
56
+            pic->refcount = 1;
57
+            memcpy(picref->data,     pic->data,     sizeof(picref->data));
58
+            memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
59
+            return picref;
60
+        }
61
+    }
43 62
 
44 63
     // +2 is needed for swscaler, +16 to be SIMD-friendly
45 64
     if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
... ...
@@ -51,6 +69,8 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
51 51
         av_free(data[0]);
52 52
         return NULL;
53 53
     }
54
+    picref->buf->priv= link;
55
+    picref->buf->free= NULL;
54 56
 
55 57
     return picref;
56 58
 }
... ...
@@ -27,6 +27,12 @@
27 27
 #include "avfilter.h"
28 28
 #include "avfiltergraph.h"
29 29
 
30
+#define POOL_SIZE 32
31
+typedef struct AVFilterPool {
32
+    AVFilterBufferRef *pic[POOL_SIZE];
33
+    int count;
34
+}AVFilterPool;
35
+
30 36
 /**
31 37
  * Check for the validity of graph.
32 38
  *