vf_crop: switch to an AVOptions-based system.
This commit is contained in:
parent
51def31dbe
commit
fba0156af7
@ -623,7 +623,25 @@ testing purposes.
|
|||||||
|
|
||||||
@section crop
|
@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:
|
The parameters are expressions containing the following constants:
|
||||||
|
|
||||||
@ -683,34 +701,34 @@ for @var{y} may depend on @var{x}.
|
|||||||
Follow some examples:
|
Follow some examples:
|
||||||
@example
|
@example
|
||||||
# crop the central input area with size 100x100
|
# 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 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 the input video central square
|
||||||
crop=in_h
|
crop=out_w=in_h
|
||||||
|
|
||||||
# delimit the rectangle with the top-left corner placed at position
|
# delimit the rectangle with the top-left corner placed at position
|
||||||
# 100:100 and the right-bottom corner corresponding to the right-bottom
|
# 100:100 and the right-bottom corner corresponding to the right-bottom
|
||||||
# corner of the input image.
|
# 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
|
# crop 10 pixels from the left and right borders, and 20 pixels from
|
||||||
# the top and bottom borders
|
# 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
|
# 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 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
|
# 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)"
|
"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
|
# 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
|
# set x depending on the value of y
|
||||||
"crop=in_w/2:in_h/2:y:10+10*sin(n/10)"
|
"crop=in_w/2:in_h/2:y:10+10*sin(n/10)"
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "libavutil/libm.h"
|
#include "libavutil/libm.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
#include "libavutil/mathematics.h"
|
#include "libavutil/mathematics.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
|
|
||||||
static const char *const var_names[] = {
|
static const char *const var_names[] = {
|
||||||
"E",
|
"E",
|
||||||
@ -70,6 +71,7 @@ enum var_name {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
const AVClass *class;
|
||||||
int x; ///< x offset of the non-cropped area with respect to the input area
|
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 y; ///< y offset of the non-cropped area with respect to the input area
|
||||||
int w; ///< width of the cropped 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 max_step[4]; ///< max pixel step for each plane, expressed as a number of bytes
|
||||||
int hsub, vsub; ///< chroma subsampling
|
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 */
|
AVExpr *x_pexpr, *y_pexpr; /* parsed expressions for x and y */
|
||||||
double var_values[VAR_VARS_NB];
|
double var_values[VAR_VARS_NB];
|
||||||
} CropContext;
|
} CropContext;
|
||||||
@ -115,21 +117,6 @@ static int query_formats(AVFilterContext *ctx)
|
|||||||
return 0;
|
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)
|
static av_cold void uninit(AVFilterContext *ctx)
|
||||||
{
|
{
|
||||||
CropContext *crop = ctx->priv;
|
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);
|
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[] = {
|
static const AVFilterPad avfilter_vf_crop_inputs[] = {
|
||||||
{
|
{
|
||||||
.name = "default",
|
.name = "default",
|
||||||
@ -319,9 +325,9 @@ AVFilter avfilter_vf_crop = {
|
|||||||
.description = NULL_IF_CONFIG_SMALL("Crop the input video to width:height:x:y."),
|
.description = NULL_IF_CONFIG_SMALL("Crop the input video to width:height:x:y."),
|
||||||
|
|
||||||
.priv_size = sizeof(CropContext),
|
.priv_size = sizeof(CropContext),
|
||||||
|
.priv_class = &crop_class,
|
||||||
|
|
||||||
.query_formats = query_formats,
|
.query_formats = query_formats,
|
||||||
.init = init,
|
|
||||||
.uninit = uninit,
|
.uninit = uninit,
|
||||||
|
|
||||||
.inputs = avfilter_vf_crop_inputs,
|
.inputs = avfilter_vf_crop_inputs,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user