[FFmpeg-devel] [PATCH 4/6] avfilter: add palettegen filter

Clément Bœsch u at pkh.me
Tue Jan 27 14:02:17 CET 2015

On Sun, Jan 25, 2015 at 07:55:21PM +0100, Clément Bœsch wrote:
> ---
>  doc/filters.texi            |  24 +++
>  libavfilter/Makefile        |   1 +
>  libavfilter/allfilters.c    |   1 +
>  libavfilter/vf_palettegen.c | 382 ++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 408 insertions(+)
>  create mode 100644 libavfilter/vf_palettegen.c

To answer the question from Paul on IRC:
13:11:13 <@durandal_1707> ubitux: what about changing pallete in palletegen when scene changes?

This was my initial plan, but since the original goal is for GIF this
isn't actually practical: with this format, you have one global palette
and eventually one palette per frame. If you want to change the global
palette, you need to change it for every frame. There is no mechanism
(AFAIK) that allows you to say "reuse the previous palette" (assuming it's
not the global one).

So basically, implementing this scene change mechanism is possible but
will cause a 768B overhead per frame (assuming full depth palette)
starting the first scene change at best.  The palette is not part of LZW,
so not compressed. As a result, I preferred having one global palette for
this first version.


BTW, this patch is also locally updated with this:

diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
index eaa4938..23c1979 100644
--- a/libavfilter/vf_palettegen.c
+++ b/libavfilter/vf_palettegen.c
@@ -47,6 +47,7 @@ typedef struct {
     int nb_refs;
     struct range_box boxes[256];    // define the segmentation of the colorspace
     int nb_boxes;
+    int palette_pushed;
 } PaletteGenContext;
 #define OFFSET(x) offsetof(PaletteGenContext, x)
@@ -329,14 +330,14 @@ static int request_frame(AVFilterLink *outlink)
     AVFilterContext *ctx = outlink->src;
     AVFilterLink *inlink = ctx->inputs[0];
+    PaletteGenContext *s = ctx->priv;
     int r;
     r = ff_request_frame(inlink);
-    if (r == AVERROR_EOF) {
+    if (r == AVERROR_EOF && !s->palette_pushed) {
         r = ff_filter_frame(outlink, get_palette_frame(ctx));
-        if (r < 0)
-            return r;
-        return AVERROR_EOF;
+        s->palette_pushed = 1;
+        return r;
     return r;

...so the EOF/request_frame actually works for API users. I wasn't able to
figure out how ffmpeg manage to get the output: using the API, flushing by
sending a NULL frame and pulling until EOF didn't get me the last frame unless
I did this change.

Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150127/bb9fa412/attachment.asc>

More information about the ffmpeg-devel mailing list