| ... | ... |
@@ -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 |
} |
| ... | ... |
@@ -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 |
} |