[FFmpeg-devel] [PATCH] avfilter/vf_crop: make it possible to use frame metadata when cropping
Paul B Mahol
onemda at gmail.com
Sun Jan 17 20:15:45 CET 2016
Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
doc/filters.texi | 6 ++++++
libavfilter/vf_crop.c | 54 +++++++++++++++++++++++++++++++++++++++------------
2 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index f4bda6a..aee4e66 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -4621,6 +4621,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.
+
+ at item metadata
+If set to 1 it will use frame metadata instead to obtain all parameters.
+To make use of this feature you need to start @ref{cropdetect} filter before
+this filter.
@end table
The @var{out_w}, @var{out_h}, @var{x}, @var{y} parameters are
@@ -4781,6 +4786,7 @@ If the specified expression is not valid, it is kept at its current
value.
@end table
+ at anchor{cropdetect}
@section cropdetect
Auto-detect the crop size.
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 01773fa..7890d6c 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
@@ -244,22 +245,50 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
AVFilterContext *ctx = link->dst;
CropContext *s = ctx->priv;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
- int i;
+ 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;
+ }
+ }
+ }
frame->width = s->w;
frame->height = s->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);
-
- 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;
@@ -344,6 +373,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
More information about the ffmpeg-devel
mailing list