On Mon, Jul 08, 2019 at 05:44:06PM +0530, Gyan wrote:
> 
> 
> On 08-07-2019 04:18 PM, lance.lmw...@gmail.com wrote:
> >From: Limin Wang <lance.lmw...@gmail.com>
> >
> >It's useful to compare two 4K videos quality side by side on 4K TV.
> >
> >Signed-off-by: Limin Wang <lance.lmw...@gmail.com>
> >---
> >  doc/filters.texi       |  6 ++++++
> >  libavfilter/vf_stack.c | 31 ++++++++++++++++++++++++++-----
> >  2 files changed, 32 insertions(+), 5 deletions(-)
> >
> >diff --git a/doc/filters.texi b/doc/filters.texi
> >index ee6a93ffbf..675b02fc34 100644
> >--- a/doc/filters.texi
> >+++ b/doc/filters.texi
> >@@ -11280,6 +11280,9 @@ The filter accept the following option:
> >  @item inputs
> >  Set number of input streams. Default is 2.
> >+@item keep_dar
> >+stack with 1/nb_inputs of each inputs screen to keep the same DAR, Default 
> >is 0.
> >+
> >  @item shortest
> >  If set to 1, force the output to terminate when the shortest input
> >  terminates. Default value is 0.
> >@@ -18333,6 +18336,9 @@ The filter accept the following option:
> >  @item inputs
> >  Set number of input streams. Default is 2.
> >+@item keep_dar
> >+stack with 1/nb_inputs of each inputs screen to keep the same DAR, Default 
> >is 0.
> >+
> >  @item shortest
> >  If set to 1, force the output to terminate when the shortest input
> >  terminates. Default value is 0.
> >diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c
> >index 4d254e0013..9196b5b0b7 100644
> >--- a/libavfilter/vf_stack.c
> >+++ b/libavfilter/vf_stack.c
> >@@ -44,6 +44,7 @@ typedef struct StackContext {
> >      int is_vertical;
> >      int is_horizontal;
> >      int nb_planes;
> >+    int keep_dar;
> >      StackItem *items;
> >      AVFrame **frames;
> >@@ -123,7 +124,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, offset[4] = { 0 }, in_offset[4] = { 0 };
> >      for (i = 0; i < s->nb_inputs; i++) {
> >          if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0)
> >@@ -153,16 +154,25 @@ static int process_frame(FFFrameSync *fs)
> >          for (p = 0; p < s->nb_planes; p++) {
> >              if (s->is_vertical) {
> >+                if (s->keep_dar) {
> >+                    height[p] /= s->nb_inputs;
> >+                    in_offset[p] = i * height[p] * in[i]->linesize[p];
> >+                }
> >+
> >                  av_image_copy_plane(out->data[p] + offset[p] * 
> > out->linesize[p],
> >                                      out->linesize[p],
> >-                                    in[i]->data[p],
> >+                                    in[i]->data[p] + in_offset[p],
> >                                      in[i]->linesize[p],
> >                                      linesize[p], height[p]);
> >                  offset[p] += height[p];
> >              } else if (s->is_horizontal) {
> >+                if (s->keep_dar) {
> >+                    linesize[p] /= s->nb_inputs;
> >+                    in_offset[p] = i * in[i]->linesize[p] / s->nb_inputs;
> >+                }
> >                  av_image_copy_plane(out->data[p] + offset[p],
> >                                      out->linesize[p],
> >-                                    in[i]->data[p],
> >+                                    in[i]->data[p] + in_offset[p],
> >                                      in[i]->linesize[p],
> >                                      linesize[p], height[p]);
> >                  offset[p] += linesize[p];
> >@@ -197,20 +207,30 @@ static int config_output(AVFilterLink *outlink)
> >          return AVERROR_BUG;
> >      if (s->is_vertical) {
> >+        if (s->keep_dar)
> >+            height /= s->nb_inputs;
> >          for (i = 1; i < s->nb_inputs; 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 (!s->keep_dar)
> >+                height += ctx->inputs[i]->h;
> >+            else
> >+                height += ctx->inputs[i]->h / s->nb_inputs;
> >          }
> >      } else if (s->is_horizontal) {
> >+        if (s->keep_dar)
> >+            width /= s->nb_inputs;
> >          for (i = 1; i < s->nb_inputs; 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 (!s->keep_dar)
> >+                width += ctx->inputs[i]->w;
> >+            else
> >+                width += ctx->inputs[i]->w / s->nb_inputs;
> >          }
> >      } else {
> >          char *arg, *p = s->layout, *saveptr = NULL;
> >@@ -339,6 +359,7 @@ static int activate(AVFilterContext *ctx)
> >  #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
> >  static const AVOption stack_options[] = {
> >      { "inputs", "set number of inputs", OFFSET(nb_inputs), 
> > AV_OPT_TYPE_INT, {.i64=2}, 2, INT_MAX, .flags = FLAGS },
> >+    { "keep_dar", "stack with 1/nb_inputs of each inputs screen to keep the 
> >same DAR", OFFSET(keep_dar), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, .flags = FLAGS 
> >},
> >      { "shortest", "force termination when the shortest input terminates", 
> > OFFSET(shortest), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS },
> >      { NULL },
> >  };
> 
> Keep DAR of which input i.e. what if the inputs have different DARs?

I'm using it for comparing two same video quality, it's not general
for all condition anyway. 

> 
> The user can already emulate this by cropping inputs befoehand.
Yes, we can use the crop filter to get the same function, however the
command line isn't very direct to use and difficult to recall.


> 
> Gyan
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to