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 <ffm...@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
+};