[FFmpeg-devel] [PATCH] avfilter/scale.c: factorize ff_scale_eval_dimensions

Michael Niedermayer michael at niedermayer.cc
Fri Dec 6 21:06:07 EET 2019


On Wed, Dec 04, 2019 at 02:14:35PM +0530, Gyan wrote:
> Will help reduce code duplication when adding animation support to vf_scale.
> See Michael's last comment in https://patchwork.ffmpeg.org/patch/16272/
> 
> Gyan

>  doc/filters.texi             |   40 +++++++++++++++++++++++++++++
>  libavfilter/scale.c          |   59 ++++++++++++++++++++++++++++++++++---------
>  libavfilter/scale.h          |    4 ++
>  libavfilter/vf_scale.c       |   28 ++------------------
>  libavfilter/vf_scale_cuda.c  |   11 ++++++++
>  libavfilter/vf_scale_npp.c   |   11 ++++++++
>  libavfilter/vf_scale_vaapi.c |   11 ++++++++
>  7 files changed, 128 insertions(+), 36 deletions(-)
> 380bf799c14d6286cc625afe019aa553614a7d53  0001-avfilter-scale.c-factorize-ff_scale_eval_dimensions.patch
> From 138a8dba766674a1b017614c58fa99aeca98e9e5 Mon Sep 17 00:00:00 2001
> From: Gyan Doshi <ffmpeg at gyani.pro>
> Date: Mon, 2 Dec 2019 21:11:21 +0530
> Subject: [PATCH] avfilter/scale.c: factorize ff_scale_eval_dimensions
> 
> Adjustment of evaluated values shifted to ff_adjust_scale_dimensions
> Shifted code for force_original_aspect_ratio and force_divisble_by from
> vf_scale so it is now available for scale_cuda, scale_npp and
> scale_vaapi as well.
> ---
>  doc/filters.texi             | 40 ++++++++++++++++++++++++
>  libavfilter/scale.c          | 59 +++++++++++++++++++++++++++++-------
>  libavfilter/scale.h          |  4 +++
>  libavfilter/vf_scale.c       | 28 ++---------------
>  libavfilter/vf_scale_cuda.c  | 11 +++++++
>  libavfilter/vf_scale_npp.c   | 11 +++++++
>  libavfilter/vf_scale_vaapi.c | 11 +++++++
>  7 files changed, 128 insertions(+), 36 deletions(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 5fdec6f015..9129f7e3a5 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -16210,6 +16210,46 @@ Supersampling
>  @item lanczos
>  @end table
>  
> + at item force_original_aspect_ratio
> +Enable decreasing or increasing output video width or height if necessary to
> +keep the original aspect ratio. Possible values:
> +
> + at table @samp
> + at item disable
> +Scale the video as specified and disable this feature.
> +
> + at item decrease
> +The output video dimensions will automatically be decreased if needed.
> +
> + at item increase
> +The output video dimensions will automatically be increased if needed.
> +
> + at end table
> +
> +One useful instance of this option is that when you know a specific device's
> +maximum allowed resolution, you can use this to limit the output video to
> +that, while retaining the aspect ratio. For example, device A allows
> +1280x720 playback, and your video is 1920x800. Using this option (set it to
> +decrease) and specifying 1280x720 to the command line makes the output
> +1280x533.
> +
> +Please note that this is a different thing than specifying -1 for @option{w}
> +or @option{h}, you still need to specify the output resolution for this option
> +to work.
> +
> + at item force_divisible_by
> +Ensures that both the output dimensions, width and height, are divisible by the
> +given integer when used together with @option{force_original_aspect_ratio}. This
> +works similar to using @code{-n} in the @option{w} and @option{h} options.
> +
> +This option respects the value set for @option{force_original_aspect_ratio},
> +increasing or decreasing the resolution accordingly. The video's aspect ratio
> +may be slightly modified.
> +
> +This option can be handy if you need to have a video fit within or exceed
> +a defined resolution using @option{force_original_aspect_ratio} but also have
> +encoder restrictions on width or height divisibility.
> +
>  @end table
>  
>  @section scale2ref
> diff --git a/libavfilter/scale.c b/libavfilter/scale.c
> index eaee95fac6..5e9f97230c 100644
> --- a/libavfilter/scale.c
> +++ b/libavfilter/scale.c
> @@ -111,8 +111,6 @@ int ff_scale_eval_dimensions(void *log_ctx,
>      const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
>      const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);
>      const char *expr;
> -    int w, h;
> -    int factor_w, factor_h;
>      int eval_w, eval_h;
>      int ret;
>      const char scale2ref = outlink->src->nb_inputs == 2 && outlink->src->inputs[1] == inlink;
> @@ -172,8 +170,28 @@ int ff_scale_eval_dimensions(void *log_ctx,
>          goto fail;
>      eval_w = (int) res == 0 ? inlink->w : (int) res;
>  
> -    w = eval_w;
> -    h = eval_h;
> +    *ret_w = eval_w;
> +    *ret_h = eval_h;
> +
> +    return 0;
> +
> +fail:
> +    av_log(log_ctx, AV_LOG_ERROR,
> +           "Error when evaluating the expression '%s'.\n"
> +           "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
> +           expr, w_expr, h_expr);
> +    return ret;
> +}
> +
> +int ff_scale_adjust_dimensions(AVFilterLink *inlink,
> +    int *ret_w, int *ret_h,
> +    int force_original_aspect_ratio, int force_divisible_by)
> +{
> +    int w, h;
> +    int factor_w, factor_h;
> +
> +    w = *ret_w;
> +    h = *ret_h;
>  
>      /* Check if it is requested that the result has to be divisible by a some
>       * factor (w or h = -n with n being the factor). */
> @@ -199,15 +217,34 @@ int ff_scale_eval_dimensions(void *log_ctx,
>      if (h < 0)
>          h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h;
>  
> +    /* Note that force_original_aspect_ratio may overwrite the previous set
> +     * dimensions so that it is not divisible by the set factors anymore
> +     * unless force_divisible_by is defined as well */
> +    if (force_original_aspect_ratio) {
> +        int tmp_w = av_rescale(h, inlink->w, inlink->h);
> +        int tmp_h = av_rescale(w, inlink->h, inlink->w);
> +
> +        if (force_original_aspect_ratio == 1) {
> +             w = FFMIN(tmp_w, w);
> +             h = FFMIN(tmp_h, h);
> +             if (force_divisible_by > 1) {
> +                 // round down
> +                 w = w / force_divisible_by * force_divisible_by;
> +                 h = h / force_divisible_by * force_divisible_by;
> +             }
> +        } else {
> +             w = FFMAX(tmp_w, w);
> +             h = FFMAX(tmp_h, h);
> +             if (force_divisible_by > 1) {
> +                 // round up
> +                 w = (w + force_divisible_by - 1) / force_divisible_by * force_divisible_by;
> +                 h = (h + force_divisible_by - 1) / force_divisible_by * force_divisible_by;
> +             }
> +        }
> +    }
> +
>      *ret_w = w;
>      *ret_h = h;
>  
>      return 0;
> -
> -fail:
> -    av_log(log_ctx, AV_LOG_ERROR,
> -           "Error when evaluating the expression '%s'.\n"
> -           "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
> -           expr, w_expr, h_expr);
> -    return ret;
>  }

> diff --git a/libavfilter/scale.h b/libavfilter/scale.h
> index dfe67d0be0..fa480d727a 100644
> --- a/libavfilter/scale.h
> +++ b/libavfilter/scale.h
> @@ -25,4 +25,8 @@ int ff_scale_eval_dimensions(void *ctx,
>      const char *w_expr, const char *h_expr,
>      AVFilterLink *inlink, AVFilterLink *outlink,
>      int *ret_w, int *ret_h);
> +
> +int ff_scale_adjust_dimensions(AVFilterLink *inlink,
> +    int *ret_w, int *ret_h,
> +    int force_original_aspect_ratio, int force_divisible_by);
>  #endif

This should be documented so developers know what it is, how to use it
and what changes can be done to it without breaking code using it.

That would make it easier to future contributors to work on this
function and the code calling this function

thx

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Asymptotically faster algorithms should always be preferred if you have
asymptotical amounts of data
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20191206/a9b163ec/attachment.sig>


More information about the ffmpeg-devel mailing list