yading@10: /* yading@10: * Copyright (c) 2010 Stefano Sabatini yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * frei0r wrapper yading@10: */ yading@10: yading@10: /* #define DEBUG */ yading@10: yading@10: #include yading@10: #include yading@10: #include yading@10: #include yading@10: #include yading@10: #include "config.h" yading@10: #include "libavutil/avstring.h" yading@10: #include "libavutil/imgutils.h" yading@10: #include "libavutil/internal.h" yading@10: #include "libavutil/mathematics.h" yading@10: #include "libavutil/mem.h" yading@10: #include "libavutil/opt.h" yading@10: #include "libavutil/parseutils.h" yading@10: #include "avfilter.h" yading@10: #include "formats.h" yading@10: #include "internal.h" yading@10: #include "video.h" yading@10: yading@10: typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height); yading@10: typedef void (*f0r_destruct_f)(f0r_instance_t instance); yading@10: typedef void (*f0r_deinit_f)(void); yading@10: typedef int (*f0r_init_f)(void); yading@10: typedef void (*f0r_get_plugin_info_f)(f0r_plugin_info_t *info); yading@10: typedef void (*f0r_get_param_info_f)(f0r_param_info_t *info, int param_index); yading@10: typedef void (*f0r_update_f)(f0r_instance_t instance, double time, const uint32_t *inframe, uint32_t *outframe); yading@10: typedef void (*f0r_update2_f)(f0r_instance_t instance, double time, const uint32_t *inframe1, const uint32_t *inframe2, const uint32_t *inframe3, uint32_t *outframe); yading@10: typedef void (*f0r_set_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index); yading@10: typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index); yading@10: yading@10: typedef struct Frei0rContext { yading@10: const AVClass *class; yading@10: f0r_update_f update; yading@10: void *dl_handle; /* dynamic library handle */ yading@10: f0r_instance_t instance; yading@10: f0r_plugin_info_t plugin_info; yading@10: yading@10: f0r_get_param_info_f get_param_info; yading@10: f0r_get_param_value_f get_param_value; yading@10: f0r_set_param_value_f set_param_value; yading@10: f0r_construct_f construct; yading@10: f0r_destruct_f destruct; yading@10: f0r_deinit_f deinit; yading@10: yading@10: char *dl_name; yading@10: char *params; yading@10: char *size; yading@10: char *framerate; yading@10: yading@10: /* only used by the source */ yading@10: int w, h; yading@10: AVRational time_base; yading@10: uint64_t pts; yading@10: } Frei0rContext; yading@10: yading@10: static void *load_sym(AVFilterContext *ctx, const char *sym_name) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: void *sym = dlsym(frei0r->dl_handle, sym_name); yading@10: if (!sym) yading@10: av_log(ctx, AV_LOG_ERROR, "Could not find symbol '%s' in loaded module\n", sym_name); yading@10: return sym; yading@10: } yading@10: yading@10: static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, char *param) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: union { yading@10: double d; yading@10: f0r_param_color_t col; yading@10: f0r_param_position_t pos; yading@10: } val; yading@10: char *tail; yading@10: uint8_t rgba[4]; yading@10: yading@10: switch (info.type) { yading@10: case F0R_PARAM_BOOL: yading@10: if (!strcmp(param, "y")) val.d = 1.0; yading@10: else if (!strcmp(param, "n")) val.d = 0.0; yading@10: else goto fail; yading@10: break; yading@10: yading@10: case F0R_PARAM_DOUBLE: yading@10: val.d = strtod(param, &tail); yading@10: if (*tail || val.d == HUGE_VAL) yading@10: goto fail; yading@10: break; yading@10: yading@10: case F0R_PARAM_COLOR: yading@10: if (sscanf(param, "%f/%f/%f", &val.col.r, &val.col.g, &val.col.b) != 3) { yading@10: if (av_parse_color(rgba, param, -1, ctx) < 0) yading@10: goto fail; yading@10: val.col.r = rgba[0] / 255.0; yading@10: val.col.g = rgba[1] / 255.0; yading@10: val.col.b = rgba[2] / 255.0; yading@10: } yading@10: break; yading@10: yading@10: case F0R_PARAM_POSITION: yading@10: if (sscanf(param, "%lf/%lf", &val.pos.x, &val.pos.y) != 2) yading@10: goto fail; yading@10: break; yading@10: } yading@10: yading@10: frei0r->set_param_value(frei0r->instance, &val, index); yading@10: return 0; yading@10: yading@10: fail: yading@10: av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for parameter '%s'\n", yading@10: param, info.name); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: static int set_params(AVFilterContext *ctx, const char *params) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: int i; yading@10: yading@10: for (i = 0; i < frei0r->plugin_info.num_params; i++) { yading@10: f0r_param_info_t info; yading@10: char *param; yading@10: int ret; yading@10: yading@10: frei0r->get_param_info(&info, i); yading@10: yading@10: if (*params) { yading@10: if (!(param = av_get_token(¶ms, "|"))) yading@10: return AVERROR(ENOMEM); yading@10: params++; /* skip ':' */ yading@10: ret = set_param(ctx, info, i, param); yading@10: av_free(param); yading@10: if (ret < 0) yading@10: return ret; yading@10: } yading@10: yading@10: av_log(ctx, AV_LOG_VERBOSE, yading@10: "idx:%d name:'%s' type:%s explanation:'%s' ", yading@10: i, info.name, yading@10: info.type == F0R_PARAM_BOOL ? "bool" : yading@10: info.type == F0R_PARAM_DOUBLE ? "double" : yading@10: info.type == F0R_PARAM_COLOR ? "color" : yading@10: info.type == F0R_PARAM_POSITION ? "position" : yading@10: info.type == F0R_PARAM_STRING ? "string" : "unknown", yading@10: info.explanation); yading@10: yading@10: #ifdef DEBUG yading@10: av_log(ctx, AV_LOG_DEBUG, "value:"); yading@10: switch (info.type) { yading@10: void *v; yading@10: double d; yading@10: char s[128]; yading@10: f0r_param_color_t col; yading@10: f0r_param_position_t pos; yading@10: yading@10: case F0R_PARAM_BOOL: yading@10: v = &d; yading@10: frei0r->get_param_value(frei0r->instance, v, i); yading@10: av_log(ctx, AV_LOG_DEBUG, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n"); yading@10: break; yading@10: case F0R_PARAM_DOUBLE: yading@10: v = &d; yading@10: frei0r->get_param_value(frei0r->instance, v, i); yading@10: av_log(ctx, AV_LOG_DEBUG, "%f", d); yading@10: break; yading@10: case F0R_PARAM_COLOR: yading@10: v = &col; yading@10: frei0r->get_param_value(frei0r->instance, v, i); yading@10: av_log(ctx, AV_LOG_DEBUG, "%f/%f/%f", col.r, col.g, col.b); yading@10: break; yading@10: case F0R_PARAM_POSITION: yading@10: v = &pos; yading@10: frei0r->get_param_value(frei0r->instance, v, i); yading@10: av_log(ctx, AV_LOG_DEBUG, "%f/%f", pos.x, pos.y); yading@10: break; yading@10: default: /* F0R_PARAM_STRING */ yading@10: v = s; yading@10: frei0r->get_param_value(frei0r->instance, v, i); yading@10: av_log(ctx, AV_LOG_DEBUG, "'%s'\n", s); yading@10: break; yading@10: } yading@10: #endif yading@10: av_log(ctx, AV_LOG_VERBOSE, "\n"); yading@10: } yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: static int load_path(AVFilterContext *ctx, void **handle_ptr, const char *prefix, const char *name) yading@10: { yading@10: char *path = av_asprintf("%s%s%s", prefix, name, SLIBSUF); yading@10: if (!path) yading@10: return AVERROR(ENOMEM); yading@10: av_log(ctx, AV_LOG_DEBUG, "Looking for frei0r effect in '%s'\n", path); yading@10: *handle_ptr = dlopen(path, RTLD_NOW|RTLD_LOCAL); yading@10: av_free(path); yading@10: return 0; yading@10: } yading@10: yading@10: static av_cold int frei0r_init(AVFilterContext *ctx, yading@10: const char *dl_name, int type) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: f0r_init_f f0r_init; yading@10: f0r_get_plugin_info_f f0r_get_plugin_info; yading@10: f0r_plugin_info_t *pi; yading@10: char *path; yading@10: int ret = 0; yading@10: yading@10: if (!dl_name) { yading@10: av_log(ctx, AV_LOG_ERROR, "No filter name provided.\n"); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: /* see: http://frei0r.dyne.org/codedoc/html/group__pluglocations.html */ yading@10: if ((path = av_strdup(getenv("FREI0R_PATH")))) { yading@10: #ifdef _WIN32 yading@10: const char *separator = ";"; yading@10: #else yading@10: const char *separator = ":"; yading@10: #endif yading@10: char *p, *ptr = NULL; yading@10: for (p = path; p = av_strtok(p, separator, &ptr); p = NULL) { yading@10: /* add additional trailing slash in case it is missing */ yading@10: char *p1 = av_asprintf("%s/", p); yading@10: if (!p1) { yading@10: ret = AVERROR(ENOMEM); yading@10: goto check_path_end; yading@10: } yading@10: ret = load_path(ctx, &frei0r->dl_handle, p1, dl_name); yading@10: av_free(p1); yading@10: if (ret < 0) yading@10: goto check_path_end; yading@10: if (frei0r->dl_handle) yading@10: break; yading@10: } yading@10: yading@10: check_path_end: yading@10: av_free(path); yading@10: if (ret < 0) yading@10: return ret; yading@10: } yading@10: if (!frei0r->dl_handle && (path = getenv("HOME"))) { yading@10: char *prefix = av_asprintf("%s/.frei0r-1/lib/", path); yading@10: if (!prefix) yading@10: return AVERROR(ENOMEM); yading@10: ret = load_path(ctx, &frei0r->dl_handle, prefix, dl_name); yading@10: av_free(prefix); yading@10: if (ret < 0) yading@10: return ret; yading@10: } yading@10: if (!frei0r->dl_handle) { yading@10: ret = load_path(ctx, &frei0r->dl_handle, "/usr/local/lib/frei0r-1/", dl_name); yading@10: if (ret < 0) yading@10: return ret; yading@10: } yading@10: if (!frei0r->dl_handle) { yading@10: ret = load_path(ctx, &frei0r->dl_handle, "/usr/lib/frei0r-1/", dl_name); yading@10: if (ret < 0) yading@10: return ret; yading@10: } yading@10: if (!frei0r->dl_handle) { yading@10: av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'\n", dl_name); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: if (!(f0r_init = load_sym(ctx, "f0r_init" )) || yading@10: !(f0r_get_plugin_info = load_sym(ctx, "f0r_get_plugin_info")) || yading@10: !(frei0r->get_param_info = load_sym(ctx, "f0r_get_param_info" )) || yading@10: !(frei0r->get_param_value = load_sym(ctx, "f0r_get_param_value")) || yading@10: !(frei0r->set_param_value = load_sym(ctx, "f0r_set_param_value")) || yading@10: !(frei0r->update = load_sym(ctx, "f0r_update" )) || yading@10: !(frei0r->construct = load_sym(ctx, "f0r_construct" )) || yading@10: !(frei0r->destruct = load_sym(ctx, "f0r_destruct" )) || yading@10: !(frei0r->deinit = load_sym(ctx, "f0r_deinit" ))) yading@10: return AVERROR(EINVAL); yading@10: yading@10: if (f0r_init() < 0) { yading@10: av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module\n"); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: f0r_get_plugin_info(&frei0r->plugin_info); yading@10: pi = &frei0r->plugin_info; yading@10: if (pi->plugin_type != type) { yading@10: av_log(ctx, AV_LOG_ERROR, yading@10: "Invalid type '%s' for the plugin\n", yading@10: pi->plugin_type == F0R_PLUGIN_TYPE_FILTER ? "filter" : yading@10: pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" : yading@10: pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" : yading@10: pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown"); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: av_log(ctx, AV_LOG_VERBOSE, yading@10: "name:%s author:'%s' explanation:'%s' color_model:%s " yading@10: "frei0r_version:%d version:%d.%d num_params:%d\n", yading@10: pi->name, pi->author, pi->explanation, yading@10: pi->color_model == F0R_COLOR_MODEL_BGRA8888 ? "bgra8888" : yading@10: pi->color_model == F0R_COLOR_MODEL_RGBA8888 ? "rgba8888" : yading@10: pi->color_model == F0R_COLOR_MODEL_PACKED32 ? "packed32" : "unknown", yading@10: pi->frei0r_version, pi->major_version, pi->minor_version, pi->num_params); yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: static av_cold int filter_init(AVFilterContext *ctx) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: yading@10: return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_FILTER); yading@10: } yading@10: yading@10: static av_cold void uninit(AVFilterContext *ctx) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: yading@10: if (frei0r->destruct && frei0r->instance) yading@10: frei0r->destruct(frei0r->instance); yading@10: if (frei0r->deinit) yading@10: frei0r->deinit(); yading@10: if (frei0r->dl_handle) yading@10: dlclose(frei0r->dl_handle); yading@10: } yading@10: yading@10: static int config_input_props(AVFilterLink *inlink) yading@10: { yading@10: AVFilterContext *ctx = inlink->dst; yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: yading@10: if (!(frei0r->instance = frei0r->construct(inlink->w, inlink->h))) { yading@10: av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n"); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: return set_params(ctx, frei0r->params); yading@10: } yading@10: yading@10: static int query_formats(AVFilterContext *ctx) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: AVFilterFormats *formats = NULL; yading@10: yading@10: if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) { yading@10: ff_add_format(&formats, AV_PIX_FMT_BGRA); yading@10: } else if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) { yading@10: ff_add_format(&formats, AV_PIX_FMT_RGBA); yading@10: } else { /* F0R_COLOR_MODEL_PACKED32 */ yading@10: static const enum AVPixelFormat pix_fmts[] = { yading@10: AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_ARGB, AV_PIX_FMT_NONE yading@10: }; yading@10: formats = ff_make_format_list(pix_fmts); yading@10: } yading@10: yading@10: if (!formats) yading@10: return AVERROR(ENOMEM); yading@10: yading@10: ff_set_common_formats(ctx, formats); yading@10: return 0; yading@10: } yading@10: yading@10: static int filter_frame(AVFilterLink *inlink, AVFrame *in) yading@10: { yading@10: Frei0rContext *frei0r = inlink->dst->priv; yading@10: AVFilterLink *outlink = inlink->dst->outputs[0]; yading@10: AVFrame *out; yading@10: yading@10: out = ff_get_video_buffer(outlink, outlink->w, outlink->h); yading@10: if (!out) { yading@10: av_frame_free(&in); yading@10: return AVERROR(ENOMEM); yading@10: } yading@10: av_frame_copy_props(out, in); yading@10: yading@10: frei0r->update(frei0r->instance, in->pts * av_q2d(inlink->time_base) * 1000, yading@10: (const uint32_t *)in->data[0], yading@10: (uint32_t *)out->data[0]); yading@10: yading@10: av_frame_free(&in); yading@10: yading@10: return ff_filter_frame(outlink, out); yading@10: } yading@10: yading@10: #define OFFSET(x) offsetof(Frei0rContext, x) yading@10: #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM yading@10: static const AVOption filter_options[] = { yading@10: { "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, yading@10: { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, yading@10: { NULL }, yading@10: }; yading@10: yading@10: static const AVClass filter_class = { yading@10: .class_name = "frei0r", yading@10: .item_name = av_default_item_name, yading@10: .option = filter_options, yading@10: .version = LIBAVUTIL_VERSION_INT, yading@10: }; yading@10: yading@10: static const AVFilterPad avfilter_vf_frei0r_inputs[] = { yading@10: { yading@10: .name = "default", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: .config_props = config_input_props, yading@10: .filter_frame = filter_frame, yading@10: }, yading@10: { NULL } yading@10: }; yading@10: yading@10: static const AVFilterPad avfilter_vf_frei0r_outputs[] = { yading@10: { yading@10: .name = "default", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: }, yading@10: { NULL } yading@10: }; yading@10: yading@10: AVFilter avfilter_vf_frei0r = { yading@10: .name = "frei0r", yading@10: .description = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."), yading@10: yading@10: .query_formats = query_formats, yading@10: .init = filter_init, yading@10: .uninit = uninit, yading@10: yading@10: .priv_size = sizeof(Frei0rContext), yading@10: .priv_class = &filter_class, yading@10: yading@10: .inputs = avfilter_vf_frei0r_inputs, yading@10: yading@10: .outputs = avfilter_vf_frei0r_outputs, yading@10: }; yading@10: yading@10: static av_cold int source_init(AVFilterContext *ctx) yading@10: { yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: AVRational frame_rate_q; yading@10: yading@10: if (av_parse_video_size(&frei0r->w, &frei0r->h, frei0r->size) < 0) { yading@10: av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frei0r->size); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: if (av_parse_video_rate(&frame_rate_q, frei0r->framerate) < 0) { yading@10: av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frei0r->framerate); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: frei0r->time_base.num = frame_rate_q.den; yading@10: frei0r->time_base.den = frame_rate_q.num; yading@10: yading@10: return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_SOURCE); yading@10: } yading@10: yading@10: static int source_config_props(AVFilterLink *outlink) yading@10: { yading@10: AVFilterContext *ctx = outlink->src; yading@10: Frei0rContext *frei0r = ctx->priv; yading@10: yading@10: if (av_image_check_size(frei0r->w, frei0r->h, 0, ctx) < 0) yading@10: return AVERROR(EINVAL); yading@10: outlink->w = frei0r->w; yading@10: outlink->h = frei0r->h; yading@10: outlink->time_base = frei0r->time_base; yading@10: outlink->sample_aspect_ratio = (AVRational){1,1}; yading@10: yading@10: if (!(frei0r->instance = frei0r->construct(outlink->w, outlink->h))) { yading@10: av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n"); yading@10: return AVERROR(EINVAL); yading@10: } yading@10: yading@10: return set_params(ctx, frei0r->params); yading@10: } yading@10: yading@10: static int source_request_frame(AVFilterLink *outlink) yading@10: { yading@10: Frei0rContext *frei0r = outlink->src->priv; yading@10: AVFrame *frame = ff_get_video_buffer(outlink, outlink->w, outlink->h); yading@10: yading@10: if (!frame) yading@10: return AVERROR(ENOMEM); yading@10: yading@10: frame->sample_aspect_ratio = (AVRational) {1, 1}; yading@10: frame->pts = frei0r->pts++; yading@10: yading@10: frei0r->update(frei0r->instance, av_rescale_q(frame->pts, frei0r->time_base, (AVRational){1,1000}), yading@10: NULL, (uint32_t *)frame->data[0]); yading@10: yading@10: return ff_filter_frame(outlink, frame); yading@10: } yading@10: yading@10: static const AVOption src_options[] = { yading@10: { "size", "Dimensions of the generated video.", OFFSET(size), AV_OPT_TYPE_STRING, { .str = "" }, .flags = FLAGS }, yading@10: { "framerate", NULL, OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = FLAGS }, yading@10: { "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, yading@10: { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, yading@10: { NULL }, yading@10: }; yading@10: yading@10: static const AVClass src_class = { yading@10: .class_name = "frei0r_src", yading@10: .item_name = av_default_item_name, yading@10: .option = src_options, yading@10: .version = LIBAVUTIL_VERSION_INT, yading@10: }; yading@10: yading@10: static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = { yading@10: { yading@10: .name = "default", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: .request_frame = source_request_frame, yading@10: .config_props = source_config_props yading@10: }, yading@10: { NULL } yading@10: }; yading@10: yading@10: AVFilter avfilter_vsrc_frei0r_src = { yading@10: .name = "frei0r_src", yading@10: .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."), yading@10: yading@10: .priv_size = sizeof(Frei0rContext), yading@10: .priv_class = &src_class, yading@10: .init = source_init, yading@10: .uninit = uninit, yading@10: yading@10: .query_formats = query_formats, yading@10: yading@10: .inputs = NULL, yading@10: yading@10: .outputs = avfilter_vsrc_frei0r_src_outputs, yading@10: };