lavfi/af_join: partially fix scheduling.
authorNicolas George <george@nsup.org>
Thu, 22 Oct 2015 07:56:11 +0000 (09:56 +0200)
committerNicolas George <george@nsup.org>
Sat, 7 Nov 2015 15:43:36 +0000 (16:43 +0100)
libavfilter/af_join.c

index f5a1c50..bd780cc 100644 (file)
@@ -78,11 +78,13 @@ static const AVOption join_options[] = {
 
 AVFILTER_DEFINE_CLASS(join);
 
+static int try_push_frame(AVFilterContext *ctx);
+
 static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     AVFilterContext *ctx = link->dst;
     JoinContext       *s = ctx->priv;
-    int i;
+    int i, j;
 
     for (i = 0; i < ctx->nb_inputs; i++)
         if (link == ctx->inputs[i])
@@ -91,7 +93,17 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
     av_assert0(!s->input_frames[i]);
     s->input_frames[i] = frame;
 
-    return 0;
+    /* request the same number of samples on all inputs */
+    /* FIXME that means a frame arriving asynchronously on a different input
+       will not have the requested number of samples */
+    if (i == 0) {
+        int nb_samples = s->input_frames[0]->nb_samples;
+
+        for (j = 1; !i && j < ctx->nb_inputs; j++)
+            ctx->inputs[j]->request_samples = nb_samples;
+    }
+
+    return try_push_frame(ctx);
 }
 
 static int parse_maps(AVFilterContext *ctx)
@@ -387,27 +399,31 @@ static int join_request_frame(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
     JoinContext *s       = ctx->priv;
-    AVFrame *frame;
-    int linesize   = INT_MAX;
-    int nb_samples = 0;
-    int nb_buffers = 0;
-    int i, j, ret;
+    int i;
 
     /* get a frame on each input */
     for (i = 0; i < ctx->nb_inputs; i++) {
         AVFilterLink *inlink = ctx->inputs[i];
+        if (!s->input_frames[i])
+            return ff_request_frame(inlink);
+    }
+    return 0;
+}
 
-        if (!s->input_frames[i] &&
-            (ret = ff_request_frame(inlink)) < 0)
-            return ret;
-
-        /* request the same number of samples on all inputs */
-        if (i == 0) {
-            nb_samples = s->input_frames[0]->nb_samples;
+static int try_push_frame(AVFilterContext *ctx)
+{
+    AVFilterLink *outlink = ctx->outputs[0];
+    JoinContext *s       = ctx->priv;
+    AVFrame *frame;
+    int linesize   = INT_MAX;
+    int nb_samples = INT_MAX;
+    int nb_buffers = 0;
+    int i, j, ret;
 
-            for (j = 1; !i && j < ctx->nb_inputs; j++)
-                ctx->inputs[j]->request_samples = nb_samples;
-        }
+    for (i = 0; i < ctx->nb_inputs; i++) {
+        if (!s->input_frames[i])
+            return 0;
+        nb_samples = FFMIN(nb_samples, s->input_frames[i]->nb_samples);
     }
 
     /* setup the output frame */