vf_crop: switch to an AVOptions-based system.
authorAnton Khirnov <anton@khirnov.net>
Mon, 25 Feb 2013 20:21:29 +0000 (21:21 +0100)
committerAnton Khirnov <anton@khirnov.net>
Tue, 9 Apr 2013 17:00:54 +0000 (19:00 +0200)
doc/filters.texi
libavfilter/vf_crop.c

index bdde8f5..c75f119 100644 (file)
@@ -623,7 +623,25 @@ testing purposes.
 
 @section crop
 
-Crop the input video to @var{out_w}:@var{out_h}:@var{x}:@var{y}.
+Crop the input video to given dimensions.
+
+This filter accepts the following options:
+
+@table @option
+
+@item out_w
+Width of the output video.
+
+@item out_h
+Height of the output video.
+
+@item x
+Horizontal position, in the input video, of the left edge of the output video.
+
+@item y
+Vertical position, in the input video, of the top edge of the output video.
+
+@end table
 
 The parameters are expressions containing the following constants:
 
@@ -683,34 +701,34 @@ for @var{y} may depend on @var{x}.
 Follow some examples:
 @example
 # crop the central input area with size 100x100
-crop=100:100
+crop=out_w=100:out_h=100
 
 # crop the central input area with size 2/3 of the input video
-"crop=2/3*in_w:2/3*in_h"
+"crop=out_w=2/3*in_w:out_h=2/3*in_h"
 
 # crop the input video central square
-crop=in_h
+crop=out_w=in_h
 
 # delimit the rectangle with the top-left corner placed at position
 # 100:100 and the right-bottom corner corresponding to the right-bottom
 # corner of the input image.
-crop=in_w-100:in_h-100:100:100
+crop=out_w=in_w-100:out_h=in_h-100:x=100:y=100
 
 # crop 10 pixels from the left and right borders, and 20 pixels from
 # the top and bottom borders
-"crop=in_w-2*10:in_h-2*20"
+"crop=out_w=in_w-2*10:out_h=in_h-2*20"
 
 # keep only the bottom right quarter of the input image
-"crop=in_w/2:in_h/2:in_w/2:in_h/2"
+"crop=out_w=in_w/2:out_h=in_h/2:x=in_w/2:y=in_h/2"
 
 # crop height for getting Greek harmony
-"crop=in_w:1/PHI*in_w"
+"crop=out_w=in_w:out_h=1/PHI*in_w"
 
 # trembling effect
 "crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(n/7)"
 
 # erratic camera effect depending on timestamp
-"crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
+"crop=out_w=in_w/2:out_h=in_h/2:x=(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):y=(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
 
 # set x depending on the value of y
 "crop=in_w/2:in_h/2:y:10+10*sin(n/10)"
index 2b571c4..ec545b3 100644 (file)
@@ -37,6 +37,7 @@
 #include "libavutil/libm.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 
 static const char *const var_names[] = {
     "E",
@@ -70,6 +71,7 @@ enum var_name {
 };
 
 typedef struct {
+    const AVClass *class;
     int  x;             ///< x offset of the non-cropped area with respect to the input area
     int  y;             ///< y offset of the non-cropped area with respect to the input area
     int  w;             ///< width of the cropped area
@@ -77,7 +79,7 @@ typedef struct {
 
     int max_step[4];    ///< max pixel step for each plane, expressed as a number of bytes
     int hsub, vsub;     ///< chroma subsampling
-    char x_expr[256], y_expr[256], ow_expr[256], oh_expr[256];
+    char *x_expr, *y_expr, *ow_expr, *oh_expr;
     AVExpr *x_pexpr, *y_pexpr;  /* parsed expressions for x and y */
     double var_values[VAR_VARS_NB];
 } CropContext;
@@ -115,21 +117,6 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    CropContext *crop = ctx->priv;
-
-    av_strlcpy(crop->ow_expr, "iw", sizeof(crop->ow_expr));
-    av_strlcpy(crop->oh_expr, "ih", sizeof(crop->oh_expr));
-    av_strlcpy(crop->x_expr, "(in_w-out_w)/2", sizeof(crop->x_expr));
-    av_strlcpy(crop->y_expr, "(in_h-out_h)/2", sizeof(crop->y_expr));
-
-    if (args)
-        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]", crop->ow_expr, crop->oh_expr, crop->x_expr, crop->y_expr);
-
-    return 0;
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
     CropContext *crop = ctx->priv;
@@ -294,6 +281,25 @@ 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_VIDEO_PARAM
+static const AVOption options[] = {
+    { "out_w", "Output video width",  OFFSET(ow_expr), AV_OPT_TYPE_STRING, { .str = "iw" },                 .flags = FLAGS },
+    { "out_h", "Output video height", OFFSET(oh_expr), AV_OPT_TYPE_STRING, { .str = "ih" },                 .flags = FLAGS },
+    { "x",     "Horizontal position in the input video of the left edge of the cropped output video",
+                                      OFFSET(x_expr),  AV_OPT_TYPE_STRING, { .str = "(in_w - out_w) / 2" }, .flags = FLAGS },
+    { "y",     "Vertical position in the input video of the top edge of the cropped output video",
+                                      OFFSET(y_expr),  AV_OPT_TYPE_STRING, { .str = "(in_h - out_h) / 2" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass crop_class = {
+    .class_name = "crop",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_crop_inputs[] = {
     {
         .name             = "default",
@@ -319,9 +325,9 @@ AVFilter avfilter_vf_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,
-    .init          = init,
     .uninit        = uninit,
 
     .inputs    = avfilter_vf_crop_inputs,