diff mbox

[FFmpeg-devel,1/2] avfilter/vf_palettegen: add mode for generating palette for each input frame

Message ID 1472848930-1985-1-git-send-email-onemda@gmail.com
State Accepted
Headers show

Commit Message

Paul B Mahol Sept. 2, 2016, 8:42 p.m. UTC
Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavfilter/vf_palettegen.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

Comments

Clément Bœsch Sept. 6, 2016, 2:51 p.m. UTC | #1
On Fri, Sep 02, 2016 at 10:42:09PM +0200, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
>  libavfilter/vf_palettegen.c | 27 +++++++++++++++++++++++----
>  1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
> index fccc5ca..3018b06 100644
> --- a/libavfilter/vf_palettegen.c
> +++ b/libavfilter/vf_palettegen.c
> @@ -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,9 @@ 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);
> +    int64_t in_pts = in->pts;
>  
>      if (ret > 0)
>          s->nb_refs += ret;
> @@ -493,6 +496,22 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>          av_frame_free(&in);
>      }
>  
> +    if (s->stats_mode == STATS_MODE_SINGLE_FRAMES) {
> +        AVFrame *out;
> +        int i;
> +
> +        out = get_palette_frame(ctx);
> +        out->pts = in_pts;
> +        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));
> +    }
> +


I'd prefer:

    if (s->stats_mode == STATS_MODE_DIFF_FRAMES) {
        av_frame_free(&s->prev_frame);
        s->prev_frame = in;
    if (s->stats_mode == STATS_MODE_SINGLE_FRAMES) {

        // ...
        out->pts = in->pts;
        // ...
        av_frame_free(&in);

    } else {
        av_frame_free(&in);
    }

[...]

otherwise LGTM, thanks
diff mbox

Patch

diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
index fccc5ca..3018b06 100644
--- a/libavfilter/vf_palettegen.c
+++ b/libavfilter/vf_palettegen.c
@@ -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,9 @@  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);
+    int64_t in_pts = in->pts;
 
     if (ret > 0)
         s->nb_refs += ret;
@@ -493,6 +496,22 @@  static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         av_frame_free(&in);
     }
 
+    if (s->stats_mode == STATS_MODE_SINGLE_FRAMES) {
+        AVFrame *out;
+        int i;
+
+        out = get_palette_frame(ctx);
+        out->pts = in_pts;
+        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));
+    }
+
     return ret;
 }
 
@@ -507,7 +526,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;