|
|
@@ -53,6 +53,7 @@ struct hist_node { |
|
|
|
enum { |
|
|
|
STATS_MODE_ALL_FRAMES, |
|
|
|
STATS_MODE_DIFF_FRAMES, |
|
|
|
STATS_MODE_SINGLE_FRAMES, |
|
|
|
NB_STATS_MODE |
|
|
|
}; |
|
|
|
|
|
|
@@ -80,9 +81,10 @@ typedef struct { |
|
|
|
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 }, |
|
|
|
{ "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" }, |
|
|
|
{ "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 } |
|
|
|
}; |
|
|
|
|
|
|
@@ -480,8 +482,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
|
|
|
{ |
|
|
|
AVFilterContext *ctx = inlink->dst; |
|
|
|
PaletteGenContext *s = ctx->priv; |
|
|
|
const int ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in) |
|
|
|
: update_histogram_frame(s->histogram, in); |
|
|
|
int ret = s->prev_frame ? update_histogram_diff(s->histogram, s->prev_frame, in) |
|
|
|
: update_histogram_frame(s->histogram, in); |
|
|
|
|
|
|
|
if (ret > 0) |
|
|
|
s->nb_refs += ret; |
|
|
@@ -489,6 +491,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
|
|
|
if (s->stats_mode == STATS_MODE_DIFF_FRAMES) { |
|
|
|
av_frame_free(&s->prev_frame); |
|
|
|
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 { |
|
|
|
av_frame_free(&in); |
|
|
|
} |
|
|
@@ -507,7 +524,7 @@ static int request_frame(AVFilterLink *outlink) |
|
|
|
int r; |
|
|
|
|
|
|
|
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)); |
|
|
|
s->palette_pushed = 1; |
|
|
|
return r; |
|
|
|