Revision d496d33d libavfilter/vf_scale.c

View differences:

libavfilter/vf_scale.c
24 24
 */
25 25

  
26 26
#include "avfilter.h"
27
#include "libavutil/avstring.h"
28
#include "libavutil/eval.h"
27 29
#include "libavutil/pixdesc.h"
28 30
#include "libavutil/avassert.h"
29 31
#include "libswscale/swscale.h"
30 32

  
33
static const char *var_names[] = {
34
    "PI",
35
    "PHI",
36
    "E",
37
    "in_w",   "iw",
38
    "in_h",   "ih",
39
    "out_w",  "ow",
40
    "out_h",  "oh",
41
    "a",
42
    "hsub",
43
    "vsub",
44
    NULL
45
};
46

  
47
enum var_name {
48
    VAR_PI,
49
    VAR_PHI,
50
    VAR_E,
51
    VAR_IN_W,   VAR_IW,
52
    VAR_IN_H,   VAR_IH,
53
    VAR_OUT_W,  VAR_OW,
54
    VAR_OUT_H,  VAR_OH,
55
    VAR_A,
56
    VAR_HSUB,
57
    VAR_VSUB,
58
    VARS_NB
59
};
60

  
31 61
typedef struct {
32 62
    struct SwsContext *sws;     ///< software scaler context
33 63
    struct SwsContext *isws[2]; ///< software scaler context for interlaced material
......
44 74
    int slice_y;                ///< top of current output slice
45 75
    int input_is_pal;           ///< set to 1 if the input format is paletted
46 76
    int interlaced;
77

  
78
    char w_expr[256];             ///< width  expression string
79
    char h_expr[256];             ///< height expression string
47 80
} ScaleContext;
48 81

  
49 82
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
......
51 84
    ScaleContext *scale = ctx->priv;
52 85
    const char *p;
53 86

  
87
    av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
88
    av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
89

  
54 90
    scale->flags = SWS_BILINEAR;
55 91
    if (args) {
56
        sscanf(args, "%d:%d", &scale->w, &scale->h);
92
        sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
57 93
        p = strstr(args,"flags=");
58 94
        if (p) scale->flags = strtoul(p+6, NULL, 0);
59 95
        if(strstr(args,"interl=1")){
......
62 98
            scale->interlaced=-1;
63 99
    }
64 100

  
65
    /* sanity check params */
66
    if (scale->w <  -1 || scale->h <  -1) {
67
        av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
68
        return AVERROR(EINVAL);
69
    }
70
    if (scale->w == -1 && scale->h == -1)
71
        scale->w = scale->h = 0;
72

  
73 101
    return 0;
74 102
}
75 103

  
......
118 146
    AVFilterLink *inlink = outlink->src->inputs[0];
119 147
    ScaleContext *scale = ctx->priv;
120 148
    int64_t w, h;
149
    double var_values[VARS_NB], res;
150
    char *expr;
151
    int ret;
152

  
153
    var_values[VAR_PI]    = M_PI;
154
    var_values[VAR_PHI]   = M_PHI;
155
    var_values[VAR_E]     = M_E;
156
    var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;
157
    var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;
158
    var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
159
    var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
160
    var_values[VAR_A]     = (float) inlink->w / inlink->h;
161
    var_values[VAR_HSUB]  = 2<<av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
162
    var_values[VAR_VSUB]  = 2<<av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
163

  
164
    /* evaluate width and height */
165
    av_expr_parse_and_eval(&res, (expr = scale->w_expr),
166
                           var_names, var_values,
167
                           NULL, NULL, NULL, NULL, NULL, 0, ctx);
168
    scale->w = var_values[VAR_OW] = res;
169
    if ((ret = av_expr_parse_and_eval(&res, (expr = scale->h_expr),
170
                                      var_names, var_values,
171
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
172
        goto fail;
173
    scale->h = var_values[VAR_OH] = res;
174
    /* evaluate again the width, as it may depend on the output height */
175
    if ((ret = av_expr_parse_and_eval(&res, (expr = scale->w_expr),
176
                                      var_names, var_values,
177
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
178
        goto fail;
179
    scale->w = res;
180

  
181
    w = scale->w;
182
    h = scale->h;
183

  
184
    /* sanity check params */
185
    if (w <  -1 || h <  -1) {
186
        av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
187
        return AVERROR(EINVAL);
188
    }
189
    if (w == -1 && h == -1)
190
        scale->w = scale->h = 0;
121 191

  
122 192
    if (!(w = scale->w))
123 193
        w = inlink->w;
......
159 229
        return AVERROR(EINVAL);
160 230

  
161 231
    return 0;
232

  
233
fail:
234
    av_log(NULL, AV_LOG_ERROR,
235
           "Error when evaluating the expression '%s'\n", expr);
236
    return ret;
162 237
}
163 238

  
164 239
static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)

Also available in: Unified diff