[FFmpeg-devel] [PATCH 4/4] Make the crop filter accept parametric expressions.
Stefano Sabatini
stefano.sabatini-lala
Fri Sep 24 15:52:58 CEST 2010
On date Wednesday 2010-09-22 22:59:50 +0200, Michael Niedermayer encoded:
> On Tue, Sep 21, 2010 at 10:36:52AM +0200, Stefano Sabatini wrote:
> > On date Friday 2010-09-17 12:09:04 +0200, Michael Niedermayer encoded:
> > > 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
> >
> > round()
> >
> > > > +
> > > > + 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?
> >
> > Fixed, set now to NAN.
> >
> > > > 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
> >
> > Changed the logic, now x/y is evaluated only in start_frame(), a
> > default value is set in case the first evaluated x/y is not valid.
> > This way the filter won't fail if the initial value of x/y is not
> > invalid (and the last valid value is used).
> >
> > Regards.
> > --
> > FFmpeg = Fascinating and Fostering MultiPurpose Extroverse Gnome
>
> > doc/ffmpeg-doc.texi | 8 +-
> > doc/filters.texi | 104 ++++++++++++++++++++++-----
> > ffmpeg.c | 4 -
> > libavfilter/vf_crop.c | 176 +++++++++++++++++++++++++++++++++++++++++-----
> > tests/lavfi-regression.sh | 10 +-
> > 5 files changed, 254 insertions(+), 48 deletions(-)
> > 39c3adc9137408cd71d23329d7c7da16b8abada3 0001-Make-the-crop-filter-accept-parametric-expressions.patch
> > From 9330a5223bfeeadd1ffbb1c8e6d39c6d95906812 Mon Sep 17 00:00:00 2001
> > From: Stefano Sabatini <stefano.sabatini-lala at poste.it>
> > Date: Thu, 9 Sep 2010 01:05:04 +0200
> > Subject: [PATCH] Make the crop filter accept parametric expressions.
> >
> > Also change the syntax of the crop filter, from:
> > x:y:w:h
> > to
> > w:h:x:y
> >
> > which looks more useful.
> > ---
> > doc/ffmpeg-doc.texi | 8 +-
> > doc/filters.texi | 104 ++++++++++++++++++++++-----
> > ffmpeg.c | 4 +-
> > libavfilter/vf_crop.c | 176 ++++++++++++++++++++++++++++++++++++++++-----
> > tests/lavfi-regression.sh | 10 ++--
> > 5 files changed, 254 insertions(+), 48 deletions(-)
> >
> > diff --git a/doc/ffmpeg-doc.texi b/doc/ffmpeg-doc.texi
> > index d9c5c14..e43e87e 100644
> > --- a/doc/ffmpeg-doc.texi
> > +++ b/doc/ffmpeg-doc.texi
> > @@ -226,13 +226,13 @@ The following abbreviations are recognized:
> >
> > @item -aspect @var{aspect}
> > Set aspect ratio (4:3, 16:9 or 1.3333, 1.7777).
> > - at item -croptop @var{size} (deprecated - use -vf crop=x:y:width:height instead)
> > + at item -croptop @var{size} (deprecated - use the crop filter instead)
> > Set top crop band size (in pixels).
> > - at item -cropbottom @var{size} (deprecated - use -vf crop=x:y:width:height instead)
> > + at item -cropbottom @var{size} (deprecated - use the crop filter instead)
> > Set bottom crop band size (in pixels).
> > - at item -cropleft @var{size} (deprecated - use -vf crop=x:y:width:height instead)
> > + at item -cropleft @var{size} (deprecated - use the crop filter instead)
> > Set left crop band size (in pixels).
> > - at item -cropright @var{size} (deprecated - use -vf crop=x:y:width:height instead)
> > + at item -cropright @var{size} (deprecated - use the crop filter instead)
> > Set right crop band size (in pixels).
> > @item -padtop @var{size}
> > @item -padbottom @var{size}
> > diff --git a/doc/filters.texi b/doc/filters.texi
> > index 262116c..209fa2a 100644
> > --- a/doc/filters.texi
> > +++ b/doc/filters.texi
> > @@ -26,34 +26,102 @@ Below is a description of the currently available video filters.
> >
> > @section crop
> >
> > -Crop the input video to @var{x}:@var{y}:@var{width}:@var{height}.
> > +Crop the input video to @var{out_w}:@var{out_h}:@var{x}:@var{y}.
> >
> > - at example
> > -./ffmpeg -i in.avi -vf "crop=0:0:0:240" out.avi
> > - at end example
> > +The parameters are expressions containing the following constants:
> >
> > - at var{x} and @var{y} specify the position of the top-left corner of the
> > -output (non-cropped) area.
> > + at table @option
> > + at item E, PI, PHI
> > +the corresponding mathematical approximated values for e
> > +(euler number), pi (greek PI), PHI (golden ratio)
> >
> > -The default value of @var{x} and @var{y} is 0.
> > + at item x, y
> > +the computed values for @var{x} and @var{y}. They are evaluated for
> > +each new frame.
> > +
> > + at item in_w, in_h
> > +the input width and heigth
> > +
> > + at item iw, ih
> > +same as @var{in_w} and @var{in_h}
> > +
> > + at item out_w, out_h
> > +the output (cropped) width and heigth
> > +
> > + at item ow, oh
> > +same as @var{out_w} and @var{out_h}
> > +
> > + at item n
> > +the number of input frame, starting from 0
> > +
> > + at item pos
> > +the position in the file of the input frame, NAN if unknown
> > +
>
> > + at item t
> > +timestamp expressed in seconds, NAN if the input timestamp is invalid
>
> is unknown
>
>
> > +
> > + at end table
> >
> > -The @var{width} and @var{height} parameters specify the width and height
> > -of the output (non-cropped) area.
> > +The @var{out_w} and @var{out_h} parameters specify the expressions for
> > +the width and height of the output (cropped) video. They are
> > +evaluated just at the configuration of the filter.
> >
> > -A value of 0 is interpreted as the maximum possible size contained in
> > -the area delimited by the top-left corner at position x:y.
> > +The default value of @var{out_w} is "in_w", and the default value of
> > + at var{out_h} is "in_h".
> >
>
> > -For example the parameters:
> > +The expression for @var{out_w} may depend on the value of
> > + at var{out_h}, and the expression for @var{out_h} may depend on
> > + at var{out_h}, but they cannot depend on @var{y} and @var{y}, as
>
> out_h may depend on out_h ?
>
>
> > + at var{x} and @var{y} are evaluated are evaluated after @var{out_w} and
> > + at var{out_h}.
>
> are evaluated are evaluated
>
> please review your own patch before submitting
> thank you
Sorry for that, it should be fixed now.
--
FFmpeg = Fancy Fascinating MultiPurpose Evangelical Gymnast
More information about the ffmpeg-devel
mailing list