static int source_config_props(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; Frei0rContext *s = ctx->priv; if (av_image_check_size(s->w, s->h, 0, ctx) < 0) return AVERROR(EINVAL); outlink->w = s->w; outlink->h = s->h; outlink->time_base = s->time_base; outlink->frame_rate = av_inv_q(s->time_base); if (s->destruct && s->instance) s->destruct(s->instance); if (!(s->instance = s->construct(outlink->w, outlink->h))) { av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance.\n"); return AVERROR(EINVAL); } if (!s->params) { av_log(ctx, AV_LOG_ERROR, "frei0r filter parameters not set.\n"); return AVERROR(EINVAL); } return set_params(ctx, s->params); }
static av_cold void uninit(AVFilterContext *ctx) { Frei0rContext *s = ctx->priv; if (s->destruct && s->instance) s->destruct(s->instance); if (s->deinit) s->deinit(); if (s->dl_handle) dlclose(s->dl_handle); }
static int config_input_props(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; Frei0rContext *s = ctx->priv; if (s->destruct && s->instance) s->destruct(s->instance); if (!(s->instance = s->construct(inlink->w, inlink->h))) { av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance.\n"); return AVERROR(EINVAL); } return set_params(ctx, s->params); }
static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, char *param) { Frei0rContext *s = ctx->priv; union { double d; f0r_param_color_t col; f0r_param_position_t pos; } val; char *tail; uint8_t rgba[4]; switch (info.type) { case F0R_PARAM_BOOL: if (!strcmp(param, "y")) val.d = 1.0; else if (!strcmp(param, "n")) val.d = 0.0; else goto fail; break; case F0R_PARAM_DOUBLE: val.d = strtod(param, &tail); if (*tail || val.d == HUGE_VAL) goto fail; break; case F0R_PARAM_COLOR: if (sscanf(param, "%f/%f/%f", &val.col.r, &val.col.g, &val.col.b) != 3) { if (av_parse_color(rgba, param, -1, ctx) < 0) goto fail; val.col.r = rgba[0] / 255.0; val.col.g = rgba[1] / 255.0; val.col.b = rgba[2] / 255.0; } break; case F0R_PARAM_POSITION: if (sscanf(param, "%lf/%lf", &val.pos.x, &val.pos.y) != 2) goto fail; break; } s->set_param_value(s->instance, &val, index); return 0; fail: av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for parameter '%s'.\n", param, info.name); return AVERROR(EINVAL); }
static int source_request_frame(AVFilterLink *outlink) { Frei0rContext *s = outlink->src->priv; AVFrame *frame = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!frame) return AVERROR(ENOMEM); frame->sample_aspect_ratio = (AVRational) {1, 1}; frame->pts = s->pts++; s->update(s->instance, av_rescale_q(frame->pts, s->time_base, (AVRational){1,1000}), NULL, (uint32_t *)frame->data[0]); return ff_filter_frame(outlink, frame); }
static int filter_frame(AVFilterLink *inlink, AVFrame *in) { Frei0rContext *s = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; AVFrame *out; 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); s->update(s->instance, in->pts * av_q2d(inlink->time_base) * 1000, (const uint32_t *)in->data[0], (uint32_t *)out->data[0]); av_frame_free(&in); return ff_filter_frame(outlink, out); }
static int set_params(AVFilterContext *ctx, const char *params) { Frei0rContext *s = ctx->priv; int i; for (i = 0; i < s->plugin_info.num_params; i++) { f0r_param_info_t info; char *param; int ret; s->get_param_info(&info, i); if (*params) { if (!(param = av_get_token(¶ms, "|"))) return AVERROR(ENOMEM); params++; /* skip ':' */ ret = set_param(ctx, info, i, param); av_free(param); if (ret < 0) return ret; } av_log(ctx, AV_LOG_VERBOSE, "idx:%d name:'%s' type:%s explanation:'%s' ", i, info.name, info.type == F0R_PARAM_BOOL ? "bool" : info.type == F0R_PARAM_DOUBLE ? "double" : info.type == F0R_PARAM_COLOR ? "color" : info.type == F0R_PARAM_POSITION ? "position" : info.type == F0R_PARAM_STRING ? "string" : "unknown", info.explanation); #ifdef DEBUG av_log(ctx, AV_LOG_DEBUG, "value:"); switch (info.type) { void *v; double d; char s[128]; f0r_param_color_t col; f0r_param_position_t pos; case F0R_PARAM_BOOL: v = &d; s->get_param_value(s->instance, v, i); av_log(ctx, AV_LOG_DEBUG, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n"); break; case F0R_PARAM_DOUBLE: v = &d; s->get_param_value(s->instance, v, i); av_log(ctx, AV_LOG_DEBUG, "%f", d); break; case F0R_PARAM_COLOR: v = &col; s->get_param_value(s->instance, v, i); av_log(ctx, AV_LOG_DEBUG, "%f/%f/%f", col.r, col.g, col.b); break; case F0R_PARAM_POSITION: v = &pos; s->get_param_value(s->instance, v, i); av_log(ctx, AV_LOG_DEBUG, "%f/%f", pos.x, pos.y); break; default: /* F0R_PARAM_STRING */ v = s; s->get_param_value(s->instance, v, i); av_log(ctx, AV_LOG_DEBUG, "'%s'", s); break; } #endif av_log(ctx, AV_LOG_VERBOSE, ".\n"); } return 0; }