From 20d00cead1e47b2e389fde99a3c0f9c36b6587ec Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Tue, 20 Jun 2017 19:44:54 +0200
Subject: [PATCH] shit

Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavfilter/framesync.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 libavfilter/framesync.h |  4 ++++
 libavfilter/vf_stack.c  |  9 ++++-----
 3 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c
index eb05d66..f2a4450 100644
--- a/libavfilter/framesync.c
+++ b/libavfilter/framesync.c
@@ -23,6 +23,7 @@
 
 #include "libavutil/avassert.h"
 #include "avfilter.h"
+#include "filters.h"
 #include "bufferqueue.h"
 #include "framesync.h"
 #include "internal.h"
@@ -224,6 +225,22 @@ void ff_framesync_next(FFFrameSync *fs)
     framesync_advance(fs);
 }
 
+void ff_framesync_next2(FFFrameSync *fs)
+{
+    AVFilterContext *ctx = fs->parent;
+    unsigned i;
+
+    av_assert0(!fs->frame_ready);
+    for (i = 0; i < fs->nb_in; i++)
+        if (!fs->in[i].have_next && ff_framequeue_queued_frames(&ctx->inputs[i]->fifo)) {
+            framesync_inject_frame(fs, i, ff_framequeue_take(&ctx->inputs[i]->fifo));
+            ctx->inputs[i]->frame_wanted_out = 1;
+            ff_filter_set_ready(ctx->inputs[i]->src, 100);
+        }
+    fs->frame_ready = 0;
+    framesync_advance(fs);
+}
+
 void ff_framesync_drop(FFFrameSync *fs)
 {
     fs->frame_ready = 0;
@@ -300,6 +317,27 @@ int ff_framesync_process_frame(FFFrameSync *fs, unsigned all)
     return count;
 }
 
+int ff_framesync_process_frame2(FFFrameSync *fs, unsigned all)
+{
+    int ret, count = 0;
+
+    av_assert0(fs->on_event);
+    while (1) {
+        ff_framesync_next2(fs);
+        if (fs->eof || !fs->frame_ready)
+            break;
+        if ((ret = fs->on_event(fs)) < 0)
+            return ret;
+        ff_framesync_drop(fs);
+        count++;
+        if (!all)
+            break;
+    }
+    if (!count && fs->eof)
+        return AVERROR_EOF;
+    return count;
+}
+
 int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
                               AVFrame *in)
 {
@@ -314,6 +352,15 @@ int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
     return 0;
 }
 
+int ff_framesync_activate(FFFrameSync *fs, AVFilterContext *ctx)
+{
+    int ret;
+
+    if ((ret = ff_framesync_process_frame2(fs, 1)) < 0)
+        return ret;
+    return 0;
+}
+
 int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
diff --git a/libavfilter/framesync.h b/libavfilter/framesync.h
index 7ba99d5..0f381e3 100644
--- a/libavfilter/framesync.h
+++ b/libavfilter/framesync.h
@@ -250,6 +250,7 @@ int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame);
  * The status of the operation can be found in fs->frame_ready and fs->eof.
  */
 void ff_framesync_next(FFFrameSync *fs);
+void ff_framesync_next2(FFFrameSync *fs);
 
 /**
  * Drop the current frame event.
@@ -275,6 +276,7 @@ int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
  * @return  number of frames processed or negative error code
  */
 int ff_framesync_process_frame(FFFrameSync *fs, unsigned all);
+int ff_framesync_process_frame2(FFFrameSync *fs, unsigned all);
 
 
 /**
@@ -286,6 +288,8 @@ int ff_framesync_process_frame(FFFrameSync *fs, unsigned all);
 int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
                               AVFrame *in);
 
+int ff_framesync_activate(FFFrameSync *fs, AVFilterContext *ctx);
+
 /**
  * Request a frame on the filter output.
  *
diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
index 03643b6..0e45952 100644
--- a/libavfilter/vf_stack.c
+++ b/libavfilter/vf_stack.c
@@ -58,10 +58,10 @@ static int query_formats(AVFilterContext *ctx)
     return ff_set_common_formats(ctx, pix_fmts);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+static int activate(AVFilterContext *ctx)
 {
-    StackContext *s = inlink->dst->priv;
-    return ff_framesync_filter_frame(&s->fs, inlink, in);
+    StackContext *s = ctx->priv;
+    return ff_framesync_activate(&s->fs, ctx);
 }
 
 static av_cold int init(AVFilterContext *ctx)
@@ -83,7 +83,6 @@ static av_cold int init(AVFilterContext *ctx)
         pad.name = av_asprintf("input%d", i);
         if (!pad.name)
             return AVERROR(ENOMEM);
-        pad.filter_frame = filter_frame;
 
         if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) {
             av_freep(&pad.name);
@@ -237,7 +236,6 @@ static const AVFilterPad outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
-        .request_frame = request_frame,
     },
     { NULL }
 };
@@ -274,6 +272,7 @@ AVFilter ff_vf_vstack = {
     .query_formats = query_formats,
     .outputs       = outputs,
     .init          = init,
+    .activate      = activate,
     .uninit        = uninit,
     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
-- 
2.9.3

