Revision 484a3308 libavfilter/vf_pad.c

View differences:

libavfilter/vf_pad.c
25 25
 */
26 26

  
27 27
#include "avfilter.h"
28
#include "libavutil/avstring.h"
29
#include "libavutil/eval.h"
28 30
#include "libavutil/pixdesc.h"
29 31
#include "libavutil/colorspace.h"
30 32
#include "libavutil/avassert.h"
......
32 34
#include "libavutil/parseutils.h"
33 35
#include "drawutils.h"
34 36

  
37
static const char *var_names[] = {
38
    "PI",
39
    "PHI",
40
    "E",
41
    "in_w",   "iw",
42
    "in_h",   "ih",
43
    "out_w",  "ow",
44
    "out_h",  "oh",
45
    "x",
46
    "y",
47
    "a",
48
    "hsub",
49
    "vsub",
50
    NULL
51
};
52

  
53
enum var_name {
54
    VAR_PI,
55
    VAR_PHI,
56
    VAR_E,
57
    VAR_IN_W,   VAR_IW,
58
    VAR_IN_H,   VAR_IH,
59
    VAR_OUT_W,  VAR_OW,
60
    VAR_OUT_H,  VAR_OH,
61
    VAR_X,
62
    VAR_Y,
63
    VAR_A,
64
    VAR_HSUB,
65
    VAR_VSUB,
66
    VARS_NB
67
};
68

  
35 69
static int query_formats(AVFilterContext *ctx)
36 70
{
37 71
    static const enum PixelFormat pix_fmts[] = {
......
58 92
    int x, y;               ///< offsets of the input area with respect to the padded area
59 93
    int in_w, in_h;         ///< width and height for the padded input video, which has to be aligned to the chroma values in order to avoid chroma issues
60 94

  
95
    char w_expr[256];       ///< width  expression string
96
    char h_expr[256];       ///< height expression string
97
    char x_expr[256];       ///< width  expression string
98
    char y_expr[256];       ///< height expression string
99

  
61 100
    uint8_t color[4];       ///< color expressed either in YUVA or RGBA colorspace for the padding area
62 101
    uint8_t *line[4];
63 102
    int      line_step[4];
......
70 109
    PadContext *pad = ctx->priv;
71 110
    char color_string[128] = "black";
72 111

  
112
    av_strlcpy(pad->w_expr, "iw", sizeof(pad->w_expr));
113
    av_strlcpy(pad->h_expr, "ih", sizeof(pad->h_expr));
114
    av_strlcpy(pad->x_expr, "0" , sizeof(pad->w_expr));
115
    av_strlcpy(pad->y_expr, "0" , sizeof(pad->h_expr));
116

  
73 117
    if (args)
74
        sscanf(args, "%d:%d:%d:%d:%s", &pad->w, &pad->h, &pad->x, &pad->y, color_string);
118
        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255s",
119
               pad->w_expr, pad->h_expr, pad->x_expr, pad->y_expr, color_string);
75 120

  
76 121
    if (av_parse_color(pad->color, color_string, -1, ctx) < 0)
77 122
        return AVERROR(EINVAL);
78 123

  
79
    /* sanity check params */
80
    if (pad->w < 0 || pad->h < 0) {
81
        av_log(ctx, AV_LOG_ERROR, "Negative size values are not acceptable.\n");
82
        return AVERROR(EINVAL);
83
    }
84

  
85 124
    return 0;
86 125
}
87 126

  
......
102 141
    PadContext *pad = ctx->priv;
103 142
    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
104 143
    uint8_t rgba_color[4];
105
    int is_packed_rgba;
144
    int ret, is_packed_rgba;
145
    double var_values[VARS_NB], res;
146
    char *expr;
106 147

  
107 148
    pad->hsub = pix_desc->log2_chroma_w;
108 149
    pad->vsub = pix_desc->log2_chroma_h;
109 150

  
151
    var_values[VAR_PI]    = M_PI;
152
    var_values[VAR_PHI]   = M_PHI;
153
    var_values[VAR_E]     = M_E;
154
    var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;
155
    var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;
156
    var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
157
    var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
158
    var_values[VAR_A]     = (float) inlink->w / inlink->h;
159
    var_values[VAR_HSUB]  = 1<<pad->hsub;
160
    var_values[VAR_VSUB]  = 2<<pad->vsub;
161

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

  
179
    /* evaluate x and y */
180
    av_expr_parse_and_eval(&res, (expr = pad->x_expr),
181
                           var_names, var_values,
182
                           NULL, NULL, NULL, NULL, NULL, 0, ctx);
183
    pad->x = var_values[VAR_X] = res;
184
    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->y_expr),
185
                                      var_names, var_values,
186
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
187
        goto eval_fail;
188
    pad->y = var_values[VAR_Y] = res;
189
    /* evaluate x again, as it may depend on the evaluated y value */
190
    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->x_expr),
191
                                      var_names, var_values,
192
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
193
        goto eval_fail;
194
    pad->x = var_values[VAR_X] = res;
195

  
196
    /* sanity check params */
197
    if (pad->w < 0 || pad->h < 0 || pad->x < 0 || pad->y < 0) {
198
        av_log(ctx, AV_LOG_ERROR, "Negative values are not acceptable.\n");
199
        return AVERROR(EINVAL);
200
    }
201

  
110 202
    if (!pad->w)
111 203
        pad->w = inlink->w;
112 204
    if (!pad->h)
......
140 232
    }
141 233

  
142 234
    return 0;
235

  
236
eval_fail:
237
    av_log(NULL, AV_LOG_ERROR,
238
           "Error when evaluating the expression '%s'\n", expr);
239
    return ret;
240

  
143 241
}
144 242

  
145 243
static int config_output(AVFilterLink *outlink)

Also available in: Unified diff