[FFmpeg-devel] [PATCH] lavf/vf_stack: add keep_dar option for vstack and hstack

Paul B Mahol onemda at gmail.com
Mon Jul 8 15:23:22 EEST 2019


Not acceptable patch.

Please do not merge.

On 7/8/19, lance.lmwang at gmail.com <lance.lmwang at gmail.com> wrote:
> From: Limin Wang <lance.lmwang at gmail.com>
>
> It's useful to compare two 4K videos quality side by side on 4K TV.
>
> Signed-off-by: Limin Wang <lance.lmwang at 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.
>
> + at 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.
>
> + at 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 },
>  };
> --
> 2.21.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".


More information about the ffmpeg-devel mailing list