avfilter/vf_palettegen: add mode for generating palette for each input frame

Signed-off-by: Paul B Mahol <onemda@gmail.com>
pull/232/head
Paul B Mahol 8 years ago
parent 424f0f9e33
commit 93ae68d62a
  1. 23
      libavfilter/vf_palettegen.c

@ -53,6 +53,7 @@ struct hist_node {
enum { enum {
STATS_MODE_ALL_FRAMES, STATS_MODE_ALL_FRAMES,
STATS_MODE_DIFF_FRAMES, STATS_MODE_DIFF_FRAMES,
STATS_MODE_SINGLE_FRAMES,
NB_STATS_MODE NB_STATS_MODE
}; };
@ -80,9 +81,10 @@ typedef struct {
static const AVOption palettegen_options[] = { static const AVOption palettegen_options[] = {
{ "max_colors", "set the maximum number of colors to use in the palette", OFFSET(max_colors), AV_OPT_TYPE_INT, {.i64=256}, 4, 256, FLAGS }, { "max_colors", "set the maximum number of colors to use in the palette", OFFSET(max_colors), AV_OPT_TYPE_INT, {.i64=256}, 4, 256, FLAGS },
{ "reserve_transparent", "reserve a palette entry for transparency", OFFSET(reserve_transparent), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, { "reserve_transparent", "reserve a palette entry for transparency", OFFSET(reserve_transparent), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
{ "stats_mode", "set statistics mode", OFFSET(stats_mode), AV_OPT_TYPE_INT, {.i64=STATS_MODE_ALL_FRAMES}, 0, NB_STATS_MODE, FLAGS, "mode" }, { "stats_mode", "set statistics mode", OFFSET(stats_mode), AV_OPT_TYPE_INT, {.i64=STATS_MODE_ALL_FRAMES}, 0, NB_STATS_MODE-1, FLAGS, "mode" },
{ "full", "compute full frame histograms", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_ALL_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" }, { "full", "compute full frame histograms", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_ALL_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" },
{ "diff", "compute histograms only for the part that differs from previous frame", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_DIFF_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" }, { "diff", "compute histograms only for the part that differs from previous frame", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_DIFF_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" },
{ "single", "compute new histogram for each frame", 0, AV_OPT_TYPE_CONST, {.i64=STATS_MODE_SINGLE_FRAMES}, INT_MIN, INT_MAX, FLAGS, "mode" },
{ NULL } { NULL }
}; };
@ -480,7 +482,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{ {
AVFilterContext *ctx = inlink->dst; AVFilterContext *ctx = inlink->dst;
PaletteGenContext *s = ctx->priv; PaletteGenContext *s = ctx->priv;
const int ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in) int ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in)
: update_histogram_frame(s->histogram, in); : update_histogram_frame(s->histogram, in);
if (ret > 0) if (ret > 0)
@ -489,6 +491,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
if (s->stats_mode == STATS_MODE_DIFF_FRAMES) { if (s->stats_mode == STATS_MODE_DIFF_FRAMES) {
av_frame_free(&s->prev_frame); av_frame_free(&s->prev_frame);
s->prev_frame = in; s->prev_frame = in;
} else if (s->stats_mode == STATS_MODE_SINGLE_FRAMES) {
AVFrame *out;
int i;
out = get_palette_frame(ctx);
out->pts = in->pts;
av_frame_free(&in);
ret = ff_filter_frame(ctx->outputs[0], out);
for (i = 0; i < HIST_SIZE; i++)
av_freep(&s->histogram[i].entries);
av_freep(&s->refs);
s->nb_refs = 0;
s->nb_boxes = 0;
memset(s->boxes, 0, sizeof(s->boxes));
memset(s->histogram, 0, sizeof(s->histogram));
} else { } else {
av_frame_free(&in); av_frame_free(&in);
} }
@ -507,7 +524,7 @@ static int request_frame(AVFilterLink *outlink)
int r; int r;
r = ff_request_frame(inlink); r = ff_request_frame(inlink);
if (r == AVERROR_EOF && !s->palette_pushed && s->nb_refs) { if (r == AVERROR_EOF && !s->palette_pushed && s->nb_refs && s->stats_mode != STATS_MODE_SINGLE_FRAMES) {
r = ff_filter_frame(outlink, get_palette_frame(ctx)); r = ff_filter_frame(outlink, get_palette_frame(ctx));
s->palette_pushed = 1; s->palette_pushed = 1;
return r; return r;

Loading…
Cancel
Save