static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; ZPContext *s = ctx->priv; int ret; outlink->w = s->w; outlink->h = s->h; outlink->time_base = av_inv_q(s->framerate); outlink->frame_rate = s->framerate; s->desc = av_pix_fmt_desc_get(outlink->format); ret = av_expr_parse(&s->zoom_expr, s->zoom_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) return ret; ret = av_expr_parse(&s->x_expr, s->x_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) return ret; ret = av_expr_parse(&s->y_expr, s->y_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) return ret; return 0; }
static av_cold int init(AVFilterContext *ctx) { SelectContext *select = ctx->priv; int i, ret; if ((ret = av_expr_parse(&select->expr, select->expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", select->expr_str); return ret; } select->do_scene_detect = !!strstr(select->expr_str, "scene"); for (i = 0; i < select->nb_outputs; i++) { AVFilterPad pad = { 0 }; pad.name = av_asprintf("output%d", i); if (!pad.name) return AVERROR(ENOMEM); pad.type = ctx->filter->inputs[0].type; pad.request_frame = request_frame; ff_insert_outpad(ctx, i, &pad); } return 0; }
//===========================================================================// static int vf_open(vf_instance_t *vf, char *args) { char eq[3][2000] = { { 0 }, { 0 }, { 0 } }; int plane, res; vf->config=config; vf->put_image=put_image; // vf->get_image=get_image; vf->uninit=uninit; vf->priv=av_malloc(sizeof(struct vf_priv_s)); memset(vf->priv, 0, sizeof(struct vf_priv_s)); if (args) sscanf(args, "%1999[^:]:%1999[^:]:%1999[^:]", eq[0], eq[1], eq[2]); if (!eq[1][0]) strncpy(eq[1], eq[0], sizeof(eq[0])-1); if (!eq[2][0]) strncpy(eq[2], eq[1], sizeof(eq[0])-1); for(plane=0; plane<3; plane++) { static const char *const_names[]= { "PI", "E", "X", "Y", "W", "H", "N", "SW", "SH", NULL }; static const char *func2_names[]= { "lum", "cb", "cr", "p", NULL }; double (*func2[])(void *, double, double)= { lum, cb, cr, plane==0 ? lum : (plane==1 ? cb : cr), NULL }; res = av_expr_parse(&vf->priv->e[plane], eq[plane], const_names, NULL, NULL, func2_names, func2, 0, NULL); if (res < 0) { mp_msg(MSGT_VFILTER, MSGL_ERR, "geq: error loading equation `%s'\n", eq[plane]); return 0; } } return 1; }
static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; DrawTextContext *s = ctx->priv; int ret; ff_draw_init(&s->dc, inlink->format, FF_DRAW_PROCESS_ALPHA); ff_draw_color(&s->dc, &s->fontcolor, s->fontcolor.rgba); ff_draw_color(&s->dc, &s->shadowcolor, s->shadowcolor.rgba); ff_draw_color(&s->dc, &s->bordercolor, s->bordercolor.rgba); ff_draw_color(&s->dc, &s->boxcolor, s->boxcolor.rgba); s->var_values[VAR_w] = s->var_values[VAR_W] = s->var_values[VAR_MAIN_W] = inlink->w; s->var_values[VAR_h] = s->var_values[VAR_H] = s->var_values[VAR_MAIN_H] = inlink->h; s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1; s->var_values[VAR_DAR] = (double)inlink->w / inlink->h * s->var_values[VAR_SAR]; s->var_values[VAR_HSUB] = 1 << s->dc.hsub_max; s->var_values[VAR_VSUB] = 1 << s->dc.vsub_max; s->var_values[VAR_X] = NAN; s->var_values[VAR_Y] = NAN; s->var_values[VAR_T] = NAN; av_lfg_init(&s->prng, av_get_random_seed()); av_expr_free(s->x_pexpr); av_expr_free(s->y_pexpr); s->x_pexpr = s->y_pexpr = NULL; if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names, NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 || (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names, NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 || (ret = av_expr_parse(&s->a_pexpr, s->a_expr, var_names, NULL, NULL, fun2_names, fun2, 0, ctx)) < 0) return AVERROR(EINVAL); return 0; }
static av_cold int init(AVFilterContext *ctx) { ShowVolumeContext *s = ctx->priv; int ret; if (s->color) { ret = av_expr_parse(&s->c_expr, s->color, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) return ret; } return 0; }
static av_cold int init(AVFilterContext *ctx, const char *args0) { AStreamSyncContext *as = ctx->priv; const char *expr = args0 ? args0 : default_expr; int r, i; r = av_expr_parse(&as->expr, expr, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (r < 0) { av_log(ctx, AV_LOG_ERROR, "Error in expression \"%s\"\n", expr); return r; } for (i = 0; i < 42; i++) av_expr_eval(as->expr, as->var_values, NULL); /* exercize prng */ return 0; }
static av_cold int init(AVFilterContext *ctx, const char *args) { SetPTSContext *setpts = ctx->priv; int ret; if ((ret = av_expr_parse(&setpts->expr, args ? args : "PTS", var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args); return ret; } setpts->var_values[VAR_N ] = 0.0; setpts->var_values[VAR_PREV_INPTS ] = NAN; setpts->var_values[VAR_PREV_OUTPTS] = NAN; setpts->var_values[VAR_STARTPTS ] = NAN; return 0; }
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) { SelectContext *select = ctx->priv; int ret; if ((ret = av_expr_parse(&select->expr, args ? args : "1", var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args); return ret; } select->pending_frames = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*)); if (!select->pending_frames) { av_log(ctx, AV_LOG_ERROR, "Failed to allocate pending frames buffer.\n"); return AVERROR(ENOMEM); } return 0; }
static int set_expr(AVExpr **pexpr, const char *expr, void *log_ctx) { int ret; AVExpr *old = NULL; if (*pexpr) old = *pexpr; ret = av_expr_parse(pexpr, expr, var_names, NULL, NULL, NULL, NULL, 0, log_ctx); if (ret < 0) { av_log(log_ctx, AV_LOG_ERROR, "Error when evaluating the volume expression '%s'\n", expr); *pexpr = old; return ret; } av_expr_free(old); return 0; }
static int set_enable_expr(AVFilterContext *ctx, const char *expr) { int ret; char *expr_dup; AVExpr *old = ctx->enable; if (!(ctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)) { av_log(ctx, AV_LOG_ERROR, "Timeline ('enable' option) not supported " "with filter '%s'\n", ctx->filter->name); return AVERROR_PATCHWELCOME; } expr_dup = av_strdup(expr); if (!expr_dup) return AVERROR(ENOMEM); if (!ctx->var_values) { ctx->var_values = av_calloc(VAR_VARS_NB, sizeof(*ctx->var_values)); if (!ctx->var_values) { av_free(expr_dup); return AVERROR(ENOMEM); } } ret = av_expr_parse((AVExpr**)&ctx->enable, expr_dup, var_names, NULL, NULL, NULL, NULL, 0, ctx->priv); if (ret < 0) { av_log(ctx->priv, AV_LOG_ERROR, "Error when evaluating the expression '%s' for enable\n", expr_dup); av_free(expr_dup); return ret; } av_expr_free(old); av_free(ctx->enable_str); ctx->enable_str = expr_dup; return 0; }
static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; QPContext *s = ctx->priv; int i; int ret; AVExpr *e = NULL; static const char *var_names[] = { "known", "qp", "x", "y", "w", "h", NULL }; if (!s->qp_expr_str) return 0; ret = av_expr_parse(&e, s->qp_expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) return ret; s->h = (inlink->h + 15) >> 4; s->qstride = (inlink->w + 15) >> 4; for (i = -129; i < 128; i++) { double var_values[] = { i != -129, i, NAN, NAN, s->qstride, s->h, 0}; double temp_val = av_expr_eval(e, var_values, NULL); if (isnan(temp_val)) { if(strchr(s->qp_expr_str, 'x') || strchr(s->qp_expr_str, 'y')) s->evaluate_per_mb = 1; else { av_expr_free(e); return AVERROR(EINVAL); } } s->lut[i + 129] = lrintf(temp_val); } av_expr_free(e); return 0; }
static av_cold int init(AVFilterContext *ctx) { DrawGraphContext *s = ctx->priv; int ret, i; if (s->max <= s->min) { av_log(ctx, AV_LOG_ERROR, "max is same or lower than min\n"); return AVERROR(EINVAL); } for (i = 0; i < 4; i++) { if (s->fg_str[i]) { ret = av_expr_parse(&s->fg_expr[i], s->fg_str[i], var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) return ret; } } s->first = 1; return 0; }
static av_cold int init(AVFilterContext *ctx, const char *args) { SelectContext *select = ctx->priv; int ret; if ((ret = av_expr_parse(&select->expr, args ? args : "1", var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args); return ret; } select->pending_frames = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*)); if (!select->pending_frames) { av_log(ctx, AV_LOG_ERROR, "Failed to allocate pending frames buffer.\n"); return AVERROR(ENOMEM); } select->do_scene_detect = args && strstr(args, "scene"); if (select->do_scene_detect && !CONFIG_AVCODEC) { av_log(ctx, AV_LOG_ERROR, "Scene detection is not available without libavcodec.\n"); return AVERROR(EINVAL); } return 0; }
av_cold int ff_rate_control_init(MpegEncContext *s) { RateControlContext *rcc = &s->rc_context; int i, res; static const char * const const_names[] = { "PI", "E", "iTex", "pTex", "tex", "mv", "fCode", "iCount", "mcVar", "var", "isI", "isP", "isB", "avgQP", "qComp", #if 0 "lastIQP", "lastPQP", "lastBQP", "nextNonBQP", #endif "avgIITex", "avgPITex", "avgPPTex", "avgBPTex", "avgTex", NULL }; static double (* const func1[])(void *, double) = { (void *)bits2qp, (void *)qp2bits, NULL }; static const char * const func1_names[] = { "bits2qp", "qp2bits", NULL }; emms_c(); if (!s->avctx->rc_max_available_vbv_use && s->avctx->rc_buffer_size) { if (s->avctx->rc_max_rate) { s->avctx->rc_max_available_vbv_use = av_clipf(s->avctx->rc_max_rate/(s->avctx->rc_buffer_size*get_fps(s->avctx)), 1.0/3, 1.0); } else s->avctx->rc_max_available_vbv_use = 1.0; } res = av_expr_parse(&rcc->rc_eq_eval, s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx); if (res < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq); return res; } for (i = 0; i < 5; i++) { rcc->pred[i].coeff = FF_QP2LAMBDA * 7.0; rcc->pred[i].count = 1.0; rcc->pred[i].decay = 0.4; rcc->i_cplx_sum [i] = rcc->p_cplx_sum [i] = rcc->mv_bits_sum[i] = rcc->qscale_sum [i] = rcc->frame_count[i] = 1; // 1 is better because of 1/0 and such rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5; } rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy; if (!rcc->buffer_index) rcc->buffer_index = s->avctx->rc_buffer_size * 3 / 4; if (s->flags & CODEC_FLAG_PASS2) { int i; char *p; /* find number of pics */ p = s->avctx->stats_in; for (i = -1; p; i++) p = strchr(p + 1, ';'); i += s->max_b_frames; if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry)) return -1; rcc->entry = av_mallocz(i * sizeof(RateControlEntry)); rcc->num_entries = i; /* init all to skipped p frames * (with b frames we might have a not encoded frame at the end FIXME) */ for (i = 0; i < rcc->num_entries; i++) { RateControlEntry *rce = &rcc->entry[i]; rce->pict_type = rce->new_pict_type = AV_PICTURE_TYPE_P; rce->qscale = rce->new_qscale = FF_QP2LAMBDA * 2; rce->misc_bits = s->mb_num + 10; rce->mb_var_sum = s->mb_num * 100; } /* read stats */ p = s->avctx->stats_in; for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) { RateControlEntry *rce; int picture_number; int e; char *next; next = strchr(p, ';'); if (next) { (*next) = 0; // sscanf in unbelievably slow on looong strings // FIXME copy / do not write next++; } e = sscanf(p, " in:%d ", &picture_number); assert(picture_number >= 0); assert(picture_number < rcc->num_entries); rce = &rcc->entry[picture_number]; e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%"SCNd64" var:%"SCNd64" icount:%d skipcount:%d hbits:%d", &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits, &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits); if (e != 14) { av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e); return -1; } p = next; } if (init_pass2(s) < 0) return -1; // FIXME maybe move to end if ((s->flags & CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) { #if CONFIG_LIBXVID return ff_xvid_rate_control_init(s); #else av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n"); return -1; #endif } } if (!(s->flags & CODEC_FLAG_PASS2)) { rcc->short_term_qsum = 0.001; rcc->short_term_qcount = 0.001; rcc->pass1_rc_eq_output_sum = 0.001; rcc->pass1_wanted_bits = 0.001; if (s->avctx->qblur > 1.0) { av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n"); return -1; } /* init stuff with the user specified complexity */ if (s->avctx->rc_initial_cplx) { for (i = 0; i < 60 * 30; i++) { double bits = s->avctx->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num; RateControlEntry rce; if (i % ((s->gop_size + 3) / 4) == 0) rce.pict_type = AV_PICTURE_TYPE_I; else if (i % (s->max_b_frames + 1)) rce.pict_type = AV_PICTURE_TYPE_B; else rce.pict_type = AV_PICTURE_TYPE_P; rce.new_pict_type = rce.pict_type; rce.mc_mb_var_sum = bits * s->mb_num / 100000; rce.mb_var_sum = s->mb_num; rce.qscale = FF_QP2LAMBDA * 2; rce.f_code = 2; rce.b_code = 1; rce.misc_bits = 1; if (s->pict_type == AV_PICTURE_TYPE_I) { rce.i_count = s->mb_num; rce.i_tex_bits = bits; rce.p_tex_bits = 0; rce.mv_bits = 0; } else { rce.i_count = 0; // FIXME we do know this approx rce.i_tex_bits = 0; rce.p_tex_bits = bits * 0.9; rce.mv_bits = bits * 0.1; } rcc->i_cplx_sum[rce.pict_type] += rce.i_tex_bits * rce.qscale; rcc->p_cplx_sum[rce.pict_type] += rce.p_tex_bits * rce.qscale; rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits; rcc->frame_count[rce.pict_type]++; get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i); // FIXME misbehaves a little for variable fps rcc->pass1_wanted_bits += s->bit_rate / get_fps(s->avctx); } } } return 0; }
int rotate_filter_frame(RotContext *rot, AVFrame *in,int frame_count_out, AVFrame* &out) { int angle_int, s, c, plane; double res; rot->var_values[ROTATE_VAR_N] = frame_count_out; rot->var_values[ROTATE_VAR_T] = 0;//TS2T(in->pts, inlink->time_base); rot->angle = res = av_expr_eval(rot->angle_expr, rot->var_values, rot); av_log(NULL, AV_LOG_DEBUG, "n:%f time:%f angle:%f/PI\n", rot->var_values[ROTATE_VAR_N], rot->var_values[ROTATE_VAR_T], rot->angle/M_PI); qDebug()<<"rotate_filter_frame n:"<<rot->var_values[ROTATE_VAR_N] <<" time:"<< rot->var_values[ROTATE_VAR_T] <<" angle(/PI): "<<(rot->angle/M_PI); angle_int = res * FIXP * 16; s = int_sin(angle_int); c = int_sin(angle_int + INT_PI/2); /* fill background */ if (rot->fillcolor_enable) ff_fill_rectangle(&rot->draw, &rot->color, out->data, out->linesize, 0, 0, out->width, out->height); for (plane = 0; plane < rot->nb_planes; plane++) { int hsub = plane == 1 || plane == 2 ? rot->hsub : 0; int vsub = plane == 1 || plane == 2 ? rot->vsub : 0; const int outw = AV_CEIL_RSHIFT(out->width, hsub); const int outh = AV_CEIL_RSHIFT(out->height, vsub); #if 0 ThreadData td = { .in = in, .out = out, .inw = AV_CEIL_RSHIFT(in->width, hsub), .inh = AV_CEIL_RSHIFT(in->height, vsub), .outh = outh, .outw = outw, .xi = -(outw-1) * c / 2, .yi = (outw-1) * s / 2, .xprime = -(outh-1) * s / 2, .yprime = -(outh-1) * c / 2, .plane = plane, .c = c, .s = s }; #endif ThreadData td; td.in = in; td.out = out; td.inw = AV_CEIL_RSHIFT(in->width, hsub); td.inh = AV_CEIL_RSHIFT(in->height, vsub); td.outh = outh; td.outw = outw; td.xi = -(outw-1) * c / 2; td.yi = (outw-1) * s / 2; td.xprime = -(outh-1) * s / 2; td.yprime = -(outh-1) * c / 2; td.plane = plane; td.c = c; td.s = s; filter_slice(rot, &td, 0, 1); } return 0; } int rotate_config_props(RotContext *rot, AVFrame *in) { const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get((AVPixelFormat)in->format); int ret; double res; char *expr; qDebug()<<"rotate_config_props foramt: "<<in->format; ff_draw_init(&rot->draw, (AVPixelFormat)in->format, 0); ff_draw_color(&rot->draw, &rot->color, rot->fillcolor); rot->hsub = pixdesc->log2_chroma_w; rot->vsub = pixdesc->log2_chroma_h; if (pixdesc->comp[0].depth == 8) rot->interpolate_bilinear = interpolate_bilinear8; else rot->interpolate_bilinear = interpolate_bilinear16; rot->var_values[ROTATE_VAR_IN_W] = rot->var_values[ROTATE_VAR_IW] = in->width; rot->var_values[ROTATE_VAR_IN_H] = rot->var_values[ROTATE_VAR_IH] = in->height; rot->var_values[ROTATE_VAR_HSUB] = 1<<rot->hsub; rot->var_values[ROTATE_VAR_VSUB] = 1<<rot->vsub; rot->var_values[ROTATE_VAR_N] = NAN; rot->var_values[ROTATE_VAR_T] = NAN; rot->var_values[ROTATE_VAR_OUT_W] = rot->var_values[ROTATE_VAR_OW] = NAN; rot->var_values[ROTATE_VAR_OUT_H] = rot->var_values[ROTATE_VAR_OH] = NAN; av_expr_free(rot->angle_expr); rot->angle_expr = NULL; if ((ret = av_expr_parse(&rot->angle_expr, expr = rot->angle_expr_str, var_names, func1_names, func1, NULL, NULL, 0, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Error occurred parsing angle expression '%s'\n", rot->angle_expr_str); return ret; } #define SET_SIZE_EXPR(name, opt_name) do { \ ret = av_expr_parse_and_eval(&res, expr = rot->name##_expr_str, \ var_names, rot->var_values, \ func1_names, func1, NULL, NULL, rot, 0, NULL); \ if (ret < 0 || isnan(res) || isinf(res) || res <= 0) { \ av_log(NULL, AV_LOG_ERROR, \ "Error parsing or evaluating expression for option %s: " \ "invalid expression '%s' or non-positive or indefinite value %f\n", \ opt_name, expr, res); \ return ret; \ } \ } while (0) /* evaluate width and height */ av_expr_parse_and_eval(&res, expr = rot->outw_expr_str, var_names, rot->var_values, func1_names, func1, NULL, NULL, rot, 0, NULL); rot->var_values[ROTATE_VAR_OUT_W] = rot->var_values[ROTATE_VAR_OW] = res; rot->outw = res + 0.5; SET_SIZE_EXPR(outh, "out_h"); rot->var_values[ROTATE_VAR_OUT_H] = rot->var_values[ROTATE_VAR_OH] = res; rot->outh = res + 0.5; /* evaluate the width again, as it may depend on the evaluated output height */ SET_SIZE_EXPR(outw, "out_w"); rot->var_values[ROTATE_VAR_OUT_W] = rot->var_values[ROTATE_VAR_OW] = res; rot->outw = res + 0.5; /* compute number of planes */ rot->nb_planes = av_pix_fmt_count_planes((AVPixelFormat)in->format); ////out->width = rot->outw; ////outlink->h = rot->outh; return 0; }
static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; DCTdnoizContext *s = ctx->priv; int i, x, y, bx, by, linesize, *iweights, max_slice_h, slice_h; const int bsize = 1 << s->n; switch (inlink->format) { case AV_PIX_FMT_BGR24: s->color_decorrelation = color_decorrelation_bgr; s->color_correlation = color_correlation_bgr; break; case AV_PIX_FMT_RGB24: s->color_decorrelation = color_decorrelation_rgb; s->color_correlation = color_correlation_rgb; break; default: av_assert0(0); } s->pr_width = inlink->w - (inlink->w - bsize) % s->step; s->pr_height = inlink->h - (inlink->h - bsize) % s->step; if (s->pr_width != inlink->w) av_log(ctx, AV_LOG_WARNING, "The last %d horizontal pixels won't be denoised\n", inlink->w - s->pr_width); if (s->pr_height != inlink->h) av_log(ctx, AV_LOG_WARNING, "The last %d vertical pixels won't be denoised\n", inlink->h - s->pr_height); max_slice_h = s->pr_height / ((s->bsize - 1) * 2); s->nb_threads = FFMIN3(MAX_THREADS, ctx->graph->nb_threads, max_slice_h); av_log(ctx, AV_LOG_DEBUG, "threads: [max=%d hmax=%d user=%d] => %d\n", MAX_THREADS, max_slice_h, ctx->graph->nb_threads, s->nb_threads); s->p_linesize = linesize = FFALIGN(s->pr_width, 32); for (i = 0; i < 2; i++) { s->cbuf[i][0] = av_malloc(linesize * s->pr_height * sizeof(*s->cbuf[i][0])); s->cbuf[i][1] = av_malloc(linesize * s->pr_height * sizeof(*s->cbuf[i][1])); s->cbuf[i][2] = av_malloc(linesize * s->pr_height * sizeof(*s->cbuf[i][2])); if (!s->cbuf[i][0] || !s->cbuf[i][1] || !s->cbuf[i][2]) return AVERROR(ENOMEM); } /* eval expressions are probably not thread safe when the eval internal * state can be changed (typically through load & store operations) */ if (s->expr_str) { for (i = 0; i < s->nb_threads; i++) { int ret = av_expr_parse(&s->expr[i], s->expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) return ret; } } /* each slice will need to (pre & re)process the top and bottom block of * the previous one in in addition to its processing area. This is because * each pixel is averaged by all the surrounding blocks */ slice_h = (int)ceilf(s->pr_height / s->nb_threads) + (s->bsize - 1) * 2; for (i = 0; i < s->nb_threads; i++) { s->slices[i] = av_malloc_array(linesize, slice_h * sizeof(*s->slices[i])); if (!s->slices[i]) return AVERROR(ENOMEM); } s->weights = av_malloc(s->pr_height * linesize * sizeof(*s->weights)); if (!s->weights) return AVERROR(ENOMEM); iweights = av_calloc(s->pr_height, linesize * sizeof(*iweights)); if (!iweights) return AVERROR(ENOMEM); for (y = 0; y < s->pr_height - bsize + 1; y += s->step) for (x = 0; x < s->pr_width - bsize + 1; x += s->step) for (by = 0; by < bsize; by++) for (bx = 0; bx < bsize; bx++) iweights[(y + by)*linesize + x + bx]++; for (y = 0; y < s->pr_height; y++) for (x = 0; x < s->pr_width; x++) s->weights[y*linesize + x] = 1. / iweights[y*linesize + x]; av_free(iweights); return 0; }
static int config_input(AVFilterLink *link) { AVFilterContext *ctx = link->dst; CropContext *crop = ctx->priv; const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[link->format]; int ret; const char *expr; double res; crop->var_values[VAR_IN_W] = crop->var_values[VAR_IW] = ctx->inputs[0]->w; crop->var_values[VAR_IN_H] = crop->var_values[VAR_IH] = ctx->inputs[0]->h; crop->var_values[VAR_A] = (float) link->w / link->h; crop->var_values[VAR_SAR] = link->sample_aspect_ratio.num ? av_q2d(link->sample_aspect_ratio) : 1; crop->var_values[VAR_DAR] = crop->var_values[VAR_A] * crop->var_values[VAR_SAR]; crop->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w; crop->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h; crop->var_values[VAR_X] = NAN; crop->var_values[VAR_Y] = NAN; crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = NAN; crop->var_values[VAR_OUT_H] = crop->var_values[VAR_OH] = NAN; crop->var_values[VAR_N] = 0; crop->var_values[VAR_T] = NAN; crop->var_values[VAR_POS] = NAN; av_image_fill_max_pixsteps(crop->max_step, NULL, pix_desc); crop->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w; crop->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; if ((ret = av_expr_parse_and_eval(&res, (expr = crop->ow_expr), var_names, crop->var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr; crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = res; if ((ret = av_expr_parse_and_eval(&res, (expr = crop->oh_expr), var_names, crop->var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr; crop->var_values[VAR_OUT_H] = crop->var_values[VAR_OH] = res; /* evaluate again ow as it may depend on oh */ if ((ret = av_expr_parse_and_eval(&res, (expr = crop->ow_expr), var_names, crop->var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr; crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = res; if (normalize_double(&crop->w, crop->var_values[VAR_OUT_W]) < 0 || normalize_double(&crop->h, crop->var_values[VAR_OUT_H]) < 0) { av_log(ctx, AV_LOG_ERROR, "Too big value or invalid expression for out_w/ow or out_h/oh. " "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", crop->ow_expr, crop->oh_expr); return AVERROR(EINVAL); } crop->w &= ~((1 << crop->hsub) - 1); crop->h &= ~((1 << crop->vsub) - 1); if ((ret = av_expr_parse(&crop->x_pexpr, crop->x_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0 || (ret = av_expr_parse(&crop->y_pexpr, crop->y_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) return AVERROR(EINVAL); if (crop->keep_aspect) { AVRational dar = av_mul_q(link->sample_aspect_ratio, (AVRational){ link->w, link->h }); av_reduce(&crop->out_sar.num, &crop->out_sar.den, dar.num * crop->h, dar.den * crop->w, INT_MAX); } else crop->out_sar = link->sample_aspect_ratio; av_log(ctx, AV_LOG_INFO, "w:%d h:%d sar:%d/%d -> w:%d h:%d sar:%d/%d\n", link->w, link->h, link->sample_aspect_ratio.num, link->sample_aspect_ratio.den, crop->w, crop->h, crop->out_sar.num, crop->out_sar.den); if (crop->w <= 0 || crop->h <= 0 || crop->w > link->w || crop->h > link->h) { av_log(ctx, AV_LOG_ERROR, "Invalid too big or non positive size for width '%d' or height '%d'\n", crop->w, crop->h); return AVERROR(EINVAL); } /* set default, required in the case the first computed value for x/y is NAN */ crop->x = (link->w - crop->w) / 2; crop->y = (link->h - crop->h) / 2; crop->x &= ~((1 << crop->hsub) - 1); crop->y &= ~((1 << crop->vsub) - 1); return 0; fail_expr: av_log(NULL, AV_LOG_ERROR, "Error when evaluating the expression '%s'\n", expr); return ret; }
static av_cold int init(AVFilterContext *ctx) { MetadataContext *s = ctx->priv; int ret; if (!s->key && s->mode != METADATA_PRINT) { av_log(ctx, AV_LOG_WARNING, "Metadata key must be set\n"); return AVERROR(EINVAL); } if ((s->mode == METADATA_MODIFY || s->mode == METADATA_ADD) && !s->value) { av_log(ctx, AV_LOG_WARNING, "Missing metadata value\n"); return AVERROR(EINVAL); } switch (s->function) { case METADATAF_SAME_STR: s->compare = same_str; break; case METADATAF_STARTS_WITH: s->compare = starts_with; break; case METADATAF_LESS: s->compare = less; break; case METADATAF_EQUAL: s->compare = equal; break; case METADATAF_GREATER: s->compare = greater; break; case METADATAF_EXPR: s->compare = parse_expr; break; default: av_assert0(0); }; if (s->function == METADATAF_EXPR) { if (!s->expr_str) { av_log(ctx, AV_LOG_WARNING, "expr option not set\n"); return AVERROR(EINVAL); } if ((ret = av_expr_parse(&s->expr, s->expr_str, var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", s->expr_str); return ret; } } if (s->mode == METADATA_PRINT && s->file_str) { s->print = print_file; } else { s->print = print_log; } s->avio_context = NULL; if (s->file_str) { if (!strcmp("-", s->file_str)) { ret = avio_open(&s->avio_context, "pipe:1", AVIO_FLAG_WRITE); } else { ret = avio_open(&s->avio_context, s->file_str, AVIO_FLAG_WRITE); } if (ret < 0) { char buf[128]; av_strerror(ret, buf, sizeof(buf)); av_log(ctx, AV_LOG_ERROR, "Could not open %s: %s\n", s->file_str, buf); return ret; } } return 0; }
static int config_input(AVFilterLink *link) { AVFilterContext *ctx = link->dst; CropContext *s = ctx->priv; const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(link->format); int ret; const char *expr; double res; s->var_values[VAR_E] = M_E; s->var_values[VAR_PHI] = M_PHI; s->var_values[VAR_PI] = M_PI; s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = ctx->inputs[0]->w; s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = ctx->inputs[0]->h; s->var_values[VAR_X] = NAN; s->var_values[VAR_Y] = NAN; s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = NAN; s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = NAN; s->var_values[VAR_N] = 0; s->var_values[VAR_T] = NAN; av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc); s->hsub = pix_desc->log2_chroma_w; s->vsub = pix_desc->log2_chroma_h; if ((ret = av_expr_parse_and_eval(&res, (expr = s->ow_expr), var_names, s->var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr; s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res; if ((ret = av_expr_parse_and_eval(&res, (expr = s->oh_expr), var_names, s->var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr; s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = res; /* evaluate again ow as it may depend on oh */ if ((ret = av_expr_parse_and_eval(&res, (expr = s->ow_expr), var_names, s->var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr; s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res; if (normalize_double(&s->w, s->var_values[VAR_OUT_W]) < 0 || normalize_double(&s->h, s->var_values[VAR_OUT_H]) < 0) { av_log(ctx, AV_LOG_ERROR, "Too big value or invalid expression for out_w/ow or out_h/oh. " "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", s->ow_expr, s->oh_expr); return AVERROR(EINVAL); } s->w &= ~((1 << s->hsub) - 1); s->h &= ~((1 << s->vsub) - 1); av_expr_free(s->x_pexpr); av_expr_free(s->y_pexpr); s->x_pexpr = s->y_pexpr = NULL; if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0 || (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) return AVERROR(EINVAL); av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n", link->w, link->h, s->w, s->h); if (s->w <= 0 || s->h <= 0 || s->w > link->w || s->h > link->h) { av_log(ctx, AV_LOG_ERROR, "Invalid too big or non positive size for width '%d' or height '%d'\n", s->w, s->h); return AVERROR(EINVAL); } /* set default, required in the case the first computed value for x/y is NAN */ s->x = (link->w - s->w) / 2; s->y = (link->h - s->h) / 2; s->x &= ~((1 << s->hsub) - 1); s->y &= ~((1 << s->vsub) - 1); return 0; fail_expr: av_log(NULL, AV_LOG_ERROR, "Error when evaluating the expression '%s'\n", expr); return ret; }
static int modplug_read_header(AVFormatContext *s) { AVStream *st; AVIOContext *pb = s->pb; ModPlug_Settings settings; ModPlugContext *modplug = s->priv_data; int sz = avio_size(pb); if (sz < 0) { av_log(s, AV_LOG_WARNING, "Could not determine file size\n"); sz = modplug->max_size; } else if (modplug->max_size && sz > modplug->max_size) { sz = modplug->max_size; av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %dB " "but demuxing is likely to fail due to incomplete buffer\n", sz == FF_MODPLUG_DEF_FILE_SIZE ? " (see -max_size)" : "", sz); } if (modplug->color_eval) { int r = av_expr_parse(&modplug->expr, modplug->color_eval, var_names, NULL, NULL, NULL, NULL, 0, s); if (r < 0) return r; } modplug->buf = av_malloc(modplug->max_size); if (!modplug->buf) return AVERROR(ENOMEM); sz = avio_read(pb, modplug->buf, sz); ModPlug_GetSettings(&settings); settings.mChannels = 2; settings.mBits = 16; settings.mFrequency = 44100; settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; // best quality settings.mLoopCount = 0; // prevents looping forever if (modplug->noise_reduction) settings.mFlags |= MODPLUG_ENABLE_NOISE_REDUCTION; SET_OPT_IF_REQUESTED(mReverbDepth, reverb_depth, MODPLUG_ENABLE_REVERB); SET_OPT_IF_REQUESTED(mReverbDelay, reverb_delay, MODPLUG_ENABLE_REVERB); SET_OPT_IF_REQUESTED(mBassAmount, bass_amount, MODPLUG_ENABLE_MEGABASS); SET_OPT_IF_REQUESTED(mBassRange, bass_range, MODPLUG_ENABLE_MEGABASS); SET_OPT_IF_REQUESTED(mSurroundDepth, surround_depth, MODPLUG_ENABLE_SURROUND); SET_OPT_IF_REQUESTED(mSurroundDelay, surround_delay, MODPLUG_ENABLE_SURROUND); if (modplug->reverb_depth) settings.mReverbDepth = modplug->reverb_depth; if (modplug->reverb_delay) settings.mReverbDelay = modplug->reverb_delay; if (modplug->bass_amount) settings.mBassAmount = modplug->bass_amount; if (modplug->bass_range) settings.mBassRange = modplug->bass_range; if (modplug->surround_depth) settings.mSurroundDepth = modplug->surround_depth; if (modplug->surround_delay) settings.mSurroundDelay = modplug->surround_delay; ModPlug_SetSettings(&settings); modplug->f = ModPlug_Load(modplug->buf, sz); if (!modplug->f) return AVERROR_INVALIDDATA; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, 1000); st->duration = ModPlug_GetLength(modplug->f); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; st->codec->channels = settings.mChannels; st->codec->sample_rate = settings.mFrequency; // timebase = 1/1000, 2ch 16bits 44.1kHz-> 2*2*44100 modplug->ts_per_packet = 1000*AUDIO_PKT_SIZE / (4*44100.); if (modplug->video_stream) { AVStream *vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); avpriv_set_pts_info(vst, 64, 1, 1000); vst->duration = st->duration; vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_id = AV_CODEC_ID_XBIN; vst->codec->width = modplug->w << 3; vst->codec->height = modplug->h << 3; modplug->linesize = modplug->w * 3; modplug->fsize = modplug->linesize * modplug->h; } return modplug_load_metadata(s); }
static av_cold int geq_init(AVFilterContext *ctx) { GEQContext *geq = ctx->priv; int plane, ret = 0; if (!geq->expr_str[Y] && !geq->expr_str[G] && !geq->expr_str[B] && !geq->expr_str[R]) { av_log(ctx, AV_LOG_ERROR, "A luminance or RGB expression is mandatory\n"); ret = AVERROR(EINVAL); goto end; } geq->is_rgb = !geq->expr_str[Y]; if ((geq->expr_str[Y] || geq->expr_str[U] || geq->expr_str[V]) && (geq->expr_str[G] || geq->expr_str[B] || geq->expr_str[R])) { av_log(ctx, AV_LOG_ERROR, "Either YCbCr or RGB but not both must be specified\n"); ret = AVERROR(EINVAL); goto end; } if (!geq->expr_str[U] && !geq->expr_str[V]) { /* No chroma at all: fallback on luma */ geq->expr_str[U] = av_strdup(geq->expr_str[Y]); geq->expr_str[V] = av_strdup(geq->expr_str[Y]); } else { /* One chroma unspecified, fallback on the other */ if (!geq->expr_str[U]) geq->expr_str[U] = av_strdup(geq->expr_str[V]); if (!geq->expr_str[V]) geq->expr_str[V] = av_strdup(geq->expr_str[U]); } if (!geq->expr_str[A]) { char bps_string[8]; snprintf(bps_string, sizeof(bps_string), "%d", (1<<geq->bps) - 1); geq->expr_str[A] = av_strdup(bps_string); } if (!geq->expr_str[G]) geq->expr_str[G] = av_strdup("g(X,Y)"); if (!geq->expr_str[B]) geq->expr_str[B] = av_strdup("b(X,Y)"); if (!geq->expr_str[R]) geq->expr_str[R] = av_strdup("r(X,Y)"); if (geq->is_rgb ? (!geq->expr_str[G] || !geq->expr_str[B] || !geq->expr_str[R]) : (!geq->expr_str[U] || !geq->expr_str[V] || !geq->expr_str[A])) { ret = AVERROR(ENOMEM); goto end; } for (plane = 0; plane < 4; plane++) { static double (*p[])(void *, double, double) = { lum, cb, cr, alpha }; static const char *const func2_yuv_names[] = { "lum", "cb", "cr", "alpha", "p", NULL }; static const char *const func2_rgb_names[] = { "g", "b", "r", "alpha", "p", NULL }; const char *const *func2_names = geq->is_rgb ? func2_rgb_names : func2_yuv_names; double (*func2[])(void *, double, double) = { lum, cb, cr, alpha, p[plane], NULL }; ret = av_expr_parse(&geq->e[plane], geq->expr_str[plane < 3 && geq->is_rgb ? plane+4 : plane], var_names, NULL, NULL, func2_names, func2, 0, ctx); if (ret < 0) break; } end: return ret; }
static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AFFTFiltContext *s = ctx->priv; char *saveptr = NULL; int ret = 0, ch, i; float overlap; char *args; const char *last_expr = "1"; s->fft = av_fft_init(s->fft_bits, 0); s->ifft = av_fft_init(s->fft_bits, 1); if (!s->fft || !s->ifft) return AVERROR(ENOMEM); s->window_size = 1 << s->fft_bits; s->fft_data = av_calloc(inlink->channels, sizeof(*s->fft_data)); if (!s->fft_data) return AVERROR(ENOMEM); for (ch = 0; ch < inlink->channels; ch++) { s->fft_data[ch] = av_calloc(s->window_size, sizeof(**s->fft_data)); if (!s->fft_data[ch]) return AVERROR(ENOMEM); } s->real = av_calloc(inlink->channels, sizeof(*s->real)); if (!s->real) return AVERROR(ENOMEM); s->imag = av_calloc(inlink->channels, sizeof(*s->imag)); if (!s->imag) return AVERROR(ENOMEM); args = av_strdup(s->real_str); if (!args) return AVERROR(ENOMEM); for (ch = 0; ch < inlink->channels; ch++) { char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr); ret = av_expr_parse(&s->real[ch], arg ? arg : last_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) break; if (arg) last_expr = arg; s->nb_exprs++; } av_free(args); args = av_strdup(s->img_str ? s->img_str : s->real_str); if (!args) return AVERROR(ENOMEM); for (ch = 0; ch < inlink->channels; ch++) { char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr); ret = av_expr_parse(&s->imag[ch], arg ? arg : last_expr, var_names, NULL, NULL, NULL, NULL, 0, ctx); if (ret < 0) break; if (arg) last_expr = arg; } av_free(args); s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size); if (!s->fifo) return AVERROR(ENOMEM); s->window_func_lut = av_realloc_f(s->window_func_lut, s->window_size, sizeof(*s->window_func_lut)); if (!s->window_func_lut) return AVERROR(ENOMEM); ff_generate_window_func(s->window_func_lut, s->window_size, s->win_func, &overlap); if (s->overlap == 1) s->overlap = overlap; for (s->win_scale = 0, i = 0; i < s->window_size; i++) { s->win_scale += s->window_func_lut[i] * s->window_func_lut[i]; } s->hop_size = s->window_size * (1 - s->overlap); if (s->hop_size <= 0) return AVERROR(EINVAL); s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2); if (!s->buffer) return AVERROR(ENOMEM); return ret; }