[FFmpeg-devel] [PATCH] avfilter/scale: allow dynamic output via expressions

Gyan ffmpeg at gyani.pro
Thu Nov 14 06:54:26 EET 2019



On 14-11-2019 01:12 am, Michael Niedermayer wrote:
> On Tue, Nov 12, 2019 at 07:20:47PM +0530, Gyan wrote:
>> This patch relies on the proposed addition to the eval API at
>> https://patchwork.ffmpeg.org/patch/16109/
>>
>> FATE passes.
>>
>> Gyan
>>   Makefile   |    4
>>   scale.c    |   72 ----------
>>   vf_scale.c |  436 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>>   3 files changed, 408 insertions(+), 104 deletions(-)
>> 0b528f9940afdb6de3db43d7f5883855855231a2  0001-avfilter-scale-allow-dynamic-output-via-expressions.patch
>>  From a435e1ba5455cec67df16db85d5c47f7e4cd9797 Mon Sep 17 00:00:00 2001
>> From: Gyan Doshi <ffmpeg at gyani.pro>
>> Date: Tue, 12 Nov 2019 19:04:54 +0530
>> Subject: [PATCH] avfilter/scale: allow dynamic output via expressions
>>
>> At present, dynamic output can be had from scale and scale2ref
>> filters by sending commands or varying the resolution of the
>> input (in scale) or reference stream (in scale2ref). This is
>> unwieldy when an interpolated or otherwise animated output is
>> desired.
>>
>> This commit introduces standard temporal variables that can be used
>> in width and height expressions, so dynamic output can be configured
>> at initialization or via commands. In order to achieve this, external
>> dependency on libavfilter/scale.c has been removed and equivalent
>> functionality introduced inline.
>>
>> Such varying output ought to be sent to filters which can
>> accommodate them, such as the overlay filter.
>> ---
>>   libavfilter/Makefile   |   4 +-
>>   libavfilter/scale.c    |  72 +------
>>   libavfilter/vf_scale.c | 436 +++++++++++++++++++++++++++++++++++++----
>>   3 files changed, 408 insertions(+), 104 deletions(-)
>>
>> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
>> index fce930360d..f1f6994574 100644
>> --- a/libavfilter/Makefile
>> +++ b/libavfilter/Makefile
>> @@ -358,12 +358,12 @@ OBJS-$(CONFIG_ROBERTS_OPENCL_FILTER)         += vf_convolution_opencl.o opencl.o
>>                                                   opencl/convolution.o
>>   OBJS-$(CONFIG_ROTATE_FILTER)                 += vf_rotate.o
>>   OBJS-$(CONFIG_SAB_FILTER)                    += vf_sab.o
>> -OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o scale.o
>> +OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o
>>   OBJS-$(CONFIG_SCALE_CUDA_FILTER)             += vf_scale_cuda.o vf_scale_cuda.ptx.o
>>   OBJS-$(CONFIG_SCALE_NPP_FILTER)              += vf_scale_npp.o scale.o
>>   OBJS-$(CONFIG_SCALE_QSV_FILTER)              += vf_scale_qsv.o
>>   OBJS-$(CONFIG_SCALE_VAAPI_FILTER)            += vf_scale_vaapi.o scale.o vaapi_vpp.o
>> -OBJS-$(CONFIG_SCALE2REF_FILTER)              += vf_scale.o scale.o
>> +OBJS-$(CONFIG_SCALE2REF_FILTER)              += vf_scale.o
>>   OBJS-$(CONFIG_SCROLL_FILTER)                 += vf_scroll.o
>>   OBJS-$(CONFIG_SELECT_FILTER)                 += f_select.o
>>   OBJS-$(CONFIG_SELECTIVECOLOR_FILTER)         += vf_selectivecolor.o
>> diff --git a/libavfilter/scale.c b/libavfilter/scale.c
>> index eaee95fac6..668aa04622 100644
>> --- a/libavfilter/scale.c
>> +++ b/libavfilter/scale.c
>> @@ -60,49 +60,6 @@ enum var_name {
>>       VARS_NB
>>   };
>>   
>> -/**
>> - * This must be kept in sync with var_names so that it is always a
>> - * complete list of var_names with the scale2ref specific names
>> - * appended. scale2ref values must appear in the order they appear
>> - * in the var_name_scale2ref enum but also be below all of the
>> - * non-scale2ref specific values.
>> - */
>> -static const char *const var_names_scale2ref[] = {
>> -    "PI",
>> -    "PHI",
>> -    "E",
>> -    "in_w",   "iw",
>> -    "in_h",   "ih",
>> -    "out_w",  "ow",
>> -    "out_h",  "oh",
>> -    "a",
>> -    "sar",
>> -    "dar",
>> -    "hsub",
>> -    "vsub",
>> -    "ohsub",
>> -    "ovsub",
>> -    "main_w",
>> -    "main_h",
>> -    "main_a",
>> -    "main_sar",
>> -    "main_dar", "mdar",
>> -    "main_hsub",
>> -    "main_vsub",
>> -    NULL
>> -};
>> -
>> -enum var_name_scale2ref {
>> -    VAR_S2R_MAIN_W,
>> -    VAR_S2R_MAIN_H,
>> -    VAR_S2R_MAIN_A,
>> -    VAR_S2R_MAIN_SAR,
>> -    VAR_S2R_MAIN_DAR, VAR_S2R_MDAR,
>> -    VAR_S2R_MAIN_HSUB,
>> -    VAR_S2R_MAIN_VSUB,
>> -    VARS_S2R_NB
>> -};
>> -
>>   int ff_scale_eval_dimensions(void *log_ctx,
>>       const char *w_expr, const char *h_expr,
>>       AVFilterLink *inlink, AVFilterLink *outlink,
>> @@ -115,16 +72,7 @@ int ff_scale_eval_dimensions(void *log_ctx,
>>       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;
>> -    double var_values[VARS_NB + VARS_S2R_NB], res;
>> -    const AVPixFmtDescriptor *main_desc;
>> -    const AVFilterLink *main_link;
>> -    const char *const *names = scale2ref ? var_names_scale2ref : var_names;
>> -
>> -    if (scale2ref) {
>> -        main_link = outlink->src->inputs[0];
>> -        main_desc = av_pix_fmt_desc_get(main_link->format);
>> -    }
>> +    double var_values[VARS_NB], res;
>>   
>>       var_values[VAR_PI]    = M_PI;
>>       var_values[VAR_PHI]   = M_PHI;
>> @@ -142,32 +90,20 @@ int ff_scale_eval_dimensions(void *log_ctx,
>>       var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;
>>       var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;
>>   
>> -    if (scale2ref) {
>> -        var_values[VARS_NB + VAR_S2R_MAIN_W] = main_link->w;
>> -        var_values[VARS_NB + VAR_S2R_MAIN_H] = main_link->h;
>> -        var_values[VARS_NB + VAR_S2R_MAIN_A] = (double) main_link->w / main_link->h;
>> -        var_values[VARS_NB + VAR_S2R_MAIN_SAR] = main_link->sample_aspect_ratio.num ?
>> -            (double) main_link->sample_aspect_ratio.num / main_link->sample_aspect_ratio.den : 1;
>> -        var_values[VARS_NB + VAR_S2R_MAIN_DAR] = var_values[VARS_NB + VAR_S2R_MDAR] =
>> -            var_values[VARS_NB + VAR_S2R_MAIN_A] * var_values[VARS_NB + VAR_S2R_MAIN_SAR];
>> -        var_values[VARS_NB + VAR_S2R_MAIN_HSUB] = 1 << main_desc->log2_chroma_w;
>> -        var_values[VARS_NB + VAR_S2R_MAIN_VSUB] = 1 << main_desc->log2_chroma_h;
>> -    }
>> -
>>       /* evaluate width and height */
>>       av_expr_parse_and_eval(&res, (expr = w_expr),
>> -                           names, var_values,
>> +                           var_names, var_values,
>>                              NULL, NULL, NULL, NULL, NULL, 0, log_ctx);
>>       eval_w = var_values[VAR_OUT_W] = var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res;
>>   
>>       if ((ret = av_expr_parse_and_eval(&res, (expr = h_expr),
>> -                                      names, var_values,
>> +                                      var_names, var_values,
>>                                         NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)
>>           goto fail;
>>       eval_h = var_values[VAR_OUT_H] = var_values[VAR_OH] = (int) res == 0 ? inlink->h : (int) res;
>>       /* evaluate again the width, as it may depend on the output height */
>>       if ((ret = av_expr_parse_and_eval(&res, (expr = w_expr),
>> -                                      names, var_values,
>> +                                      var_names, var_values,
>>                                         NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)
>>           goto fail;
>>       eval_w = (int) res == 0 ? inlink->w : (int) res;
>> diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
>> index 41ddec7661..cbacd34827 100644
>> --- a/libavfilter/vf_scale.c
>> +++ b/libavfilter/vf_scale.c
>> @@ -29,9 +29,9 @@
>>   #include "avfilter.h"
>>   #include "formats.h"
>>   #include "internal.h"
>> -#include "scale.h"
>>   #include "video.h"
>>   #include "libavutil/avstring.h"
>> +#include "libavutil/eval.h"
>>   #include "libavutil/internal.h"
>>   #include "libavutil/mathematics.h"
>>   #include "libavutil/opt.h"
>> @@ -41,6 +41,62 @@
>>   #include "libavutil/avassert.h"
>>   #include "libswscale/swscale.h"
>>   
>> +static const char *const var_names[] = {
>> +    "in_w",   "iw",
>> +    "in_h",   "ih",
>> +    "out_w",  "ow",
>> +    "out_h",  "oh",
>> +    "a",
>> +    "sar",
>> +    "dar",
>> +    "hsub",
>> +    "vsub",
>> +    "ohsub",
>> +    "ovsub",
>> +    "n",
>> +    "t",
>> +    "pos",
>> +    "main_w",
>> +    "main_h",
>> +    "main_a",
>> +    "main_sar",
>> +    "main_dar", "mdar",
>> +    "main_hsub",
>> +    "main_vsub",
>> +    "main_n",
>> +    "main_t",
>> +    "main_pos",
>> +    NULL
>> +};
> Moving and changing code at the same time makes it hard to see th difference.
> Idealy all code moves should be seperate from changes to the code.
>
> also more generally, spliting this patch up would simpify review

One function has been moved from outside and then modified. All the 
modifications work together so at best I can split into two. Will do that.

Thanks,
Gyan



More information about the ffmpeg-devel mailing list