[FFmpeg-devel] [PATCH 4/4] Make the crop filter accept parametric expressions.

Michael Niedermayer michaelni
Fri Sep 17 12:09:04 CEST 2010


On Wed, Sep 15, 2010 at 12:28:06AM +0200, Stefano Sabatini wrote:
[...]
> +static inline int normalize_double(int *n, double d)
> +{
> +    int ret = 0;
> +
> +    if (isnan(d)) {
> +        ret = AVERROR(EINVAL);
> +    } else if (d > INT_MAX || d < INT_MIN) {
> +        *n = d > INT_MAX ? INT_MAX : INT_MIN;
> +        ret = AVERROR(EINVAL);
> +    } else

> +        *n = d;

something that rounds to nearest should be used


> +
> +    return ret;
> +}
> +
>  static int config_input(AVFilterLink *link)
>  {
>      AVFilterContext *ctx = link->dst;
>      CropContext *crop = ctx->priv;
>      const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[link->format];
> +    int ret;
> +    const char *expr;
> +    double res;
> +
> +    crop->var_values[E]     = M_E;
> +    crop->var_values[PHI]   = M_PHI;
> +    crop->var_values[PI]    = M_PI;
> +    crop->var_values[IN_W]  = crop->var_values[IW] = ctx->inputs[0]->w;
> +    crop->var_values[IN_H]  = crop->var_values[IH] = ctx->inputs[0]->h;
> +    crop->var_values[X]     = NAN;
> +    crop->var_values[Y]     = NAN;
> +    crop->var_values[OUT_W] = crop->var_values[OW] = NAN;
> +    crop->var_values[OUT_H] = crop->var_values[OH] = NAN;
> +    crop->var_values[N]     = 0;

T/POS are random?


>  
>      av_image_fill_max_pixsteps(crop->max_step, NULL, pix_desc);
>      crop->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w;
>      crop->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
>  
> -    if (crop->w == 0)
> -        crop->w = link->w - crop->x;
> -    if (crop->h == 0)
> -        crop->h = link->h - crop->y;
> +    if ((ret = av_parse_and_eval_expr(&res, (expr = crop->ow_expr),
> +                                      var_names, crop->var_values,
> +                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
> +    crop->var_values[OUT_W] = crop->var_values[OW] = res;
> +    if ((ret = av_parse_and_eval_expr(&res, (expr = crop->oh_expr),
> +                                      var_names, crop->var_values,
> +                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
> +    crop->var_values[OUT_H] = crop->var_values[OH] = res;
> +    /* evaluate again ow as it may depend on oh */
> +    if ((ret = av_parse_and_eval_expr(&res, (expr = crop->ow_expr),
> +                                      var_names, crop->var_values,
> +                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
> +    crop->var_values[OUT_W] = crop->var_values[OW] = res;
> +    if (normalize_double(&crop->w, crop->var_values[OUT_W]) < 0 ||
> +        normalize_double(&crop->h, crop->var_values[OUT_H]) < 0) {
> +        av_log(ctx, AV_LOG_ERROR,
> +               "Too big value or invalid expression for out_w/ow or out_h/oh. "
> +               "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
> +               crop->ow_expr, crop->oh_expr);
> +        return AVERROR(EINVAL);
> +    }
> +    crop->w &= ~((1 << crop->hsub) - 1);
> +    crop->h &= ~((1 << crop->vsub) - 1);
> +
> +    if ((ret = av_parse_expr(&crop->x_pexpr, crop->x_expr, var_names,
> +                             NULL, NULL, NULL, NULL, 0, ctx)) < 0 ||
> +        (ret = av_parse_expr(&crop->y_pexpr, crop->y_expr, var_names,
> +                             NULL, NULL, NULL, NULL, 0, ctx)) < 0)
> +        return AVERROR(EINVAL);
>  
> +    crop->var_values[X] = av_eval_expr(crop->x_pexpr, crop->var_values, NULL);
> +    crop->var_values[Y] = av_eval_expr(crop->y_pexpr, crop->var_values, NULL);
> +    /* evaluate again x as it may depend on y */
> +    crop->var_values[X] = av_eval_expr(crop->x_pexpr, crop->var_values, NULL);
> +    if (normalize_double(&crop->x, crop->var_values[X]) < 0 ||
> +        normalize_double(&crop->y, crop->var_values[Y]) < 0) {
> +        av_log(ctx, AV_LOG_ERROR,
> +               "Too big value or invalid expression for x or y. "
> +               "Maybe the expression for x:'%s' or for y:'%s' is self-referencing.\n",
> +               crop->x_expr, crop->y_expr);
> +        return AVERROR(EINVAL);
> +    }

i dont think that will work they can depend on N/T/POS which should be NAN for W/H

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

If a bugfix only changes things apparently unrelated to the bug with no
further explanation, that is a good sign that the bugfix is wrong.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100917/5eda8c44/attachment.pgp>



More information about the ffmpeg-devel mailing list