~medibuntu-maintainers/mplayer/medibuntu.quantal

« back to all changes in this revision

Viewing changes to ffmpeg/libavfilter/vf_lut.c

  • Committer: Gauvain Pocentek
  • Date: 2012-03-06 11:59:12 UTC
  • mfrom: (66.1.15 precise)
  • Revision ID: gauvain@pocentek.net-20120306115912-h9d6kt9j0l532oo5
* Merge from Ubuntu:
  - put back faac support
  - recommends apport-hooks-medibuntu
  - change Maintainer, Uploaders & Vcs-* fields.
* New upstream snapshot
* upload to unstable
* Build against external libmpeg2
* drop 51_FTBFS_arm.patch again
* no longer build depend on libcdparanoia-dev on the Hurd
* Fix FTBFS on the hurd.
  Thanks to Samuel Thibault <sthibault@debian.org> (Closes: #654974)
* Fix FTBFS on arm
* New upstream snapshot, Closes: #650339, #643621, #481807
* Imported Upstream version 1.0~rc4+svn34492
* Bump standards version
* Bump dependency on libav >= 4:0.8~, Closes: #653887
* Fix build-indep
* Build mplayer-gui again, Closes: #568514
* Drop debian/all-lang-config-mak.sh, no longer needed
* include .dfsg1 in version number
* remove get-orig-source target
* no longer prune compiler flags from the environment
* No longer advertise nor build 3fdx, mga and dxr3 backends,
  Closes: #496106, #442181, #533546
* beautify mplayer version identification string
* Brown paperbag upload.
* Next try to fix build failure on sparce after recent binutils change.
* Brown paperbag upload.
* Really fix build failure on sparc after recent binutils change.
* Properly set Replaces/Conflicts on mplayer2{,-dbg} to avoid
  file overwrite errors.
* Adjust versioning of mplayer listed in the mplayer-dbg's Depends field.
* Fix build failure on sparc after recent binutils change.
* Urgency medium bumped because of RC-level bugfix
  and speeding up x264 transition.
* Update to my @debian.org email.
* Upload to unstable
* Enable joystick support on Linux only, Closes: #638408
* Rebuild fixes toolchain issue on arm, Closes: #637077
* New upstream snapshot
* following the discussion started by Diego Biurrun <diego@biurrun.de>
  in debian-devel, I have prepared a new packaging of 'mplayer'
  (with code that comes from CVS)
* the upstream tar.bz cannot be distributed by Debian, since it contains
   CSS code; so I am repackaging it 
* I have tried my best to address all known issues:
  - the package contains the detailed Copyright made by Diego Biurrun 
  - the package does not contain CSS code, or  AFAIK other code on which 
     there is active patent enforcement
  - there is a script  debian/cvs-changelog.sh  that shows all changes
     done to files included in this source.
    This should comply with GPLv2 sec 2.a  (in spirit if not in letter)
    For this reason, the source code contains CVS directories.
* needs   make (>= 3.80) for 'html-chunked-$(1)' in DOCS/xml/Makefile

* some corrections, as suggested Diego Biurrun
  - binary codecs should go into /usr/lib/codecs (upstream default)
  - better template 'mplayer/install_codecs'
  - an empty 'font=' in mplayer.conf breaks mplayer: postinst corrected
* correction in 'mplayer/cfgnote'
* better mplayer.postinst and mplayer.config

* New upstream release
* better debian/copyright file
* do not ship a skin
* New upstream release
* changed DEB_BUILD_OPTIONS to DEB_BUILD_CONFIGURE ,
  DEB_BUILD_OPTIONS is used as in debian policy
* use gcc-3.4
* changed xlibs-dev to a long list of dependencies, for Debian/etch
* try to adhere to  http://www.mplayerhq.hu/DOCS/tech/binary-packaging.txt
  (see README.Debian for details)
* removed dependency on xlibmesa-dev, disabled opengl
* New upstream release
* Simon McVittie <hacks@pseudorandom.co.uk> wonderful work:
- Work around Debian bug #267442 (glibc's sys/uio.h and gcc's altivec.h have
  conflicting uses for __vector) by re-ordering #includes
- Fix potential symlink attack in ./configure
- Disable support for binary codecs on platforms for which those codecs
  aren't available; also disable the corresponding Debconf note when it's
  inappropriate
- Changed Build-Depends: so it works in pbuilder
- Explicitly build-depend on libjpeg62-dev, libfontconfig1-dev,
  libungif4-dev 
- Tweak debian/rules to avoid certain errors being ignored
- Use --language=all
* provide a target  'debian/rules get-orig-source' 
  that recreates the orig.tar.gz ; then use the above orig.tar.gz
* rewrote some parts of debian/rules
* don't clean and recompile docs if upstream ships them
* mplayer-doc was shipping too much stuff
* translated man pages where not installed properly
* compile with libdv4-dev
* correct README.Debian
* Forgot build-dep on libtheora
* Must not depend on libxvidcore
* New upstream release
* new release.
* rc1 to become 0.90
* new pre-release
* new pre-release
* gtk bug fixed.
* new release.
* version bumped
* 0.60 pre2 release
* 0.60 pre-release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2011 Stefano Sabatini
 
3
 *
 
4
 * This file is part of Libav.
 
5
 *
 
6
 * Libav is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * Libav is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with Libav; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
19
 */
 
20
 
 
21
/**
 
22
 * @file
 
23
 * Compute a look-up table for binding the input value to the output
 
24
 * value, and apply it to input video.
 
25
 */
 
26
 
 
27
#include "libavutil/eval.h"
 
28
#include "libavutil/mathematics.h"
 
29
#include "libavutil/opt.h"
 
30
#include "libavutil/pixdesc.h"
 
31
#include "avfilter.h"
 
32
#include "internal.h"
 
33
 
 
34
static const char *var_names[] = {
 
35
    "E",
 
36
    "PHI",
 
37
    "PI",
 
38
    "w",        ///< width of the input video
 
39
    "h",        ///< height of the input video
 
40
    "val",      ///< input value for the pixel
 
41
    "maxval",   ///< max value for the pixel
 
42
    "minval",   ///< min value for the pixel
 
43
    "negval",   ///< negated value
 
44
    "clipval",
 
45
    NULL
 
46
};
 
47
 
 
48
enum var_name {
 
49
    VAR_E,
 
50
    VAR_PHI,
 
51
    VAR_PI,
 
52
    VAR_W,
 
53
    VAR_H,
 
54
    VAR_VAL,
 
55
    VAR_MAXVAL,
 
56
    VAR_MINVAL,
 
57
    VAR_NEGVAL,
 
58
    VAR_CLIPVAL,
 
59
    VAR_VARS_NB
 
60
};
 
61
 
 
62
typedef struct {
 
63
    const AVClass *class;
 
64
    uint8_t lut[4][256];  ///< lookup table for each component
 
65
    char   *comp_expr_str[4];
 
66
    AVExpr *comp_expr[4];
 
67
    int hsub, vsub;
 
68
    double var_values[VAR_VARS_NB];
 
69
    int is_rgb, is_yuv;
 
70
    int rgba_map[4];
 
71
    int step;
 
72
    int negate_alpha; /* only used by negate */
 
73
} LutContext;
 
74
 
 
75
#define Y 0
 
76
#define U 1
 
77
#define V 2
 
78
#define R 0
 
79
#define G 1
 
80
#define B 2
 
81
#define A 3
 
82
 
 
83
#define OFFSET(x) offsetof(LutContext, x)
 
84
 
 
85
static const AVOption lut_options[] = {
 
86
    {"c0", "set component #0 expression", OFFSET(comp_expr_str[0]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
87
    {"c1", "set component #1 expression", OFFSET(comp_expr_str[1]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
88
    {"c2", "set component #2 expression", OFFSET(comp_expr_str[2]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
89
    {"c3", "set component #3 expression", OFFSET(comp_expr_str[3]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
90
    {"y",  "set Y expression", OFFSET(comp_expr_str[Y]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
91
    {"u",  "set U expression", OFFSET(comp_expr_str[U]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
92
    {"v",  "set V expression", OFFSET(comp_expr_str[V]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
93
    {"r",  "set R expression", OFFSET(comp_expr_str[R]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
94
    {"g",  "set G expression", OFFSET(comp_expr_str[G]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
95
    {"b",  "set B expression", OFFSET(comp_expr_str[B]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
96
    {"a",  "set A expression", OFFSET(comp_expr_str[A]),  FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
 
97
    {NULL},
 
98
};
 
99
 
 
100
static const char *lut_get_name(void *ctx)
 
101
{
 
102
    return "lut";
 
103
}
 
104
 
 
105
static const AVClass lut_class = {
 
106
    "LutContext",
 
107
    lut_get_name,
 
108
    lut_options
 
109
};
 
110
 
 
111
static int init(AVFilterContext *ctx, const char *args, void *opaque)
 
112
{
 
113
    LutContext *lut = ctx->priv;
 
114
    int ret;
 
115
 
 
116
    lut->class = &lut_class;
 
117
    av_opt_set_defaults(lut);
 
118
 
 
119
    lut->var_values[VAR_PHI] = M_PHI;
 
120
    lut->var_values[VAR_PI]  = M_PI;
 
121
    lut->var_values[VAR_E ]  = M_E;
 
122
 
 
123
    lut->is_rgb = !strcmp(ctx->filter->name, "lutrgb");
 
124
    lut->is_yuv = !strcmp(ctx->filter->name, "lutyuv");
 
125
    if (args && (ret = av_set_options_string(lut, args, "=", ":")) < 0)
 
126
        return ret;
 
127
 
 
128
    return 0;
 
129
}
 
130
 
 
131
static av_cold void uninit(AVFilterContext *ctx)
 
132
{
 
133
    LutContext *lut = ctx->priv;
 
134
    int i;
 
135
 
 
136
    for (i = 0; i < 4; i++) {
 
137
        av_expr_free(lut->comp_expr[i]);
 
138
        lut->comp_expr[i] = NULL;
 
139
        av_freep(&lut->comp_expr_str[i]);
 
140
    }
 
141
}
 
142
 
 
143
#define YUV_FORMATS                                         \
 
144
    PIX_FMT_YUV444P,  PIX_FMT_YUV422P,  PIX_FMT_YUV420P,    \
 
145
    PIX_FMT_YUV411P,  PIX_FMT_YUV410P,  PIX_FMT_YUV440P,    \
 
146
    PIX_FMT_YUVA420P,                                       \
 
147
    PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P,   \
 
148
    PIX_FMT_YUVJ440P
 
149
 
 
150
#define RGB_FORMATS                             \
 
151
    PIX_FMT_ARGB,         PIX_FMT_RGBA,         \
 
152
    PIX_FMT_ABGR,         PIX_FMT_BGRA,         \
 
153
    PIX_FMT_RGB24,        PIX_FMT_BGR24
 
154
 
 
155
static enum PixelFormat yuv_pix_fmts[] = { YUV_FORMATS, PIX_FMT_NONE };
 
156
static enum PixelFormat rgb_pix_fmts[] = { RGB_FORMATS, PIX_FMT_NONE };
 
157
static enum PixelFormat all_pix_fmts[] = { RGB_FORMATS, YUV_FORMATS, PIX_FMT_NONE };
 
158
 
 
159
static int query_formats(AVFilterContext *ctx)
 
160
{
 
161
    LutContext *lut = ctx->priv;
 
162
 
 
163
    enum PixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts :
 
164
                                 lut->is_yuv ? yuv_pix_fmts : all_pix_fmts;
 
165
 
 
166
    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
 
167
    return 0;
 
168
}
 
169
 
 
170
/**
 
171
 * Clip value val in the minval - maxval range.
 
172
 */
 
173
static double clip(void *opaque, double val)
 
174
{
 
175
    LutContext *lut = opaque;
 
176
    double minval = lut->var_values[VAR_MINVAL];
 
177
    double maxval = lut->var_values[VAR_MAXVAL];
 
178
 
 
179
    return av_clip(val, minval, maxval);
 
180
}
 
181
 
 
182
/**
 
183
 * Compute gamma correction for value val, assuming the minval-maxval
 
184
 * range, val is clipped to a value contained in the same interval.
 
185
 */
 
186
static double compute_gammaval(void *opaque, double gamma)
 
187
{
 
188
    LutContext *lut = opaque;
 
189
    double val    = lut->var_values[VAR_CLIPVAL];
 
190
    double minval = lut->var_values[VAR_MINVAL];
 
191
    double maxval = lut->var_values[VAR_MAXVAL];
 
192
 
 
193
    return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval;
 
194
}
 
195
 
 
196
static double (* const funcs1[])(void *, double) = {
 
197
    clip,
 
198
    compute_gammaval,
 
199
    NULL
 
200
};
 
201
 
 
202
static const char * const funcs1_names[] = {
 
203
    "clip",
 
204
    "gammaval",
 
205
    NULL
 
206
};
 
207
 
 
208
static int config_props(AVFilterLink *inlink)
 
209
{
 
210
    AVFilterContext *ctx = inlink->dst;
 
211
    LutContext *lut = ctx->priv;
 
212
    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
 
213
    int min[4], max[4];
 
214
    int val, comp, ret;
 
215
 
 
216
    lut->hsub = desc->log2_chroma_w;
 
217
    lut->vsub = desc->log2_chroma_h;
 
218
 
 
219
    lut->var_values[VAR_W] = inlink->w;
 
220
    lut->var_values[VAR_H] = inlink->h;
 
221
 
 
222
    switch (inlink->format) {
 
223
    case PIX_FMT_YUV410P:
 
224
    case PIX_FMT_YUV411P:
 
225
    case PIX_FMT_YUV420P:
 
226
    case PIX_FMT_YUV422P:
 
227
    case PIX_FMT_YUV440P:
 
228
    case PIX_FMT_YUV444P:
 
229
    case PIX_FMT_YUVA420P:
 
230
        min[Y] = min[U] = min[V] = 16;
 
231
        max[Y] = 235;
 
232
        max[U] = max[V] = 240;
 
233
        min[A] = 0; max[A] = 255;
 
234
        break;
 
235
    default:
 
236
        min[0] = min[1] = min[2] = min[3] = 0;
 
237
        max[0] = max[1] = max[2] = max[3] = 255;
 
238
    }
 
239
 
 
240
    lut->is_yuv = lut->is_rgb = 0;
 
241
    if      (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) lut->is_yuv = 1;
 
242
    else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) lut->is_rgb = 1;
 
243
 
 
244
    if (lut->is_rgb) {
 
245
        switch (inlink->format) {
 
246
        case PIX_FMT_ARGB:  lut->rgba_map[A] = 0; lut->rgba_map[R] = 1; lut->rgba_map[G] = 2; lut->rgba_map[B] = 3; break;
 
247
        case PIX_FMT_ABGR:  lut->rgba_map[A] = 0; lut->rgba_map[B] = 1; lut->rgba_map[G] = 2; lut->rgba_map[R] = 3; break;
 
248
        case PIX_FMT_RGBA:
 
249
        case PIX_FMT_RGB24: lut->rgba_map[R] = 0; lut->rgba_map[G] = 1; lut->rgba_map[B] = 2; lut->rgba_map[A] = 3; break;
 
250
        case PIX_FMT_BGRA:
 
251
        case PIX_FMT_BGR24: lut->rgba_map[B] = 0; lut->rgba_map[G] = 1; lut->rgba_map[R] = 2; lut->rgba_map[A] = 3; break;
 
252
        }
 
253
        lut->step = av_get_bits_per_pixel(desc) >> 3;
 
254
    }
 
255
 
 
256
    for (comp = 0; comp < desc->nb_components; comp++) {
 
257
        double res;
 
258
 
 
259
        /* create the parsed expression */
 
260
        ret = av_expr_parse(&lut->comp_expr[comp], lut->comp_expr_str[comp],
 
261
                            var_names, funcs1_names, funcs1, NULL, NULL, 0, ctx);
 
262
        if (ret < 0) {
 
263
            av_log(ctx, AV_LOG_ERROR,
 
264
                   "Error when parsing the expression '%s' for the component %d.\n",
 
265
                   lut->comp_expr_str[comp], comp);
 
266
            return AVERROR(EINVAL);
 
267
        }
 
268
 
 
269
        /* compute the lut */
 
270
        lut->var_values[VAR_MAXVAL] = max[comp];
 
271
        lut->var_values[VAR_MINVAL] = min[comp];
 
272
 
 
273
        for (val = 0; val < 256; val++) {
 
274
            lut->var_values[VAR_VAL] = val;
 
275
            lut->var_values[VAR_CLIPVAL] = av_clip(val, min[comp], max[comp]);
 
276
            lut->var_values[VAR_NEGVAL] =
 
277
                av_clip(min[comp] + max[comp] - lut->var_values[VAR_VAL],
 
278
                        min[comp], max[comp]);
 
279
 
 
280
            res = av_expr_eval(lut->comp_expr[comp], lut->var_values, lut);
 
281
            if (isnan(res)) {
 
282
                av_log(ctx, AV_LOG_ERROR,
 
283
                       "Error when evaluating the expression '%s' for the value %d for the component #%d.\n",
 
284
                       lut->comp_expr_str[comp], val, comp);
 
285
                return AVERROR(EINVAL);
 
286
            }
 
287
            lut->lut[comp][val] = av_clip((int)res, min[comp], max[comp]);
 
288
            av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, lut->lut[comp][val]);
 
289
        }
 
290
    }
 
291
 
 
292
    return 0;
 
293
}
 
294
 
 
295
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
 
296
{
 
297
    AVFilterContext *ctx = inlink->dst;
 
298
    LutContext *lut = ctx->priv;
 
299
    AVFilterLink *outlink = ctx->outputs[0];
 
300
    AVFilterBufferRef *inpic  = inlink ->cur_buf;
 
301
    AVFilterBufferRef *outpic = outlink->out_buf;
 
302
    uint8_t *inrow, *outrow, *inrow0, *outrow0;
 
303
    int i, j, k, plane;
 
304
 
 
305
    if (lut->is_rgb) {
 
306
        /* packed */
 
307
        inrow0  = inpic ->data[0] + y * inpic ->linesize[0];
 
308
        outrow0 = outpic->data[0] + y * outpic->linesize[0];
 
309
 
 
310
        for (i = 0; i < h; i ++) {
 
311
            inrow  = inrow0;
 
312
            outrow = outrow0;
 
313
            for (j = 0; j < inlink->w; j++) {
 
314
                for (k = 0; k < lut->step; k++)
 
315
                    outrow[k] = lut->lut[lut->rgba_map[k]][inrow[k]];
 
316
                outrow += lut->step;
 
317
                inrow  += lut->step;
 
318
            }
 
319
            inrow0  += inpic ->linesize[0];
 
320
            outrow0 += outpic->linesize[0];
 
321
        }
 
322
    } else {
 
323
        /* planar */
 
324
        for (plane = 0; plane < 4 && inpic->data[plane]; plane++) {
 
325
            int vsub = plane == 1 || plane == 2 ? lut->vsub : 0;
 
326
            int hsub = plane == 1 || plane == 2 ? lut->hsub : 0;
 
327
 
 
328
            inrow  = inpic ->data[plane] + (y>>vsub) * inpic ->linesize[plane];
 
329
            outrow = outpic->data[plane] + (y>>vsub) * outpic->linesize[plane];
 
330
 
 
331
            for (i = 0; i < h>>vsub; i ++) {
 
332
                for (j = 0; j < inlink->w>>hsub; j++)
 
333
                    outrow[j] = lut->lut[plane][inrow[j]];
 
334
                inrow  += inpic ->linesize[plane];
 
335
                outrow += outpic->linesize[plane];
 
336
            }
 
337
        }
 
338
    }
 
339
 
 
340
    avfilter_draw_slice(outlink, y, h, slice_dir);
 
341
}
 
342
 
 
343
#define DEFINE_LUT_FILTER(name_, description_, init_)                   \
 
344
    AVFilter avfilter_vf_##name_ = {                                    \
 
345
        .name          = #name_,                                        \
 
346
        .description   = NULL_IF_CONFIG_SMALL(description_),            \
 
347
        .priv_size     = sizeof(LutContext),                            \
 
348
                                                                        \
 
349
        .init          = init_,                                         \
 
350
        .uninit        = uninit,                                        \
 
351
        .query_formats = query_formats,                                 \
 
352
                                                                        \
 
353
        .inputs    = (AVFilterPad[]) {{ .name            = "default",   \
 
354
                                        .type            = AVMEDIA_TYPE_VIDEO, \
 
355
                                        .draw_slice      = draw_slice,  \
 
356
                                        .config_props    = config_props, \
 
357
                                        .min_perms       = AV_PERM_READ, }, \
 
358
                                      { .name = NULL}},                 \
 
359
        .outputs   = (AVFilterPad[]) {{ .name            = "default",   \
 
360
                                        .type            = AVMEDIA_TYPE_VIDEO, }, \
 
361
                                      { .name = NULL}},                 \
 
362
    }
 
363
 
 
364
#if CONFIG_LUT_FILTER
 
365
DEFINE_LUT_FILTER(lut,    "Compute and apply a lookup table to the RGB/YUV input video.", init);
 
366
#endif
 
367
#if CONFIG_LUTYUV_FILTER
 
368
DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.",     init);
 
369
#endif
 
370
#if CONFIG_LUTRGB_FILTER
 
371
DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.",     init);
 
372
#endif
 
373
 
 
374
#if CONFIG_NEGATE_FILTER
 
375
 
 
376
static int negate_init(AVFilterContext *ctx, const char *args, void *opaque)
 
377
{
 
378
    LutContext *lut = ctx->priv;
 
379
    char lut_params[64];
 
380
 
 
381
    if (args)
 
382
        sscanf(args, "%d", &lut->negate_alpha);
 
383
 
 
384
    av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", lut->negate_alpha);
 
385
 
 
386
    snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s",
 
387
             lut->negate_alpha ? "negval" : "val");
 
388
 
 
389
    return init(ctx, lut_params, opaque);
 
390
}
 
391
 
 
392
DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init);
 
393
 
 
394
#endif