On Tue, Dec 08, 2015 at 12:58:15PM +0100, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol <one...@gmail.com> > --- > doc/filters.texi | 54 ++++++++++ > libavfilter/Makefile | 1 + > libavfilter/allfilters.c | 1 + > libavfilter/vf_swaprect.c | 267 > ++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 323 insertions(+) > create mode 100644 libavfilter/vf_swaprect.c > > diff --git a/doc/filters.texi b/doc/filters.texi > index 274532d..37c9c2b 100644 > --- a/doc/filters.texi > +++ b/doc/filters.texi > @@ -10897,6 +10897,60 @@ Interpolate) pixel art scaling algorithm. > > Useful for enlarging pixel art images without reducing sharpness. > > +@section swaprect > + > +Swap two rectangular objects in video. > + > +This filter accepts the following options: > + > +@table @option > +@item w > +Set object width. > + > +@item h > +Set object height. > + > +@item x1 > +Set 1st rect x coordinate. > + > +@item y1 > +Set 1st rect y coordinate. > + > +@item x2 > +Set 2nd rect x coordinate. > + > +@item y2 > +Set 2nd rect y coordinate. > + > +All expressions are evaluated once for each frame. > +@end table > + > +The all options are expressions containing the following constants: > + > +@table @option > +@item w > +@item h > +The input width and height. > + > +@item a > +same as @var{w} / @var{h} > + > +@item sar > +input sample aspect ratio > + > +@item dar > +input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar} > + > +@item n > +The number of the input frame, starting from 0. > + > +@item t > +The timestamp expressed in seconds. It's NAN if the input timestamp is > unknown. > + > +@item pos > +the position in the file of the input frame, NAN if unknown > +@end table > + > @section swapuv > Swap U & V plane. > > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 8884d1d..4d1376b 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -233,6 +233,7 @@ OBJS-$(CONFIG_SSIM_FILTER) += vf_ssim.o > dualinput.o framesync. > OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o > OBJS-$(CONFIG_SUBTITLES_FILTER) += vf_subtitles.o > OBJS-$(CONFIG_SUPER2XSAI_FILTER) += vf_super2xsai.o > +OBJS-$(CONFIG_SWAPRECT_FILTER) += vf_swaprect.o > OBJS-$(CONFIG_SWAPUV_FILTER) += vf_swapuv.o > OBJS-$(CONFIG_TBLEND_FILTER) += vf_blend.o dualinput.o > framesync.o > OBJS-$(CONFIG_TELECINE_FILTER) += vf_telecine.o > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c > index 0eeef53..94a951b 100644 > --- a/libavfilter/allfilters.c > +++ b/libavfilter/allfilters.c > @@ -254,6 +254,7 @@ void avfilter_register_all(void) > REGISTER_FILTER(STEREO3D, stereo3d, vf); > REGISTER_FILTER(SUBTITLES, subtitles, vf); > REGISTER_FILTER(SUPER2XSAI, super2xsai, vf); > + REGISTER_FILTER(SWAPRECT, swaprect, vf); > REGISTER_FILTER(SWAPUV, swapuv, vf); > REGISTER_FILTER(TBLEND, tblend, vf); > REGISTER_FILTER(TELECINE, telecine, vf); > diff --git a/libavfilter/vf_swaprect.c b/libavfilter/vf_swaprect.c > new file mode 100644 > index 0000000..a5e1fab > --- /dev/null > +++ b/libavfilter/vf_swaprect.c > @@ -0,0 +1,267 @@ > +/* > + * Copyright (c) 2015 Paul B. Mahol > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include "libavutil/avstring.h" > +#include "libavutil/eval.h" > +#include "libavutil/imgutils.h" > +#include "libavutil/opt.h" > +#include "libavutil/pixdesc.h" > + > +#include "avfilter.h" > +#include "formats.h" > +#include "internal.h" > +#include "video.h" > + > +typedef struct SwapRectContext { > + const AVClass *class; > + char *w, *h; > + char *x1, *y1; > + char *x2, *y2; > + > + int nb_planes; > + int pixsteps[4]; > + > + const AVPixFmtDescriptor *desc; > + uint8_t *temp; > +} SwapRectContext; > + > +#define OFFSET(x) offsetof(SwapRectContext, x) > +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM > +static const AVOption swaprect_options[] = { > + { "w", "set rect width", OFFSET(w), > AV_OPT_TYPE_STRING, {.str="w/2"}, 0, 0, .flags = FLAGS }, > + { "h", "set rect height", OFFSET(h), > AV_OPT_TYPE_STRING, {.str="h/2"}, 0, 0, .flags = FLAGS }, > + { "x1", "set 1st rect x top left coordinate", OFFSET(x1), > AV_OPT_TYPE_STRING, {.str="w/2"}, 0, 0, .flags = FLAGS }, > + { "y1", "set 1st rect y top left coordinate", OFFSET(y1), > AV_OPT_TYPE_STRING, {.str="h/2"}, 0, 0, .flags = FLAGS }, > + { "x2", "set 2nd rect x top left coordinate", OFFSET(x2), > AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, .flags = FLAGS }, > + { "y2", "set 2nd rect y top left coordinate", OFFSET(y2), > AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, .flags = FLAGS }, > + { NULL }, > +}; > + > +AVFILTER_DEFINE_CLASS(swaprect); > + > +static int query_formats(AVFilterContext *ctx) > +{ > + AVFilterFormats *pix_fmts = NULL; > + int fmt, ret; > + > + for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { > + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); > + if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || > + desc->flags & AV_PIX_FMT_FLAG_HWACCEL || > + desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && > + (ret = ff_add_format(&pix_fmts, fmt)) < 0) > + return ret; > + } > + > + return ff_set_common_formats(ctx, pix_fmts); > +} > + > +static const char *const var_names[] = { "w", "h", "a", "n", "t", > "pos", "sar", "dar", NULL }; > +enum { VAR_W, VAR_H, VAR_A, VAR_N, VAR_T, > VAR_POS, VAR_SAR, VAR_DAR, VAR_VARS_NB }; > + > +static int filter_frame(AVFilterLink *inlink, AVFrame *in) > +{ > + AVFilterContext *ctx = inlink->dst; > + AVFilterLink *outlink = ctx->outputs[0]; > + SwapRectContext *s = ctx->priv; > + double var_values[VAR_VARS_NB]; > + int x1[4], y1[4]; > + int x2[4], y2[4]; > + int aw[4], ah[4]; > + int lw[4], lh[4]; > + int pw[4], ph[4]; > + double dw, dh; > + double dx1, dy1; > + double dx2, dy2; > + int i, x, y, p; > + int w, h; > + int ret; > + > + var_values[VAR_W] = inlink->w; > + var_values[VAR_H] = inlink->h; > + var_values[VAR_A] = (float) inlink->w / inlink->h; > + var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? > av_q2d(inlink->sample_aspect_ratio) : 1; > + var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; > + var_values[VAR_N] = inlink->frame_count; > + var_values[VAR_T] = in->pts == AV_NOPTS_VALUE ? NAN : in->pts * > av_q2d(inlink->time_base); > + var_values[VAR_POS] = av_frame_get_pkt_pos(in) == -1 ? NAN : > av_frame_get_pkt_pos(in); > + > + ret = av_expr_parse_and_eval(&dw, s->w, > + var_names, &var_values[0], > + NULL, NULL, NULL, NULL, > + 0, 0, ctx); > + if (ret < 0) > + return ret; > + > + ret = av_expr_parse_and_eval(&dh, s->h, > + var_names, &var_values[0], > + NULL, NULL, NULL, NULL, > + 0, 0, ctx); > + if (ret < 0) > + return ret; > + > + ret = av_expr_parse_and_eval(&dx1, s->x1, > + var_names, &var_values[0], > + NULL, NULL, NULL, NULL, > + 0, 0, ctx); > + if (ret < 0) > + return ret; > + > + ret = av_expr_parse_and_eval(&dy1, s->y1, > + var_names, &var_values[0], > + NULL, NULL, NULL, NULL, > + 0, 0, ctx); > + if (ret < 0) > + return ret; > + > + ret = av_expr_parse_and_eval(&dx2, s->x2, > + var_names, &var_values[0], > + NULL, NULL, NULL, NULL, > + 0, 0, ctx); > + if (ret < 0) > + return ret; > + > + ret = av_expr_parse_and_eval(&dy2, s->y2, > + var_names, &var_values[0], > + NULL, NULL, NULL, NULL, > + 0, 0, ctx); > + if (ret < 0) > + return ret; > + > + w = dw; h = dh; x1[0] = dx1; y1[0] = dy1; x2[0] = dx2; y2[0] = dy2; > +
> + x1[0] = x1[0] % inlink->w; > + y1[0] = y1[0] % inlink->h; > + > + x2[0] = x2[0] % inlink->w; > + y2[0] = y2[0] % inlink->h; that will fail to keep the values inside the image when they are negative filter LGTM otherwise though [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Democracy is the form of government in which you can choose your dictator
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel