Commit a74dcb7d authored by Stefano Sabatini's avatar Stefano Sabatini

lavfi/color: cache and reuse colored picture in context

Avoid to fill the same picture again and again with the same content.

Optimize computation, and provides an example for the use of the
AV_PERM_REUSE permission flag.
parent 47b6b7a2
...@@ -45,6 +45,7 @@ typedef struct { ...@@ -45,6 +45,7 @@ typedef struct {
uint64_t pts; uint64_t pts;
FFDrawContext draw; FFDrawContext draw;
FFDrawColor color; FFDrawColor color;
AVFilterBufferRef *picref; ///< cached reference containing the painted picture
} ColorContext; } ColorContext;
#define OFFSET(x) offsetof(ColorContext, x) #define OFFSET(x) offsetof(ColorContext, x)
...@@ -92,6 +93,12 @@ end: ...@@ -92,6 +93,12 @@ end:
return ret; return ret;
} }
static av_cold void color_uninit(AVFilterContext *ctx)
{
ColorContext *color = ctx->priv;
avfilter_unref_bufferp(&color->picref);
}
static int query_formats(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx)
{ {
ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
...@@ -124,18 +131,24 @@ static int color_config_props(AVFilterLink *inlink) ...@@ -124,18 +131,24 @@ static int color_config_props(AVFilterLink *inlink)
static int color_request_frame(AVFilterLink *link) static int color_request_frame(AVFilterLink *link)
{ {
ColorContext *color = link->src->priv; ColorContext *color = link->src->priv;
AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h);
AVFilterBufferRef *buf_out; AVFilterBufferRef *buf_out;
int ret; int ret;
if (!picref) if (!color->picref) {
return AVERROR(ENOMEM); color->picref =
ff_get_video_buffer(link, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE,
picref->video->sample_aspect_ratio = (AVRational) {1, 1}; color->w, color->h);
picref->pts = color->pts++; if (!color->picref)
picref->pos = -1; return AVERROR(ENOMEM);
ff_fill_rectangle(&color->draw, &color->color,
color->picref->data, color->picref->linesize,
0, 0, color->w, color->h);
color->picref->video->sample_aspect_ratio = (AVRational) {1, 1};
color->picref->pos = -1;
}
buf_out = avfilter_ref_buffer(picref, ~0); color->picref->pts = color->pts++;
buf_out = avfilter_ref_buffer(color->picref, ~AV_PERM_WRITE);
if (!buf_out) { if (!buf_out) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
...@@ -145,8 +158,6 @@ static int color_request_frame(AVFilterLink *link) ...@@ -145,8 +158,6 @@ static int color_request_frame(AVFilterLink *link)
if (ret < 0) if (ret < 0)
goto fail; goto fail;
ff_fill_rectangle(&color->draw, &color->color, picref->data, picref->linesize,
0, 0, color->w, color->h);
ret = ff_draw_slice(link, 0, color->h, 1); ret = ff_draw_slice(link, 0, color->h, 1);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
...@@ -154,8 +165,6 @@ static int color_request_frame(AVFilterLink *link) ...@@ -154,8 +165,6 @@ static int color_request_frame(AVFilterLink *link)
ret = ff_end_frame(link); ret = ff_end_frame(link);
fail: fail:
avfilter_unref_buffer(picref);
return ret; return ret;
} }
...@@ -165,6 +174,7 @@ AVFilter avfilter_vsrc_color = { ...@@ -165,6 +174,7 @@ AVFilter avfilter_vsrc_color = {
.priv_size = sizeof(ColorContext), .priv_size = sizeof(ColorContext),
.init = color_init, .init = color_init,
.uninit = color_uninit,
.query_formats = query_formats, .query_formats = query_formats,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment