Unified · Split
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 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) · 38 unmodified lines | ||
| 69 | 70 | return ret; |
| 70 | 71 | } |
| 71 | 72 | |
| 73 | +static void store_in_pool(AVFilterBufferRef *ref) | |
| 74 | +{ | |
| 75 | + int i; | |
| 76 | + AVFilterLink *link= ref->buf->priv; | |
| 77 | + AVFilterPool *pool; | |
| 78 | + | |
| 79 | + av_assert0(ref->buf->data[0]); | |
| 80 | + | |
| 81 | + if(!link->pool) | |
| 82 | + link->pool = av_mallocz(sizeof(AVFilterPool)); | |
| 83 | + pool= link->pool; | |
| 84 | + | |
| 85 | + if(pool->count == POOL_SIZE){ | |
| 86 | + AVFilterBufferRef *ref1= pool->pic[0]; | |
| 87 | + av_freep(&ref1->video); | |
| 88 | + av_freep(&ref1->audio); | |
| 89 | + av_freep(&ref1->buf->data[0]); | |
| 90 | + av_freep(&ref1->buf); | |
| 91 | + av_free(ref1); | |
| 92 | + memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1)); | |
| 93 | + pool->count--; | |
| 94 | + pool->pic[POOL_SIZE-1] = NULL; | |
| 95 | + } | |
| 96 | + | |
| 97 | + for(i=0; i<POOL_SIZE; i++){ | |
| 98 | + if(!pool->pic[i]){ | |
| 99 | + pool->pic[i]= ref; | |
| 100 | + pool->count++; | |
| 101 | + break; | |
| 102 | + } | |
| 103 | + } | |
| 104 | +} | |
| 105 | + | |
| 72 | 106 | void avfilter_unref_buffer(AVFilterBufferRef *ref) |
| 73 | 107 | { |
| 74 | 108 | if (!ref) |
| 75 | 109 | return; |
| 76 | − if (!(--ref->buf->refcount)) | |
| 110 | + if (!(--ref->buf->refcount)){ | |
| 111 | + if(!ref->buf->free){ | |
| 112 | + store_in_pool(ref); | |
| 113 | + return; | |
| 114 | + } | |
| 77 | 115 | ref->buf->free(ref->buf); |
| 116 | + } | |
| 78 | 117 | av_freep(&ref->video); |
| 79 | 118 | av_freep(&ref->audio); |
| 80 | 119 | av_free(ref); |
| @@ -646,6 +685,7 @@ void avfilter_free(AVFilterContext *filter) · 565 unmodified lines | ||
| 646 | 685 | if ((link = filter->inputs[i])) { |
| 647 | 686 | if (link->src) |
| 648 | 687 | link->src->outputs[link->srcpad - link->src->output_pads] = NULL; |
| 688 | + av_freep(&link->pool); | |
| 649 | 689 | avfilter_formats_unref(&link->in_formats); |
| 650 | 690 | avfilter_formats_unref(&link->out_formats); |
| 651 | 691 | } |
| @@ -655,6 +695,7 @@ void avfilter_free(AVFilterContext *filter) · 3 unmodified lines | ||
| 655 | 695 | if ((link = filter->outputs[i])) { |
| 656 | 696 | if (link->dst) |
| 657 | 697 | link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL; |
| 698 | + av_freep(&link->pool); | |
| 658 | 699 | avfilter_formats_unref(&link->in_formats); |
| 659 | 700 | avfilter_formats_unref(&link->out_formats); |
| 660 | 701 | } |
| @@ -619,6 +619,8 @@ struct AVFilterLink { · 618 unmodified lines | ||
| 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 @@ · 24 unmodified lines | ||
| 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 · 7 unmodified lines | ||
| 39 | 38 | { |
| 40 | 39 | int linesize[4]; |
| 41 | 40 | uint8_t *data[4]; |
| 41 | + int i; | |
| 42 | 42 | AVFilterBufferRef *picref = NULL; |
| 43 | + AVFilterPool *pool= link->pool; | |
| 44 | + | |
| 45 | + if(pool) for(i=0; i<POOL_SIZE; i++){ | |
| 46 | + picref= pool->pic[i]; | |
| 47 | + if(picref && picref->buf->format == link->format && picref->buf->w == w && picref->buf->h == h){ | |
| 48 | + AVFilterBuffer *pic= picref->buf; | |
| 49 | + pool->pic[i]= NULL; | |
| 50 | + pool->count--; | |
| 51 | + picref->video->w = w; | |
| 52 | + picref->video->h = h; | |
| 53 | + picref->perms = perms | AV_PERM_READ; | |
| 54 | + picref->format= link->format; | |
| 55 | + pic->refcount = 1; | |
| 56 | + memcpy(picref->data, pic->data, sizeof(picref->data)); | |
| 57 | + memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize)); | |
| 58 | + return picref; | |
| 59 | + } | |
| 60 | + } | |
| 43 | 61 | |
| 44 | 62 | // +2 is needed for swscaler, +16 to be SIMD-friendly |
| 45 | 63 | 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 · 5 unmodified lines | ||
| 51 | 69 | av_free(data[0]); |
| 52 | 70 | return NULL; |
| 53 | 71 | } |
| 72 | + picref->buf->priv= link; | |
| 73 | + picref->buf->free= NULL; | |
| 54 | 74 | |
| 55 | 75 | return picref; |
| 56 | 76 | } |
| @@ -27,6 +27,12 @@ · 26 unmodified lines | ||
| 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 | * |