FFmpeg
scale.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 Bobby Bingham
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdint.h>
22 #include "scale.h"
23 #include "libavutil/eval.h"
24 #include "libavutil/mathematics.h"
25 #include "libavutil/pixdesc.h"
26 
27 static const char *const var_names[] = {
28  "PI",
29  "PHI",
30  "E",
31  "in_w", "iw",
32  "in_h", "ih",
33  "out_w", "ow",
34  "out_h", "oh",
35  "a",
36  "sar",
37  "dar",
38  "hsub",
39  "vsub",
40  "ohsub",
41  "ovsub",
42  NULL
43 };
44 
45 enum var_name {
61 };
62 
63 /**
64  * This must be kept in sync with var_names so that it is always a
65  * complete list of var_names with the scale2ref specific names
66  * appended. scale2ref values must appear in the order they appear
67  * in the var_name_scale2ref enum but also be below all of the
68  * non-scale2ref specific values.
69  */
70 static const char *const var_names_scale2ref[] = {
71  "PI",
72  "PHI",
73  "E",
74  "in_w", "iw",
75  "in_h", "ih",
76  "out_w", "ow",
77  "out_h", "oh",
78  "a",
79  "sar",
80  "dar",
81  "hsub",
82  "vsub",
83  "ohsub",
84  "ovsub",
85  "main_w",
86  "main_h",
87  "main_a",
88  "main_sar",
89  "main_dar", "mdar",
90  "main_hsub",
91  "main_vsub",
92  NULL
93 };
94 
104 };
105 
106 int ff_scale_eval_dimensions(void *log_ctx,
107  const char *w_expr, const char *h_expr,
108  AVFilterLink *inlink, AVFilterLink *outlink,
109  int *ret_w, int *ret_h)
110 {
112  const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);
113  const char *expr;
114  int w, h;
115  int factor_w, factor_h;
116  int eval_w, eval_h;
117  int ret;
118  const char scale2ref = outlink->src->nb_inputs == 2 && outlink->src->inputs[1] == inlink;
119  double var_values[VARS_NB + VARS_S2R_NB], res;
120  const AVPixFmtDescriptor *main_desc;
121  const AVFilterLink *main_link;
122  const char *const *names = scale2ref ? var_names_scale2ref : var_names;
123 
124  if (scale2ref) {
125  main_link = outlink->src->inputs[0];
126  main_desc = av_pix_fmt_desc_get(main_link->format);
127  }
128 
129  var_values[VAR_PI] = M_PI;
130  var_values[VAR_PHI] = M_PHI;
131  var_values[VAR_E] = M_E;
132  var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
133  var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
134  var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
135  var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
136  var_values[VAR_A] = (double) inlink->w / inlink->h;
137  var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
138  (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
139  var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR];
140  var_values[VAR_HSUB] = 1 << desc->log2_chroma_w;
141  var_values[VAR_VSUB] = 1 << desc->log2_chroma_h;
142  var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;
143  var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;
144 
145  if (scale2ref) {
146  var_values[VARS_NB + VAR_S2R_MAIN_W] = main_link->w;
147  var_values[VARS_NB + VAR_S2R_MAIN_H] = main_link->h;
148  var_values[VARS_NB + VAR_S2R_MAIN_A] = (double) main_link->w / main_link->h;
149  var_values[VARS_NB + VAR_S2R_MAIN_SAR] = main_link->sample_aspect_ratio.num ?
150  (double) main_link->sample_aspect_ratio.num / main_link->sample_aspect_ratio.den : 1;
151  var_values[VARS_NB + VAR_S2R_MAIN_DAR] = var_values[VARS_NB + VAR_S2R_MDAR] =
152  var_values[VARS_NB + VAR_S2R_MAIN_A] * var_values[VARS_NB + VAR_S2R_MAIN_SAR];
153  var_values[VARS_NB + VAR_S2R_MAIN_HSUB] = 1 << main_desc->log2_chroma_w;
154  var_values[VARS_NB + VAR_S2R_MAIN_VSUB] = 1 << main_desc->log2_chroma_h;
155  }
156 
157  /* evaluate width and height */
158  av_expr_parse_and_eval(&res, (expr = w_expr),
159  names, var_values,
160  NULL, NULL, NULL, NULL, NULL, 0, log_ctx);
161  eval_w = var_values[VAR_OUT_W] = var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res;
162 
163  if ((ret = av_expr_parse_and_eval(&res, (expr = h_expr),
164  names, var_values,
165  NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)
166  goto fail;
167  eval_h = var_values[VAR_OUT_H] = var_values[VAR_OH] = (int) res == 0 ? inlink->h : (int) res;
168  /* evaluate again the width, as it may depend on the output height */
169  if ((ret = av_expr_parse_and_eval(&res, (expr = w_expr),
170  names, var_values,
171  NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)
172  goto fail;
173  eval_w = (int) res == 0 ? inlink->w : (int) res;
174 
175  w = eval_w;
176  h = eval_h;
177 
178  /* Check if it is requested that the result has to be divisible by a some
179  * factor (w or h = -n with n being the factor). */
180  factor_w = 1;
181  factor_h = 1;
182  if (w < -1) {
183  factor_w = -w;
184  }
185  if (h < -1) {
186  factor_h = -h;
187  }
188 
189  if (w < 0 && h < 0) {
190  w = inlink->w;
191  h = inlink->h;
192  }
193 
194  /* Make sure that the result is divisible by the factor we determined
195  * earlier. If no factor was set, it is nothing will happen as the default
196  * factor is 1 */
197  if (w < 0)
198  w = av_rescale(h, inlink->w, inlink->h * factor_w) * factor_w;
199  if (h < 0)
200  h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h;
201 
202  *ret_w = w;
203  *ret_h = h;
204 
205  return 0;
206 
207 fail:
208  av_log(log_ctx, AV_LOG_ERROR,
209  "Error when evaluating the expression '%s'.\n"
210  "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
211  expr, w_expr, h_expr);
212  return ret;
213 }
VAR_IN_W
@ VAR_IN_W
Definition: scale.c:49
VARS_NB
@ VARS_NB
Definition: scale.c:60
M_PHI
#define M_PHI
Definition: mathematics.h:49
var_names_scale2ref
static const char *const var_names_scale2ref[]
This must be kept in sync with var_names so that it is always a complete list of var_names with the s...
Definition: scale.c:70
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
VAR_OHSUB
@ VAR_OHSUB
Definition: scale.c:58
VAR_E
@ VAR_E
Definition: scale.c:48
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
VAR_HSUB
@ VAR_HSUB
Definition: scale.c:56
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
VAR_VSUB
@ VAR_VSUB
Definition: scale.c:57
mathematics.h
VAR_IW
@ VAR_IW
Definition: scale.c:49
VAR_IN_H
@ VAR_IN_H
Definition: scale.c:50
VAR_DAR
@ VAR_DAR
Definition: scale.c:55
VAR_S2R_MAIN_HSUB
@ VAR_S2R_MAIN_HSUB
Definition: scale.c:101
VAR_S2R_MAIN_VSUB
@ VAR_S2R_MAIN_VSUB
Definition: scale.c:102
fail
#define fail()
Definition: checkasm.h:120
AVRational::num
int num
Numerator.
Definition: rational.h:59
VAR_S2R_MAIN_DAR
@ VAR_S2R_MAIN_DAR
Definition: scale.c:100
VAR_S2R_MAIN_SAR
@ VAR_S2R_MAIN_SAR
Definition: scale.c:99
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
VAR_OVSUB
@ VAR_OVSUB
Definition: scale.c:59
M_E
#define M_E
Definition: mathematics.h:37
VAR_S2R_MAIN_H
@ VAR_S2R_MAIN_H
Definition: scale.c:97
VAR_PHI
@ VAR_PHI
Definition: scale.c:47
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
NAN
#define NAN
Definition: mathematics.h:64
VAR_OW
@ VAR_OW
Definition: scale.c:51
scale.h
NULL
#define NULL
Definition: coverity.c:32
VAR_IH
@ VAR_IH
Definition: scale.c:50
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
VAR_PI
@ VAR_PI
Definition: scale.c:46
VAR_S2R_MAIN_A
@ VAR_S2R_MAIN_A
Definition: scale.c:98
VAR_OUT_H
@ VAR_OUT_H
Definition: scale.c:52
eval.h
desc
const char * desc
Definition: nvenc.c:68
AVFilterContext::nb_inputs
unsigned nb_inputs
number of input pads
Definition: avfilter.h:347
av_expr_parse_and_eval
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition: eval.c:744
var_name
var_name
Definition: aeval.c:46
M_PI
#define M_PI
Definition: mathematics.h:52
ff_scale_eval_dimensions
int ff_scale_eval_dimensions(void *log_ctx, const char *w_expr, const char *h_expr, AVFilterLink *inlink, AVFilterLink *outlink, int *ret_w, int *ret_h)
Definition: scale.c:106
VAR_A
@ VAR_A
Definition: scale.c:53
var_name_scale2ref
var_name_scale2ref
Definition: scale.c:95
VAR_S2R_MDAR
@ VAR_S2R_MDAR
Definition: scale.c:100
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
ret
ret
Definition: filter_design.txt:187
VARS_S2R_NB
@ VARS_S2R_NB
Definition: scale.c:103
AVRational::den
int den
Denominator.
Definition: rational.h:60
var_names
static const char *const var_names[]
Definition: scale.c:27
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
VAR_S2R_MAIN_W
@ VAR_S2R_MAIN_W
Definition: scale.c:96
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
h
h
Definition: vp9dsp_template.c:2038
VAR_OH
@ VAR_OH
Definition: scale.c:52
int
int
Definition: ffmpeg_filter.c:191
VAR_SAR
@ VAR_SAR
Definition: scale.c:54
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
VAR_OUT_W
@ VAR_OUT_W
Definition: scale.c:51