diff --git a/doc/filters.texi b/doc/filters.texi index 91ce6d3cdd..e5ea2459cb 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2133,7 +2133,7 @@ testing purposes. @section crop -Crop the input video. +Crop the input video to given dimensions. This filter accepts a list of @var{key}=@var{value} pairs as argument, separated by ':'. If the key of the first options is omitted, the @@ -2143,22 +2143,22 @@ arguments are interpreted according to the syntax A description of the accepted options follows: @table @option @item w, out_w -Set the crop area width. It defaults to @code{iw}. +Width of the output video. It defaults to @code{iw}. This expression is evaluated only once during the filter configuration. @item h, out_h -Set the crop area height. It defaults to @code{ih}. +Height of the output video. It defaults to @code{ih}. This expression is evaluated only once during the filter configuration. @item x -Set the expression for the x top-left coordinate of the cropped area. +Horizontal position, in the input video, of the left edge of the output video. It defaults to @code{(in_w-out_w)/2}. This expression is evaluated per-frame. @item y -Set the expression for the y top-left coordinate of the cropped area. +Vertical position, in the input video, of the top edge of the output video. It defaults to @code{(in_h-out_h)/2}. This expression is evaluated per-frame. @@ -2251,6 +2251,7 @@ crop=2/3*in_w:2/3*in_h @item Crop the input video central square: @example +crop=out_w=in_h crop=in_h @end example diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index a3037041d2..8f1322c523 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -659,6 +659,7 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque !strcmp(filter->filter->name, "aformat") || !strcmp(filter->filter->name, "blackframe") || !strcmp(filter->filter->name, "boxblur" ) || + !strcmp(filter->filter->name, "crop" ) || !strcmp(filter->filter->name, "format") || !strcmp(filter->filter->name, "noformat") || !strcmp(filter->filter->name, "resample") diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index f99d1a7ce9..35bb3e699e 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -91,30 +91,6 @@ typedef struct { double var_values[VAR_VARS_NB]; } CropContext; -#define OFFSET(x) offsetof(CropContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption crop_options[] = { - { "x", "set the x crop area expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "(in_w-out_w)/2"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set the y crop area expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "(in_h-out_h)/2"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "out_w", "set the width crop area expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "w", "set the width crop area expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "out_h", "set the height crop area expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "h", "set the height crop area expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "keep_aspect", "keep aspect ratio", OFFSET(keep_aspect), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - {NULL} -}; - -AVFILTER_DEFINE_CLASS(crop); - -static av_cold void uninit(AVFilterContext *ctx) -{ - CropContext *crop = ctx->priv; - - av_expr_free(crop->x_pexpr); crop->x_pexpr = NULL; - av_expr_free(crop->y_pexpr); crop->y_pexpr = NULL; -} - static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { @@ -148,6 +124,14 @@ static int query_formats(AVFilterContext *ctx) return 0; } +static av_cold void uninit(AVFilterContext *ctx) +{ + CropContext *crop = ctx->priv; + + av_expr_free(crop->x_pexpr); crop->x_pexpr = NULL; + av_expr_free(crop->y_pexpr); crop->y_pexpr = NULL; +} + static inline int normalize_double(int *n, double d) { int ret = 0; @@ -316,6 +300,22 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) return ff_filter_frame(link->dst->outputs[0], frame); } +#define OFFSET(x) offsetof(CropContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption crop_options[] = { + { "out_w", "set the width crop area expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "w", "set the width crop area expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "out_h", "set the height crop area expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "h", "set the height crop area expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "x", "set the x crop area expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "(in_w-out_w)/2"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "y", "set the y crop area expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "(in_h-out_h)/2"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "keep_aspect", "keep aspect ratio", OFFSET(keep_aspect), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, + {NULL} +}; + +AVFILTER_DEFINE_CLASS(crop); + static const AVFilterPad avfilter_vf_crop_inputs[] = { { .name = "default", @@ -336,13 +336,12 @@ static const AVFilterPad avfilter_vf_crop_outputs[] = { { NULL } }; -static const char *const shorthand[] = { "w", "h", "x", "y", "keep_aspect", NULL }; - AVFilter avfilter_vf_crop = { .name = "crop", .description = NULL_IF_CONFIG_SMALL("Crop the input video to width:height:x:y."), .priv_size = sizeof(CropContext), + .priv_class = &crop_class, .query_formats = query_formats, .uninit = uninit, @@ -350,5 +349,4 @@ AVFilter avfilter_vf_crop = { .inputs = avfilter_vf_crop_inputs, .outputs = avfilter_vf_crop_outputs, .priv_class = &crop_class, - .shorthand = shorthand, };