AVFilter: use picture pool to avoid malloc().
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
fa3eddc011
commit
39f66edbea
@ -25,6 +25,7 @@
|
|||||||
#include "libavutil/rational.h"
|
#include "libavutil/rational.h"
|
||||||
#include "libavutil/audioconvert.h"
|
#include "libavutil/audioconvert.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
|
#include "libavutil/avassert.h"
|
||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -69,12 +70,50 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void store_in_pool(AVFilterBufferRef *ref)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
AVFilterLink *link= ref->buf->priv;
|
||||||
|
AVFilterPool *pool;
|
||||||
|
|
||||||
|
av_assert0(ref->buf->data[0]);
|
||||||
|
|
||||||
|
if(!link->pool)
|
||||||
|
link->pool = av_mallocz(sizeof(AVFilterPool));
|
||||||
|
pool= link->pool;
|
||||||
|
|
||||||
|
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_free(ref1);
|
||||||
|
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)
|
void avfilter_unref_buffer(AVFilterBufferRef *ref)
|
||||||
{
|
{
|
||||||
if (!ref)
|
if (!ref)
|
||||||
return;
|
return;
|
||||||
if (!(--ref->buf->refcount))
|
if (!(--ref->buf->refcount)){
|
||||||
|
if(!ref->buf->free){
|
||||||
|
store_in_pool(ref);
|
||||||
|
return;
|
||||||
|
}
|
||||||
ref->buf->free(ref->buf);
|
ref->buf->free(ref->buf);
|
||||||
|
}
|
||||||
av_freep(&ref->video);
|
av_freep(&ref->video);
|
||||||
av_freep(&ref->audio);
|
av_freep(&ref->audio);
|
||||||
av_free(ref);
|
av_free(ref);
|
||||||
@ -646,6 +685,7 @@ void avfilter_free(AVFilterContext *filter)
|
|||||||
if ((link = filter->inputs[i])) {
|
if ((link = filter->inputs[i])) {
|
||||||
if (link->src)
|
if (link->src)
|
||||||
link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
|
link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
|
||||||
|
av_freep(&link->pool);
|
||||||
avfilter_formats_unref(&link->in_formats);
|
avfilter_formats_unref(&link->in_formats);
|
||||||
avfilter_formats_unref(&link->out_formats);
|
avfilter_formats_unref(&link->out_formats);
|
||||||
}
|
}
|
||||||
@ -655,6 +695,7 @@ void avfilter_free(AVFilterContext *filter)
|
|||||||
if ((link = filter->outputs[i])) {
|
if ((link = filter->outputs[i])) {
|
||||||
if (link->dst)
|
if (link->dst)
|
||||||
link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
|
link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
|
||||||
|
av_freep(&link->pool);
|
||||||
avfilter_formats_unref(&link->in_formats);
|
avfilter_formats_unref(&link->in_formats);
|
||||||
avfilter_formats_unref(&link->out_formats);
|
avfilter_formats_unref(&link->out_formats);
|
||||||
}
|
}
|
||||||
|
@ -619,6 +619,8 @@ struct AVFilterLink {
|
|||||||
* input link is assumed to be an unchangeable property.
|
* input link is assumed to be an unchangeable property.
|
||||||
*/
|
*/
|
||||||
AVRational time_base;
|
AVRational time_base;
|
||||||
|
|
||||||
|
struct AVFilterPool *pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
|
|
||||||
void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
|
void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
|
||||||
{
|
{
|
||||||
av_free(ptr->data[0]);
|
av_free(ptr->data[0]);
|
||||||
@ -39,7 +38,26 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per
|
|||||||
{
|
{
|
||||||
int linesize[4];
|
int linesize[4];
|
||||||
uint8_t *data[4];
|
uint8_t *data[4];
|
||||||
|
int i;
|
||||||
AVFilterBufferRef *picref = NULL;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// +2 is needed for swscaler, +16 to be SIMD-friendly
|
// +2 is needed for swscaler, +16 to be SIMD-friendly
|
||||||
if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
|
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
|
|||||||
av_free(data[0]);
|
av_free(data[0]);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
picref->buf->priv= link;
|
||||||
|
picref->buf->free= NULL;
|
||||||
|
|
||||||
return picref;
|
return picref;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,12 @@
|
|||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
#include "avfiltergraph.h"
|
#include "avfiltergraph.h"
|
||||||
|
|
||||||
|
#define POOL_SIZE 32
|
||||||
|
typedef struct AVFilterPool {
|
||||||
|
AVFilterBufferRef *pic[POOL_SIZE];
|
||||||
|
int count;
|
||||||
|
}AVFilterPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for the validity of graph.
|
* Check for the validity of graph.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user