[FFmpeg-devel] [PATCH] lavfi: port phase filter from libmpcodecs
Stefano Sabatini
stefasab at gmail.com
Mon Sep 2 20:04:42 CEST 2013
On date Monday 2013-09-02 14:06:13 +0000, Paul B Mahol encoded:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
> Changelog | 1 +
> LICENSE | 1 +
> configure | 1 +
> doc/filters.texi | 61 +++++++++
> libavfilter/Makefile | 1 +
> libavfilter/allfilters.c | 1 +
> libavfilter/version.h | 4 +-
> libavfilter/vf_phase.c | 313 +++++++++++++++++++++++++++++++++++++++++++++++
> 8 files changed, 381 insertions(+), 2 deletions(-)
> create mode 100644 libavfilter/vf_phase.c
>
> diff --git a/Changelog b/Changelog
> index 1ec6e9b..6706d07 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -16,6 +16,7 @@ version <next>
> - incomplete Voxware MetaSound decoder
> - read EXIF metadata from JPEG
> - DVB teletext decoder
> +- phase filter ported from libmpcodecs
>
>
> version 2.0:
> diff --git a/LICENSE b/LICENSE
> index 575824e..f765ce8 100644
> --- a/LICENSE
> +++ b/LICENSE
> @@ -40,6 +40,7 @@ Specifically, the GPL parts of FFmpeg are
> - vf_noise.c
> - vf_owdenoise.c
> - vf_perspective.c
> + - vf_phase.c
> - vf_pp.c
> - vf_sab.c
> - vf_smartblur.c
> diff --git a/configure b/configure
> index 590d67f..62f258a 100755
> --- a/configure
> +++ b/configure
> @@ -2220,6 +2220,7 @@ resample_filter_deps="avresample"
> ocv_filter_deps="libopencv"
> owdenoise_filter_deps="gpl"
> pan_filter_deps="swresample"
> +phase_filter_deps="gpl"
> pp_filter_deps="gpl postproc"
> removelogo_filter_deps="avcodec avformat swscale"
> sab_filter_deps="gpl swscale"
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 5d9a2df..11ebfd5 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -5854,6 +5854,67 @@ It accepts the following values:
> Default value is @samp{linear}.
> @end table
>
> + at section phase
> +
> +Delay interlaced video by one field time so that the field order changes.
> +
> +The intended use is to fix PAL movies that have been captured with the
> +opposite field order to the film-to-video transfer.
> +
> +A description of the accepted parameters follows.
> +
> + at table @option
> + at item mode
> +Set phase mode.
> +
> +It accepts the following values:
> + at table @samp
> + at item t
> +Capture field order top-first, transfer bottom-first.
> +Filter will delay the bottom field.
> +
> + at item b
> +Capture field order bottom-first, transfer top-first.
> +Filter will delay the top field.
> +
> + at item p
> +Capture and transfer with the same field order. This mode only exists
> +for the documentation of the other options to refer to, but if you
> +actually select it, the filter will faithfully do nothing.
> +
> + at item a
> +Capture field order determined automatically by field flags, transfer
> +opposite.
> +Filter selects among @samp{t} and @samp{b} modes on a frame by frame
> +basis using field flags. If no field information is available,
> +then this works just like @samp{u}.
> +
> + at item u
> +Capture unknown or varying, transfer opposite.
> +Filter selects among @samp{t} and @samp{b} on a frame by frame basis by
> +analyzing the images and selecting the alternative that produces best
> +match between the fields.
> +
> + at item T
> +Capture top-first, transfer unknown or varying.
> +Filter selects among @samp{t} and @samp{p} using image analysis.
> +
> + at item B
> +Capture bottom-first, transfer unknown or varying.
> +Filter selects among @samp{b} and @samp{p} using image analysis.
> +
> + at item A
> +Capture determined by field flags, transfer unknown or varying.
> +Filter selects among @samp{t} @samp{b} and @samp{p} using field flags and
@samp{t}, @samp{b}, and ..
> +image analysis. If no field information is available, then this works just
> +like @samp{U} This is the default mode.
missing dot
> +
> + at item U
> +Both capture and transfer unknown or varying.
> +Filter selects among @samp{t}, @samp{b} and @samp{p} using image analysis only.
> + at end table
> + at end table
> +
> @section pixdesctest
>
> Pixel format descriptor test filter, mainly useful for internal
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 3751d54..35f03c7 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -168,6 +168,7 @@ OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o
> OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o
> OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o
> OBJS-$(CONFIG_PERSPECTIVE_FILTER) += vf_perspective.o
> +OBJS-$(CONFIG_PHASE_FILTER) += vf_phase.o
> OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o
> OBJS-$(CONFIG_PP_FILTER) += vf_pp.o
> OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o dualinput.o
> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> index bcebcfc..b1792bf 100644
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -163,6 +163,7 @@ void avfilter_register_all(void)
> REGISTER_FILTER(PAD, pad, vf);
> REGISTER_FILTER(PERMS, perms, vf);
> REGISTER_FILTER(PERSPECTIVE, perspective, vf);
> + REGISTER_FILTER(PHASE, phase, vf);
> REGISTER_FILTER(PIXDESCTEST, pixdesctest, vf);
> REGISTER_FILTER(PP, pp, vf);
> REGISTER_FILTER(PSNR, psnr, vf);
> diff --git a/libavfilter/version.h b/libavfilter/version.h
> index 20ff257..cdae706 100644
> --- a/libavfilter/version.h
> +++ b/libavfilter/version.h
> @@ -30,8 +30,8 @@
> #include "libavutil/avutil.h"
>
> #define LIBAVFILTER_VERSION_MAJOR 3
> -#define LIBAVFILTER_VERSION_MINOR 82
> -#define LIBAVFILTER_VERSION_MICRO 102
> +#define LIBAVFILTER_VERSION_MINOR 83
> +#define LIBAVFILTER_VERSION_MICRO 100
>
> #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
> LIBAVFILTER_VERSION_MINOR, \
> diff --git a/libavfilter/vf_phase.c b/libavfilter/vf_phase.c
> new file mode 100644
> index 0000000..66a387d
> --- /dev/null
> +++ b/libavfilter/vf_phase.c
> @@ -0,0 +1,313 @@
> +/*
> + * Copyright (c) 2004 Ville Saari
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU 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/avassert.h"
> +#include "libavutil/imgutils.h"
> +#include "libavutil/pixdesc.h"
> +#include "libavutil/opt.h"
> +#include "avfilter.h"
> +#include "formats.h"
> +#include "internal.h"
> +#include "video.h"
> +
> +enum PhaseMode {
> + PROGRESSIVE,
> + TOP_FIRST,
> + BOTTOM_FIRST,
> + TOP_FIRST_ANALYZE,
> + BOTTOM_FIRST_ANALYZE,
> + ANALYZE,
> + FULL_ANALYZE,
> + AUTO,
> + AUTO_ANALYZE
> +};
> +
> +typedef struct PhaseContext {
> + const AVClass *class;
> + enum PhaseMode mode;
> + AVFrame *frame;
> + int nb_planes;
> + int planeheight[4];
> + int stride[4];
nit++: linesize for internal consistency
> +} PhaseContext;
> +
> +#define OFFSET(x) offsetof(PhaseContext, x)
> +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
> +
> +static const AVOption phase_options[] = {
> + { "mode", "set phase mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=AUTO_ANALYZE}, PROGRESSIVE, AUTO_ANALYZE, FLAGS, "mode" },
> + { "p", "progressive", 0, AV_OPT_TYPE_CONST, {.i64=PROGRESSIVE}, 0, 0, FLAGS, "mode" },
> + { "t", "top first", 0, AV_OPT_TYPE_CONST, {.i64=TOP_FIRST}, 0, 0, FLAGS, "mode" },
> + { "b", "bottom first", 0, AV_OPT_TYPE_CONST, {.i64=BOTTOM_FIRST}, 0, 0, FLAGS, "mode" },
> + { "T", "top first analyze", 0, AV_OPT_TYPE_CONST, {.i64=TOP_FIRST_ANALYZE}, 0, 0, FLAGS, "mode" },
> + { "B", "bottom first analyze", 0, AV_OPT_TYPE_CONST, {.i64=BOTTOM_FIRST_ANALYZE}, 0, 0, FLAGS, "mode" },
> + { "u", "analyze", 0, AV_OPT_TYPE_CONST, {.i64=ANALYZE}, 0, 0, FLAGS, "mode" },
> + { "U", "full analyze", 0, AV_OPT_TYPE_CONST, {.i64=FULL_ANALYZE}, 0, 0, FLAGS, "mode" },
> + { "a", "auto", 0, AV_OPT_TYPE_CONST, {.i64=AUTO}, 0, 0, FLAGS, "mode" },
> + { "A", "auto analyze", 0, AV_OPT_TYPE_CONST, {.i64=AUTO_ANALYZE}, 0, 0, FLAGS, "mode" },
> + { NULL }
> +};
> +
> +AVFILTER_DEFINE_CLASS(phase);
> +
> +static int query_formats(AVFilterContext *ctx)
> +{
> + static const enum AVPixelFormat pix_fmts[] = {
> + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P,
> + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P,AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P,
> + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
> + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
> + };
> +
> + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
> + return 0;
> +}
> +
> +static int config_input(AVFilterLink *inlink)
> +{
> + PhaseContext *s = inlink->dst->priv;
> + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
> + int ret;
> +
> + if ((ret = av_image_fill_linesizes(s->stride, inlink->format, inlink->w)) < 0)
> + return ret;
> +
> + s->planeheight[1] = s->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
> + s->planeheight[0] = s->planeheight[3] = inlink->h;
> +
> + s->nb_planes = av_pix_fmt_count_planes(inlink->format);
> +
> + return 0;
> +}
> +
> +/*
> + * This macro interpolates the value of both fields at a point halfway
> + * between lines and takes the squared difference. In field resolution
> + * the point is a quarter pixel below a line in one field and a quarter
> + * pixel above a line in other.
> + *
> + * (The result is actually multiplied by 25)
> + */
> +#define DIFF(a, as, b, bs) (t = ((*a - b[bs]) << 2) + a[as << 1] - b[-bs], t * t)
> +
> +/*
> + * Find which field combination has the smallest average squared difference
> + * between the fields.
> + */
> +static enum PhaseMode analyze_plane(AVFilterContext *ctx, PhaseContext *s, AVFrame *old, AVFrame *new)
> +{
[...]
Should be fine assuming that it's bit identical with mp=phase.
Looks fine otherwise, but please wait one day so I can have a more
indepth look at the algorithm.
--
FFmpeg = Frightening and Fundamentalist Moronic Portentous Elaborated Gladiator
More information about the ffmpeg-devel
mailing list