avfilter: add pseudocolor filter
This commit is contained in:
		
							parent
							
								
									3c99523a28
								
							
						
					
					
						commit
						e3a4afca07
					
				@ -32,6 +32,7 @@ version <next>:
 | 
				
			|||||||
- unpremultiply video filter
 | 
					- unpremultiply video filter
 | 
				
			||||||
- tlut2 video filter
 | 
					- tlut2 video filter
 | 
				
			||||||
- floodfill video filter
 | 
					- floodfill video filter
 | 
				
			||||||
 | 
					- pseudocolor video filter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
version 3.3:
 | 
					version 3.3:
 | 
				
			||||||
- CrystalHD decoder moved to new decode API
 | 
					- CrystalHD decoder moved to new decode API
 | 
				
			||||||
 | 
				
			|||||||
@ -11785,6 +11785,51 @@ Set value which will be multiplied with filtered result.
 | 
				
			|||||||
Set value which will be added to filtered result.
 | 
					Set value which will be added to filtered result.
 | 
				
			||||||
@end table
 | 
					@end table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section pseudocolor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Alter frame colors in video with pseudocolors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This filter accept the following options:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@table @option
 | 
				
			||||||
 | 
					@item c0
 | 
				
			||||||
 | 
					set pixel first component expression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item c1
 | 
				
			||||||
 | 
					set pixel second component expression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item c2
 | 
				
			||||||
 | 
					set pixel third component expression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item c3
 | 
				
			||||||
 | 
					set pixel fourth component expression, corresponds to the alpha component
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item i
 | 
				
			||||||
 | 
					set component to use as base for altering colors
 | 
				
			||||||
 | 
					@end table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each of them specifies the expression to use for computing the lookup table for
 | 
				
			||||||
 | 
					the corresponding pixel component values.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The expressions can contain the following constants and functions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@table @option
 | 
				
			||||||
 | 
					@item w
 | 
				
			||||||
 | 
					@item h
 | 
				
			||||||
 | 
					The input width and height.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item val
 | 
				
			||||||
 | 
					The input value for the pixel component.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item ymin, umin, vmin, amin
 | 
				
			||||||
 | 
					The minimum allowed component value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item ymax, umax, vmax, amax
 | 
				
			||||||
 | 
					The maximum allowed component value.
 | 
				
			||||||
 | 
					@end table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All expressions default to "val".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@section psnr
 | 
					@section psnr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Obtain the average, maximum and minimum PSNR (Peak Signal to Noise
 | 
					Obtain the average, maximum and minimum PSNR (Peak Signal to Noise
 | 
				
			||||||
 | 
				
			|||||||
@ -259,6 +259,7 @@ OBJS-$(CONFIG_PP_FILTER)                     += vf_pp.o
 | 
				
			|||||||
OBJS-$(CONFIG_PP7_FILTER)                    += vf_pp7.o
 | 
					OBJS-$(CONFIG_PP7_FILTER)                    += vf_pp7.o
 | 
				
			||||||
OBJS-$(CONFIG_PREMULTIPLY_FILTER)            += vf_premultiply.o framesync2.o
 | 
					OBJS-$(CONFIG_PREMULTIPLY_FILTER)            += vf_premultiply.o framesync2.o
 | 
				
			||||||
OBJS-$(CONFIG_PREWITT_FILTER)                += vf_convolution.o
 | 
					OBJS-$(CONFIG_PREWITT_FILTER)                += vf_convolution.o
 | 
				
			||||||
 | 
					OBJS-$(CONFIG_PSEUDOCOLOR_FILTER)            += vf_pseudocolor.o
 | 
				
			||||||
OBJS-$(CONFIG_PSNR_FILTER)                   += vf_psnr.o dualinput.o framesync.o
 | 
					OBJS-$(CONFIG_PSNR_FILTER)                   += vf_psnr.o dualinput.o framesync.o
 | 
				
			||||||
OBJS-$(CONFIG_PULLUP_FILTER)                 += vf_pullup.o
 | 
					OBJS-$(CONFIG_PULLUP_FILTER)                 += vf_pullup.o
 | 
				
			||||||
OBJS-$(CONFIG_QP_FILTER)                     += vf_qp.o
 | 
					OBJS-$(CONFIG_QP_FILTER)                     += vf_qp.o
 | 
				
			||||||
 | 
				
			|||||||
@ -270,6 +270,7 @@ static void register_all(void)
 | 
				
			|||||||
    REGISTER_FILTER(PP7,            pp7,            vf);
 | 
					    REGISTER_FILTER(PP7,            pp7,            vf);
 | 
				
			||||||
    REGISTER_FILTER(PREMULTIPLY,    premultiply,    vf);
 | 
					    REGISTER_FILTER(PREMULTIPLY,    premultiply,    vf);
 | 
				
			||||||
    REGISTER_FILTER(PREWITT,        prewitt,        vf);
 | 
					    REGISTER_FILTER(PREWITT,        prewitt,        vf);
 | 
				
			||||||
 | 
					    REGISTER_FILTER(PSEUDOCOLOR,    pseudocolor,    vf);
 | 
				
			||||||
    REGISTER_FILTER(PSNR,           psnr,           vf);
 | 
					    REGISTER_FILTER(PSNR,           psnr,           vf);
 | 
				
			||||||
    REGISTER_FILTER(PULLUP,         pullup,         vf);
 | 
					    REGISTER_FILTER(PULLUP,         pullup,         vf);
 | 
				
			||||||
    REGISTER_FILTER(QP,             qp,             vf);
 | 
					    REGISTER_FILTER(QP,             qp,             vf);
 | 
				
			||||||
 | 
				
			|||||||
@ -30,7 +30,7 @@
 | 
				
			|||||||
#include "libavutil/version.h"
 | 
					#include "libavutil/version.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LIBAVFILTER_VERSION_MAJOR   6
 | 
					#define LIBAVFILTER_VERSION_MAJOR   6
 | 
				
			||||||
#define LIBAVFILTER_VERSION_MINOR  99
 | 
					#define LIBAVFILTER_VERSION_MINOR 100
 | 
				
			||||||
#define LIBAVFILTER_VERSION_MICRO 100
 | 
					#define LIBAVFILTER_VERSION_MICRO 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
 | 
					#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										256
									
								
								libavfilter/vf_pseudocolor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								libavfilter/vf_pseudocolor.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,256 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2017 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/attributes.h"
 | 
				
			||||||
 | 
					#include "libavutil/common.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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *const var_names[] = {
 | 
				
			||||||
 | 
					    "w",        ///< width of the input video
 | 
				
			||||||
 | 
					    "h",        ///< height of the input video
 | 
				
			||||||
 | 
					    "val",      ///< input value for the pixel
 | 
				
			||||||
 | 
					    "ymin",
 | 
				
			||||||
 | 
					    "umin",
 | 
				
			||||||
 | 
					    "vmin",
 | 
				
			||||||
 | 
					    "amin",
 | 
				
			||||||
 | 
					    "ymax",
 | 
				
			||||||
 | 
					    "umax",
 | 
				
			||||||
 | 
					    "vmax",
 | 
				
			||||||
 | 
					    "amax",
 | 
				
			||||||
 | 
					    NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum var_name {
 | 
				
			||||||
 | 
					    VAR_W,
 | 
				
			||||||
 | 
					    VAR_H,
 | 
				
			||||||
 | 
					    VAR_VAL,
 | 
				
			||||||
 | 
					    VAR_YMIN,
 | 
				
			||||||
 | 
					    VAR_UMIN,
 | 
				
			||||||
 | 
					    VAR_VMIN,
 | 
				
			||||||
 | 
					    VAR_AMIN,
 | 
				
			||||||
 | 
					    VAR_YMAX,
 | 
				
			||||||
 | 
					    VAR_UMAX,
 | 
				
			||||||
 | 
					    VAR_VMAX,
 | 
				
			||||||
 | 
					    VAR_AMAX,
 | 
				
			||||||
 | 
					    VAR_VARS_NB
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct PseudoColorContext {
 | 
				
			||||||
 | 
					    const AVClass *class;
 | 
				
			||||||
 | 
					    int max;
 | 
				
			||||||
 | 
					    int index;
 | 
				
			||||||
 | 
					    int nb_planes;
 | 
				
			||||||
 | 
					    int color;
 | 
				
			||||||
 | 
					    int linesize[4];
 | 
				
			||||||
 | 
					    int width[4], height[4];
 | 
				
			||||||
 | 
					    double var_values[VAR_VARS_NB];
 | 
				
			||||||
 | 
					    char   *comp_expr_str[4];
 | 
				
			||||||
 | 
					    AVExpr *comp_expr[4];
 | 
				
			||||||
 | 
					    float lut[4][256];
 | 
				
			||||||
 | 
					} PseudoColorContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OFFSET(x) offsetof(PseudoColorContext, x)
 | 
				
			||||||
 | 
					#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const AVOption pseudocolor_options[] = {
 | 
				
			||||||
 | 
					    { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
 | 
				
			||||||
 | 
					    { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
 | 
				
			||||||
 | 
					    { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
 | 
				
			||||||
 | 
					    { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, {.str="val"},   .flags = FLAGS },
 | 
				
			||||||
 | 
					    { "i",  "set component as base",       OFFSET(index),            AV_OPT_TYPE_INT,    {.i64=0}, 0, 3, .flags = FLAGS },
 | 
				
			||||||
 | 
					    { NULL }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const enum AVPixelFormat pix_fmts[] = {
 | 
				
			||||||
 | 
					    AV_PIX_FMT_GRAY8,
 | 
				
			||||||
 | 
					    AV_PIX_FMT_YUV444P, AV_PIX_FMT_GBRP,
 | 
				
			||||||
 | 
					    AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GBRAP,
 | 
				
			||||||
 | 
					    AV_PIX_FMT_NONE
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int query_formats(AVFilterContext *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
 | 
				
			||||||
 | 
					    if (!fmts_list)
 | 
				
			||||||
 | 
					        return AVERROR(ENOMEM);
 | 
				
			||||||
 | 
					    return ff_set_common_formats(ctx, fmts_list);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int config_input(AVFilterLink *inlink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    AVFilterContext *ctx = inlink->dst;
 | 
				
			||||||
 | 
					    PseudoColorContext *s = ctx->priv;
 | 
				
			||||||
 | 
					    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
 | 
				
			||||||
 | 
					    int depth, ret, hsub, vsub, color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    depth = desc->comp[0].depth;
 | 
				
			||||||
 | 
					    s->max = (1 << depth) - 1;
 | 
				
			||||||
 | 
					    s->nb_planes = av_pix_fmt_count_planes(inlink->format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->index >= s->nb_planes) {
 | 
				
			||||||
 | 
					        av_log(ctx, AV_LOG_ERROR, "index out of allowed range\n");
 | 
				
			||||||
 | 
					        return AVERROR(EINVAL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hsub = desc->log2_chroma_w;
 | 
				
			||||||
 | 
					    vsub = desc->log2_chroma_h;
 | 
				
			||||||
 | 
					    s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
 | 
				
			||||||
 | 
					    s->height[0] = s->height[3] = inlink->h;
 | 
				
			||||||
 | 
					    s->width[1]  = s->width[2]  = AV_CEIL_RSHIFT(inlink->w, hsub);
 | 
				
			||||||
 | 
					    s->width[0]  = s->width[3]  = inlink->w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->var_values[VAR_W] = inlink->w;
 | 
				
			||||||
 | 
					    s->var_values[VAR_H] = inlink->h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->var_values[VAR_YMIN] = 16 * (1 << (depth - 8));
 | 
				
			||||||
 | 
					    s->var_values[VAR_UMIN] = 16 * (1 << (depth - 8));
 | 
				
			||||||
 | 
					    s->var_values[VAR_VMIN] = 16 * (1 << (depth - 8));
 | 
				
			||||||
 | 
					    s->var_values[VAR_AMIN] = 0;
 | 
				
			||||||
 | 
					    s->var_values[VAR_YMAX] = 235 * (1 << (depth - 8));
 | 
				
			||||||
 | 
					    s->var_values[VAR_UMAX] = 240 * (1 << (depth - 8));
 | 
				
			||||||
 | 
					    s->var_values[VAR_VMAX] = 240 * (1 << (depth - 8));
 | 
				
			||||||
 | 
					    s->var_values[VAR_AMAX] = s->max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (color = 0; color < s->nb_planes; color++) {
 | 
				
			||||||
 | 
					        double res;
 | 
				
			||||||
 | 
					        int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* create the parsed expression */
 | 
				
			||||||
 | 
					        av_expr_free(s->comp_expr[color]);
 | 
				
			||||||
 | 
					        s->comp_expr[color] = NULL;
 | 
				
			||||||
 | 
					        ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
 | 
				
			||||||
 | 
					                            var_names, NULL, NULL, NULL, NULL, 0, ctx);
 | 
				
			||||||
 | 
					        if (ret < 0) {
 | 
				
			||||||
 | 
					            av_log(ctx, AV_LOG_ERROR,
 | 
				
			||||||
 | 
					                   "Error when parsing the expression '%s' for the component %d and color %d.\n",
 | 
				
			||||||
 | 
					                   s->comp_expr_str[color], color, color);
 | 
				
			||||||
 | 
					            return AVERROR(EINVAL);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* compute the lut */
 | 
				
			||||||
 | 
					        for (val = 0; val < FF_ARRAY_ELEMS(s->lut[color]); val++) {
 | 
				
			||||||
 | 
					            s->var_values[VAR_VAL] = val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            res = av_expr_eval(s->comp_expr[color], s->var_values, s);
 | 
				
			||||||
 | 
					            if (isnan(res)) {
 | 
				
			||||||
 | 
					                av_log(ctx, AV_LOG_ERROR,
 | 
				
			||||||
 | 
					                       "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
 | 
				
			||||||
 | 
					                       s->comp_expr_str[color], val, color);
 | 
				
			||||||
 | 
					                return AVERROR(EINVAL);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            s->lut[color][val] = res;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    AVFilterContext *ctx = inlink->dst;
 | 
				
			||||||
 | 
					    PseudoColorContext *s = ctx->priv;
 | 
				
			||||||
 | 
					    AVFilterLink *outlink = ctx->outputs[0];
 | 
				
			||||||
 | 
					    AVFrame *out;
 | 
				
			||||||
 | 
					    int x, y, plane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
 | 
				
			||||||
 | 
					    if (!out) {
 | 
				
			||||||
 | 
					        av_frame_free(&in);
 | 
				
			||||||
 | 
					        return AVERROR(ENOMEM);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    av_frame_copy_props(out, in);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (plane = 0; plane < s->nb_planes; plane++) {
 | 
				
			||||||
 | 
					        const uint8_t *index = in->data[s->index];
 | 
				
			||||||
 | 
					        const uint8_t *src = in->data[plane];
 | 
				
			||||||
 | 
					        uint8_t *dst = out->data[plane];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (y = 0; y < s->height[plane]; y++) {
 | 
				
			||||||
 | 
					            for (x = 0; x < s->width[plane]; x++) {
 | 
				
			||||||
 | 
					                int v = s->lut[plane][index[x]];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (v >= 0 && v <= s->max) {
 | 
				
			||||||
 | 
					                    dst[x] = v;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    dst[x] = src[x];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            index += in->linesize[s->index];
 | 
				
			||||||
 | 
					            src += in->linesize[plane];
 | 
				
			||||||
 | 
					            dst += out->linesize[plane];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    av_frame_free(&in);
 | 
				
			||||||
 | 
					    return ff_filter_frame(outlink, out);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const AVFilterPad inputs[] = {
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .name         = "default",
 | 
				
			||||||
 | 
					        .type         = AVMEDIA_TYPE_VIDEO,
 | 
				
			||||||
 | 
					        .filter_frame = filter_frame,
 | 
				
			||||||
 | 
					        .config_props = config_input,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { NULL }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const AVFilterPad outputs[] = {
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .name = "default",
 | 
				
			||||||
 | 
					        .type = AVMEDIA_TYPE_VIDEO,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { NULL }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static av_cold void uninit(AVFilterContext *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PseudoColorContext *s = ctx->priv;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 4; i++) {
 | 
				
			||||||
 | 
					        av_expr_free(s->comp_expr[i]);
 | 
				
			||||||
 | 
					        s->comp_expr[i] = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AVFILTER_DEFINE_CLASS(pseudocolor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AVFilter ff_vf_pseudocolor = {
 | 
				
			||||||
 | 
					    .name          = "pseudocolor",
 | 
				
			||||||
 | 
					    .description   = NULL_IF_CONFIG_SMALL("Make pseudocolored video frames."),
 | 
				
			||||||
 | 
					    .priv_size     = sizeof(PseudoColorContext),
 | 
				
			||||||
 | 
					    .priv_class    = &pseudocolor_class,
 | 
				
			||||||
 | 
					    .uninit        = uninit,
 | 
				
			||||||
 | 
					    .query_formats = query_formats,
 | 
				
			||||||
 | 
					    .inputs        = inputs,
 | 
				
			||||||
 | 
					    .outputs       = outputs,
 | 
				
			||||||
 | 
					    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user