avfilter/vf_stack: simplify main processing path
authorPaul B Mahol <onemda@gmail.com>
Wed, 25 Sep 2019 16:40:56 +0000 (18:40 +0200)
committerPaul B Mahol <onemda@gmail.com>
Wed, 25 Sep 2019 16:40:56 +0000 (18:40 +0200)
libavfilter/vf_stack.c

index 4d254e0..3b05807 100644 (file)
@@ -82,6 +82,10 @@ static av_cold int init(AVFilterContext *ctx)
     if (!s->frames)
         return AVERROR(ENOMEM);
 
+    s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
+    if (!s->items)
+        return AVERROR(ENOMEM);
+
     if (!strcmp(ctx->filter->name, "xstack")) {
         if (!s->layout) {
             if (s->nb_inputs == 2) {
@@ -93,10 +97,6 @@ static av_cold int init(AVFilterContext *ctx)
                 return AVERROR(EINVAL);
             }
         }
-
-        s->items = av_calloc(s->nb_inputs, sizeof(*s->items));
-        if (!s->items)
-            return AVERROR(ENOMEM);
     }
 
     for (i = 0; i < s->nb_inputs; i++) {
@@ -123,7 +123,7 @@ static int process_frame(FFFrameSync *fs)
     StackContext *s = fs->opaque;
     AVFrame **in = s->frames;
     AVFrame *out;
-    int i, p, ret, offset[4] = { 0 };
+    int i, p, ret;
 
     for (i = 0; i < s->nb_inputs; i++) {
         if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0)
@@ -137,44 +137,14 @@ static int process_frame(FFFrameSync *fs)
     out->sample_aspect_ratio = outlink->sample_aspect_ratio;
 
     for (i = 0; i < s->nb_inputs; i++) {
-        AVFilterLink *inlink = ctx->inputs[i];
-        int linesize[4];
-        int height[4];
-
-        if (s->is_horizontal || s->is_vertical) {
-            if ((ret = av_image_fill_linesizes(linesize, inlink->format, inlink->w)) < 0) {
-                av_frame_free(&out);
-                return ret;
-            }
-
-            height[1] = height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
-            height[0] = height[3] = inlink->h;
-        }
+        StackItem *item = &s->items[i];
 
         for (p = 0; p < s->nb_planes; p++) {
-            if (s->is_vertical) {
-                av_image_copy_plane(out->data[p] + offset[p] * out->linesize[p],
-                                    out->linesize[p],
-                                    in[i]->data[p],
-                                    in[i]->linesize[p],
-                                    linesize[p], height[p]);
-                offset[p] += height[p];
-            } else if (s->is_horizontal) {
-                av_image_copy_plane(out->data[p] + offset[p],
-                                    out->linesize[p],
-                                    in[i]->data[p],
-                                    in[i]->linesize[p],
-                                    linesize[p], height[p]);
-                offset[p] += linesize[p];
-            } else {
-                StackItem *item = &s->items[i];
-
-                av_image_copy_plane(out->data[p] + out->linesize[p] * item->y[p] + item->x[p],
-                                    out->linesize[p],
-                                    in[i]->data[p],
-                                    in[i]->linesize[p],
-                                    item->linesize[p], item->height[p]);
-            }
+            av_image_copy_plane(out->data[p] + out->linesize[p] * item->y[p] + item->x[p],
+                                out->linesize[p],
+                                in[i]->data[p],
+                                in[i]->linesize[p],
+                                item->linesize[p], item->height[p]);
         }
     }
 
@@ -197,20 +167,53 @@ static int config_output(AVFilterLink *outlink)
         return AVERROR_BUG;
 
     if (s->is_vertical) {
-        for (i = 1; i < s->nb_inputs; i++) {
+        for (i = 0; i < s->nb_inputs; i++) {
+            AVFilterLink *inlink = ctx->inputs[i];
+            StackItem *item = &s->items[i];
+
             if (ctx->inputs[i]->w != width) {
                 av_log(ctx, AV_LOG_ERROR, "Input %d width %d does not match input %d width %d.\n", i, ctx->inputs[i]->w, 0, width);
                 return AVERROR(EINVAL);
             }
-            height += ctx->inputs[i]->h;
+
+            if ((ret = av_image_fill_linesizes(item->linesize, inlink->format, inlink->w)) < 0) {
+                return ret;
+            }
+
+            item->height[1] = item->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
+            item->height[0] = item->height[3] = inlink->h;
+
+            if (i) {
+                item->y[1] = item->y[2] = AV_CEIL_RSHIFT(height, s->desc->log2_chroma_h);
+                item->y[0] = item->y[3] = height;
+
+                height += ctx->inputs[i]->h;
+            }
         }
     } else if (s->is_horizontal) {
-        for (i = 1; i < s->nb_inputs; i++) {
+        for (i = 0; i < s->nb_inputs; i++) {
+            AVFilterLink *inlink = ctx->inputs[i];
+            StackItem *item = &s->items[i];
+
             if (ctx->inputs[i]->h != height) {
                 av_log(ctx, AV_LOG_ERROR, "Input %d height %d does not match input %d height %d.\n", i, ctx->inputs[i]->h, 0, height);
                 return AVERROR(EINVAL);
             }
-            width += ctx->inputs[i]->w;
+
+            if ((ret = av_image_fill_linesizes(item->linesize, inlink->format, inlink->w)) < 0) {
+                return ret;
+            }
+
+            item->height[1] = item->height[2] = AV_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
+            item->height[0] = item->height[3] = inlink->h;
+
+            if (i) {
+                if ((ret = av_image_fill_linesizes(item->x, inlink->format, width)) < 0) {
+                    return ret;
+                }
+
+                width += ctx->inputs[i]->w;
+            }
         }
     } else {
         char *arg, *p = s->layout, *saveptr = NULL;