Hi, updated version attached.
From 4a4d760c78f16e8ddeab65a0fc6532059bf13750 Mon Sep 17 00:00:00 2001 From: Paul B Mahol <one...@gmail.com> Date: Sun, 17 Jan 2016 20:14:55 +0100 Subject: [PATCH] avfilter/vf_crop: make it possible to use frame metadata when cropping
Signed-off-by: Paul B Mahol <one...@gmail.com> --- doc/filters.texi | 6 +++++ libavfilter/vf_crop.c | 64 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 7f2c419..87bf4dd 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4760,6 +4760,11 @@ This expression is evaluated per-frame. If set to 1 will force the output display aspect ratio to be the same of the input, by changing the output sample aspect ratio. It defaults to 0. + +@item metadata +If set to 1, the frame metadata as inserted by the cropdetect filter +will be used to determine all parameters. This requires that the +@ref{cropdetect} filter is inserted before this filter in the chain. @end table The @var{out_w}, @var{out_h}, @var{x}, @var{y} parameters are @@ -4920,6 +4925,7 @@ If the specified expression is not valid, it is kept at its current value. @end table +@anchor{cropdetect} @section cropdetect Auto-detect the crop size. diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 01773fa..8cea499 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -82,6 +82,7 @@ typedef struct CropContext { AVRational out_sar; ///< output sample aspect ratio int keep_aspect; ///< keep display aspect ratio when cropping + int metadata; ///< use frame metadata instead of expressions int max_step[4]; ///< max pixel step for each plane, expressed as a number of bytes int hsub, vsub; ///< chroma subsampling @@ -243,23 +244,55 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) { AVFilterContext *ctx = link->dst; CropContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); - int i; - - frame->width = s->w; - frame->height = s->h; + int i, metadata = 0; + + if (s->metadata) { + AVDictionaryEntry *ex, *ey, *ew, *eh; + + ew = av_dict_get(frame->metadata, "lavfi.cropdetect.w", NULL, AV_DICT_MATCH_CASE); + eh = av_dict_get(frame->metadata, "lavfi.cropdetect.h", NULL, AV_DICT_MATCH_CASE); + ex = av_dict_get(frame->metadata, "lavfi.cropdetect.x", NULL, AV_DICT_MATCH_CASE); + ey = av_dict_get(frame->metadata, "lavfi.cropdetect.y", NULL, AV_DICT_MATCH_CASE); + + if (ex && ey && ew && eh) { + char *xendptr = NULL, *yendptr = NULL, *wendptr = NULL, *hendptr = NULL; + int x, y, w, h; + + x = strtol(ex->value, &xendptr, 10); + y = strtol(ey->value, ¥dptr, 10); + w = strtol(ew->value, &wendptr, 10); + h = strtol(eh->value, &hendptr, 10); + if (x >= 0 && y >= 0 && w > 0 && h >0) { + metadata = 1; + s->x = x; + s->y = y; + s->w = w; + s->h = h; + } + } + } - s->var_values[VAR_N] = link->frame_count; - s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ? - NAN : frame->pts * av_q2d(link->time_base); - s->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ? - NAN : av_frame_get_pkt_pos(frame); - s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); - s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL); - s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); + if (s->w != frame->width || s->h != frame->height) { + frame->width = outlink->w = s->w; + frame->height = outlink->h = s->h; + avfilter_config_links(ctx); + } - normalize_double(&s->x, s->var_values[VAR_X]); - normalize_double(&s->y, s->var_values[VAR_Y]); + if (!metadata) { + s->var_values[VAR_N] = link->frame_count; + s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ? + NAN : frame->pts * av_q2d(link->time_base); + s->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ? + NAN : av_frame_get_pkt_pos(frame); + s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); + s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL); + s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); + + normalize_double(&s->x, s->var_values[VAR_X]); + normalize_double(&s->y, s->var_values[VAR_Y]); + } if (s->x < 0) s->x = 0; @@ -294,7 +327,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) frame->data[3] += s->x * s->max_step[3]; } - return ff_filter_frame(link->dst->outputs[0], frame); + return ff_filter_frame(outlink, frame); } static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, @@ -344,6 +377,7 @@ 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 }, { "keep_aspect", "keep aspect ratio", OFFSET(keep_aspect), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "metadata", "use frame metadata", OFFSET(metadata), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { NULL } }; -- 1.9.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel