[FFmpeg-devel] [PATCH] avfilter: port qp filter from libmpcodecs

Paul B Mahol onemda at gmail.com
Thu Sep 19 22:48:55 CEST 2013


On 9/19/13, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Thu, Sep 19, 2013 at 06:00:55PM +0000, Paul B Mahol wrote:
>> On 9/19/13, Michael Niedermayer <michaelni at gmx.at> wrote:
>> > On Thu, Sep 19, 2013 at 10:49:41AM +0000, Paul B Mahol wrote:
>> >> On 9/19/13, Michael Niedermayer <michaelni at gmx.at> wrote:
>> >> > On Wed, Sep 18, 2013 at 11:57:55PM +0000, Paul B Mahol wrote:
>> >> >> Signed-off-by: Paul B Mahol <onemda at gmail.com>
>> >> >> ---
>> >> >>  doc/filters.texi         |  32 ++++++++++
>> >> >>  libavfilter/Makefile     |   1 +
>> >> >>  libavfilter/allfilters.c |   1 +
>> >> >>  libavfilter/vf_qp.c      | 152
>> >> >> +++++++++++++++++++++++++++++++++++++++++++++++
>> >> >>  4 files changed, 186 insertions(+)
>> >> >>  create mode 100644 libavfilter/vf_qp.c
>> >> >>
>> >> >> diff --git a/doc/filters.texi b/doc/filters.texi
>> >> >> index 915f310..127885a 100644
>> >> >> --- a/doc/filters.texi
>> >> >> +++ b/doc/filters.texi
>> >> >> @@ -6236,6 +6236,38 @@ The main purpose of setting @option{mp} to a
>> >> >> chroma
>> >> >> plane is to reduce CPU
>> >> >>  load and make pullup usable in realtime on slow machines.
>> >> >>  @end table
>> >> >>
>> >> >> + at section qp
>> >> >> +
>> >> >> +Change video quantization parameters (QP).
>> >> >> +
>> >> >> +The filter accepts the following option:
>> >> >> +
>> >> >> + at table @option
>> >> >> + at item qp
>> >> >> +Set expression for quantization parameter.
>> >> >> + at end table
>> >> >> +
>> >> >> +The expression is evaluated through the eval API and can contain,
>> >> >> among
>> >> >> others,
>> >> >> +the following constants:
>> >> >> +
>> >> >> + at table @var
>> >> >> + at item known
>> >> >> +1 if index is not 129, 0 otherwise.
>> >> >> +
>> >> >> + at item qp
>> >> >> +Sequentional index starting from -129 to 128.
>> >> >> + at end table
>> >> >> +
>> >> >> + at subsection Examples
>> >> >> +
>> >> >> + at itemize
>> >> >> + at item
>> >> >> +Some equation like:
>> >> >> + at example
>> >> >> +qp=2+2*sin(PI*qp)
>> >> >> + at end example
>> >> >> + at end itemize
>> >> >> +
>> >> >>  @section removelogo
>> >> >>
>> >> >>  Suppress a TV station logo, using an image file to determine which
>> >> >> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
>> >> >> index 198bf4c..5dc8389 100644
>> >> >> --- a/libavfilter/Makefile
>> >> >> +++ b/libavfilter/Makefile
>> >> >> @@ -174,6 +174,7 @@ OBJS-$(CONFIG_PIXDESCTEST_FILTER)            +=
>> >> >> vf_pixdesctest.o
>> >> >>  OBJS-$(CONFIG_PP_FILTER)                     += vf_pp.o
>> >> >>  OBJS-$(CONFIG_PSNR_FILTER)                   += vf_psnr.o
>> >> >> dualinput.o
>> >> >>  OBJS-$(CONFIG_PULLUP_FILTER)                 += vf_pullup.o
>> >> >> +OBJS-$(CONFIG_QP_FILTER)                     += vf_qp.o
>> >> >>  OBJS-$(CONFIG_REMOVELOGO_FILTER)             += bbox.o lswsutils.o
>> >> >> lavfutils.o vf_removelogo.o
>> >> >>  OBJS-$(CONFIG_ROTATE_FILTER)                 += vf_rotate.o
>> >> >>  OBJS-$(CONFIG_SEPARATEFIELDS_FILTER)         +=
>> >> >> vf_separatefields.o
>> >> >> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
>> >> >> index 2825304..69e6cab 100644
>> >> >> --- a/libavfilter/allfilters.c
>> >> >> +++ b/libavfilter/allfilters.c
>> >> >> @@ -169,6 +169,7 @@ void avfilter_register_all(void)
>> >> >>      REGISTER_FILTER(PP,             pp,             vf);
>> >> >>      REGISTER_FILTER(PSNR,           psnr,           vf);
>> >> >>      REGISTER_FILTER(PULLUP,         pullup,         vf);
>> >> >> +    REGISTER_FILTER(QP,             qp,             vf);
>> >> >>      REGISTER_FILTER(REMOVELOGO,     removelogo,     vf);
>> >> >>      REGISTER_FILTER(ROTATE,         rotate,         vf);
>> >> >>      REGISTER_FILTER(SAB,            sab,            vf);
>> >> >> diff --git a/libavfilter/vf_qp.c b/libavfilter/vf_qp.c
>> >> >> new file mode 100644
>> >> >> index 0000000..67fe2ec
>> >> >> --- /dev/null
>> >> >> +++ b/libavfilter/vf_qp.c
>> >> >> @@ -0,0 +1,152 @@
>> >> >> +/*
>> >> >> + * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
>> >> >> + *
>> >> >> + * 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 <math.h>
>> >> >> +#include "libavutil/eval.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"
>> >> >> +
>> >> >> +typedef struct QPContext {
>> >> >> +    const AVClass *class;
>> >> >> +    char *qp_expr_str;
>> >> >> +    int8_t lut[257];
>> >> >> +    int h, qstride;
>> >> >> +} QPContext;
>> >> >> +
>> >> >> +#define OFFSET(x) offsetof(QPContext, x)
>> >> >> +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
>> >> >> +
>> >> >> +static const AVOption qp_options[] = {
>> >> >> +    { "qp", "set qp expression", OFFSET(qp_expr_str),
>> >> >> AV_OPT_TYPE_STRING,
>> >> >> {.str=NULL}, 0, 0, FLAGS },
>> >> >> +    { NULL }
>> >> >> +};
>> >> >> +
>> >> >> +AVFILTER_DEFINE_CLASS(qp);
>> >> >> +
>> >> >> +static int config_input(AVFilterLink *inlink)
>> >> >> +{
>> >> >> +    AVFilterContext *ctx = inlink->dst;
>> >> >> +    QPContext *s = ctx->priv;
>> >> >> +    int i;
>> >> >> +
>> >> >> +    if (!s->qp_expr_str)
>> >> >> +        return 0;
>> >> >> +
>> >> >> +    s->h       = (inlink->h + 15) >> 4;
>> >> >> +    s->qstride = (inlink->w + 15) >> 4;
>> >> >> +    for (i = -129; i < 128; i++) {
>> >> >> +        double var_values[] = { i != -129, i, 0 };
>> >> >> +        static const char *var_names[] = { "known", "qp", NULL };
>> >> >> +        double temp_val;
>> >> >> +        int ret;
>> >> >> +
>> >> >> +        ret = av_expr_parse_and_eval(&temp_val, s->qp_expr_str,
>> >> >> +                                     var_names, var_values,
>> >> >> +                                     NULL, NULL, NULL, NULL, 0, 0,
>> >> >> ctx);
>> >> >> +        if (ret < 0)
>> >> >> +            return ret;
>> >> >> +
>> >> >> +        s->lut[i + 129] = lrintf(temp_val);
>> >> >> +    }
>> >> >
>> >> > it could make sense to allow forcing the evaluating the expression
>> >> > for
>> >> > each macroblock
>> >> > that way it could be used to do spatial or temporal smoothing,
>> >> > depend on frame number of do add a random value
>> >>
>> >> Gread idea, but becaues I can't compare it with broken mp=qp, I want
>> >> to
>> >> know
>> >> is current code (use of API) correct?
>> >>
>> >> This patch is not about adding new (non-trivial/easy) features, one
>> >> can do it freely later.
>> >
>> > the API use should be ok but i dont think you need to clone the frame
>>
>> So i can just overwrite it, even if frame is not writtable?
>
> you can set a new table, you cant write into an existing table without
> some additional checks

OK, so I will commit this as is (with cloning removed) and leave it to
others to improve/extend it.
I can't as I'm missing testcase.

>
> [...]
>
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> It is dangerous to be right in matters on which the established authorities
> are wrong. -- Voltaire
>


More information about the ffmpeg-devel mailing list