avfilter/vf_zoompan: switch to activate
authorPaul B Mahol <onemda@gmail.com>
Sun, 27 Aug 2017 14:51:24 +0000 (16:51 +0200)
committerPaul B Mahol <onemda@gmail.com>
Sun, 27 Aug 2017 15:13:21 +0000 (17:13 +0200)
Fixes #5182.

Signed-off-by: Paul B Mahol <onemda@gmail.com>
libavfilter/vf_zoompan.c

index 53a0700..6998441 100644 (file)
@@ -23,6 +23,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
+#include "filters.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
@@ -217,97 +218,91 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va
     sws_freeContext(s->sws);
     s->sws = NULL;
     s->current_frame++;
+
+    if (s->current_frame >= s->nb_frames) {
+        if (*dx != -1)
+            s->x = *dx;
+        if (*dy != -1)
+            s->y = *dy;
+        if (*zoom != -1)
+            s->prev_zoom = *zoom;
+        s->prev_nb_frames = s->nb_frames;
+        s->nb_frames = 0;
+        s->current_frame = 0;
+        av_frame_free(&s->in);
+        s->finished = 1;
+    }
     return ret;
 error:
     av_frame_free(&out);
     return ret;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+static int activate(AVFilterContext *ctx)
 {
-    AVFilterContext *ctx = inlink->dst;
-    AVFilterLink *outlink = ctx->outputs[0];
     ZPContext *s = ctx->priv;
-    double nb_frames;
-    int ret;
-
-    av_assert0(s->in == NULL);
-
-    s->finished = 0;
-    s->var_values[VAR_IN_W]  = s->var_values[VAR_IW] = in->width;
-    s->var_values[VAR_IN_H]  = s->var_values[VAR_IH] = in->height;
-    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w;
-    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h;
-    s->var_values[VAR_IN]    = inlink->frame_count_out + 1;
-    s->var_values[VAR_ON]    = outlink->frame_count_in + 1;
-    s->var_values[VAR_PX]    = s->x;
-    s->var_values[VAR_PY]    = s->y;
-    s->var_values[VAR_X]     = 0;
-    s->var_values[VAR_Y]     = 0;
-    s->var_values[VAR_PZOOM] = s->prev_zoom;
-    s->var_values[VAR_ZOOM]  = 1;
-    s->var_values[VAR_PDURATION] = s->prev_nb_frames;
-    s->var_values[VAR_A]     = (double) in->width / in->height;
-    s->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
-        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
-    s->var_values[VAR_DAR]   = s->var_values[VAR_A] * s->var_values[VAR_SAR];
-    s->var_values[VAR_HSUB]  = 1 << s->desc->log2_chroma_w;
-    s->var_values[VAR_VSUB]  = 1 << s->desc->log2_chroma_h;
-
-    if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str,
-                                      var_names, s->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
-        av_frame_free(&in);
-        return ret;
-    }
-
-    s->var_values[VAR_DURATION] = s->nb_frames = nb_frames;
-    s->in = in;
-
-    return 0;
-}
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    int status, ret = 0;
+    int64_t pts;
 
-static int request_frame(AVFilterLink *outlink)
-{
-    AVFilterContext *ctx = outlink->src;
-    ZPContext *s = ctx->priv;
-    AVFrame *in = s->in;
-    double zoom=-1, dx=-1, dy=-1;
-    int ret = -1;
+    if (s->in && ff_outlink_frame_wanted(outlink)) {
+        double zoom = -1, dx = -1, dy = -1;
 
-    if (in) {
-        ret = output_single_frame(ctx, in, s->var_values, s->current_frame,
+        ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame,
                                   &zoom, &dx, &dy);
         if (ret < 0)
-            goto fail;
+            return ret;
     }
 
-    if (s->current_frame >= s->nb_frames) {
-        if (dx != -1)
-            s->x = dx;
-        if (dy != -1)
-            s->y = dy;
-        if (zoom != -1)
-            s->prev_zoom = zoom;
-        s->prev_nb_frames = s->nb_frames;
-        s->nb_frames = 0;
-        s->current_frame = 0;
-        av_frame_free(&s->in);
-        s->finished = 1;
-        ret = ff_request_frame(ctx->inputs[0]);
+    if (!s->in && (ret = ff_inlink_consume_frame(inlink, &s->in)) > 0) {
+        double zoom = -1, dx = -1, dy = -1, nb_frames;
+
+        s->finished = 0;
+        s->var_values[VAR_IN_W]  = s->var_values[VAR_IW] = s->in->width;
+        s->var_values[VAR_IN_H]  = s->var_values[VAR_IH] = s->in->height;
+        s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w;
+        s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h;
+        s->var_values[VAR_IN]    = inlink->frame_count_out + 1;
+        s->var_values[VAR_ON]    = outlink->frame_count_in + 1;
+        s->var_values[VAR_PX]    = s->x;
+        s->var_values[VAR_PY]    = s->y;
+        s->var_values[VAR_X]     = 0;
+        s->var_values[VAR_Y]     = 0;
+        s->var_values[VAR_PZOOM] = s->prev_zoom;
+        s->var_values[VAR_ZOOM]  = 1;
+        s->var_values[VAR_PDURATION] = s->prev_nb_frames;
+        s->var_values[VAR_A]     = (double) s->in->width / s->in->height;
+        s->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
+            (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
+        s->var_values[VAR_DAR]   = s->var_values[VAR_A] * s->var_values[VAR_SAR];
+        s->var_values[VAR_HSUB]  = 1 << s->desc->log2_chroma_w;
+        s->var_values[VAR_VSUB]  = 1 << s->desc->log2_chroma_h;
+
+        if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str,
+                                          var_names, s->var_values,
+                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
+            av_frame_free(&s->in);
+            return ret;
+        }
+
+        s->var_values[VAR_DURATION] = s->nb_frames = nb_frames;
+
+        ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame,
+                                  &zoom, &dx, &dy);
+        if (ret < 0)
+            return ret;
+    }
+    if (ret < 0) {
+        return ret;
+    } else if (s->finished && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
+        ff_outlink_set_status(outlink, status, pts);
+        return 0;
+    } else {
+        if (ff_outlink_frame_wanted(outlink) && s->finished)
+            ff_inlink_request_frame(inlink);
+        return 0;
     }
-
-fail:
-    sws_freeContext(s->sws);
-    s->sws = NULL;
-
-    return ret;
-}
-
-static int poll_frame(AVFilterLink *link)
-{
-    ZPContext *s = link->src->priv;
-    return s->nb_frames - s->current_frame;
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -344,8 +339,6 @@ static const AVFilterPad inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .filter_frame = filter_frame,
-        .needs_fifo   = 1,
     },
     { NULL }
 };
@@ -355,8 +348,6 @@ static const AVFilterPad outputs[] = {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
         .config_props  = config_output,
-        .poll_frame    = poll_frame,
-        .request_frame = request_frame,
     },
     { NULL }
 };
@@ -369,6 +360,7 @@ AVFilter ff_vf_zoompan = {
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
+    .activate      = activate,
     .inputs        = inputs,
     .outputs       = outputs,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,