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.

Attachment: pgp0EVQ1knsUK.pgp
Description: PGP signature

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to