[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