Beispiel #1
0
static int config_input_overlay(AVFilterLink *inlink)
{
    AVFilterContext *ctx  = inlink->dst;
    OverlayContext  *over = inlink->dst->priv;
    char *expr;
    double var_values[VAR_VARS_NB], res;
    int ret;

    /* Finish the configuration by evaluating the expressions
       now when both inputs are configured. */
    var_values[VAR_E  ] = M_E;
    var_values[VAR_PHI] = M_PHI;
    var_values[VAR_PI ] = M_PI;

    var_values[VAR_MAIN_W   ] = var_values[VAR_MW] = ctx->inputs[MAIN   ]->w;
    var_values[VAR_MAIN_H   ] = var_values[VAR_MH] = ctx->inputs[MAIN   ]->h;
    var_values[VAR_OVERLAY_W] = var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
    var_values[VAR_OVERLAY_H] = var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;

    if ((ret = av_expr_parse_and_eval(&res, (expr = over->x_expr), var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        goto fail;
    over->x = res;
    if ((ret = av_expr_parse_and_eval(&res, (expr = over->y_expr), var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)))
        goto fail;
    over->y = res;
    /* x may depend on y */
    if ((ret = av_expr_parse_and_eval(&res, (expr = over->x_expr), var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        goto fail;
    over->x = res;

    av_log(ctx, AV_LOG_INFO,
           "main w:%d h:%d fmt:%s overlay x:%d y:%d w:%d h:%d fmt:%s\n",
           ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
           av_pix_fmt_descriptors[ctx->inputs[MAIN]->format].name,
           over->x, over->y,
           ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
           av_pix_fmt_descriptors[ctx->inputs[OVERLAY]->format].name);

    if (over->x < 0 || over->y < 0 ||
        over->x + var_values[VAR_OVERLAY_W] > var_values[VAR_MAIN_W] ||
        over->y + var_values[VAR_OVERLAY_H] > var_values[VAR_MAIN_H]) {
        av_log(ctx, AV_LOG_ERROR,
               "Overlay area (%d,%d)<->(%d,%d) not within the main area (0,0)<->(%d,%d) or zero-sized\n",
               over->x, over->y,
               (int)(over->x + var_values[VAR_OVERLAY_W]),
               (int)(over->y + var_values[VAR_OVERLAY_H]),
               (int)var_values[VAR_MAIN_W], (int)var_values[VAR_MAIN_H]);
        return AVERROR(EINVAL);
    }
    return 0;

fail:
    av_log(NULL, AV_LOG_ERROR,
           "Error when evaluating the expression '%s'\n", expr);
    return ret;
}
Beispiel #2
0
static int get_aspect_ratio(AVFilterLink *inlink, AVRational *aspect_ratio)
{
    AVFilterContext *ctx = inlink->dst;
    AspectContext *s = inlink->dst->priv;
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
    double var_values[VARS_NB], res;
    int ret;

    var_values[VAR_PI]    = M_PI;
    var_values[VAR_PHI]   = M_PHI;
    var_values[VAR_E]     = M_E;
    var_values[VAR_W]     = inlink->w;
    var_values[VAR_H]     = inlink->h;
    var_values[VAR_A]     = (double) inlink->w / inlink->h;
    var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
    var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];
    var_values[VAR_HSUB]  = 1 << desc->log2_chroma_w;
    var_values[VAR_VSUB]  = 1 << desc->log2_chroma_h;

    /* evaluate new aspect ratio*/
    if ((ret = av_expr_parse_and_eval(&res, s->ratio_expr,
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
        av_log(NULL, AV_LOG_ERROR,
               "Error when evaluating the expression '%s'\n", s->ratio_expr);
        return ret;
    }
    *aspect_ratio = av_d2q(res, INT_MAX);
    return 0;
}
Beispiel #3
0
static int config_output_props(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    SetTBContext *settb = ctx->priv;
    AVFilterLink *inlink = ctx->inputs[0];
    AVRational time_base;
    int ret;
    double res;

    settb->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q);
    settb->var_values[VAR_INTB] = av_q2d(inlink->time_base);

    outlink->w = inlink->w;
    outlink->h = inlink->h;

    if ((ret = av_expr_parse_and_eval(&res, settb->tb_expr, var_names, settb->var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
        av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", settb->tb_expr);
        return ret;
    }
    time_base = av_d2q(res, INT_MAX);
    if (time_base.num <= 0 || time_base.den <= 0) {
        av_log(ctx, AV_LOG_ERROR,
               "Invalid non-positive values for the timebase num:%d or den:%d.\n",
               time_base.num, time_base.den);
        return AVERROR(EINVAL);
    }

    outlink->time_base = time_base;
    av_log(outlink->src, AV_LOG_INFO, "tb:%d/%d -> tb:%d/%d\n",
           inlink ->time_base.num, inlink ->time_base.den,
           outlink->time_base.num, outlink->time_base.den);

    return 0;
}
Beispiel #4
0
int av_parse_ratio(AVRational *q, const char *str, int max,
                   int log_offset, void *log_ctx)
{
    char c;
    int ret;
    int64_t gcd;

    if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) {
        double d;
        ret = av_expr_parse_and_eval(&d, str, NULL, NULL,
                                     NULL, NULL, NULL, NULL,
                                     NULL, log_offset, log_ctx);
        if (ret < 0)
            return ret;
        *q = av_d2q(d, max);
    }

    gcd = av_gcd(FFABS(q->num), FFABS(q->den));
    if (gcd) {
        q->num /= gcd;
        q->den /= gcd;
    }

    return 0;
}
Beispiel #5
0
static int config_props(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    NullContext *priv = ctx->priv;
    AVRational tb;
    int ret;
    double res;

    priv->var_values[VAR_E]    = M_E;
    priv->var_values[VAR_PHI]  = M_PHI;
    priv->var_values[VAR_PI]   = M_PI;
    priv->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q);

    if ((ret = av_expr_parse_and_eval(&res, priv->tb_expr, var_names, priv->var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
        av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", priv->tb_expr);
        return ret;
    }
    tb = av_d2q(res, INT_MAX);
    if (tb.num <= 0 || tb.den <= 0) {
        av_log(ctx, AV_LOG_ERROR,
               "Invalid non-positive value for the timebase %d/%d.\n",
               tb.num, tb.den);
        return AVERROR(EINVAL);
    }

    outlink->w = priv->w;
    outlink->h = priv->h;
    outlink->time_base = tb;

    av_log(outlink->src, AV_LOG_VERBOSE, "w:%d h:%d tb:%d/%d\n", priv->w, priv->h,
           tb.num, tb.den);

    return 0;
}
Beispiel #6
0
static int func_eval_expr_int_format(AVFilterContext *ctx, AVBPrint *bp,
                          char *fct, unsigned argc, char **argv, int tag)
{
    DrawTextContext *s = ctx->priv;
    double res;
    int intval;
    int ret;
    unsigned int positions = 0;
    char fmt_str[30] = "%";

    /*
     * argv[0] expression to be converted to `int`
     * argv[1] format: 'x', 'X', 'd' or 'u'
     * argv[2] positions printed (optional)
     */

    ret = av_expr_parse_and_eval(&res, argv[0], var_names, s->var_values,
                                 NULL, NULL, fun2_names, fun2,
                                 &s->prng, 0, ctx);
    if (ret < 0) {
        av_log(ctx, AV_LOG_ERROR,
               "Expression '%s' for the expr text expansion function is not valid\n",
               argv[0]);
        return ret;
    }

    if (!strchr("xXdu", argv[1][0])) {
        av_log(ctx, AV_LOG_ERROR, "Invalid format '%c' specified,"
                " allowed values: 'x', 'X', 'd', 'u'\n", argv[1][0]);
        return AVERROR(EINVAL);
    }

    if (argc == 3) {
        ret = sscanf(argv[2], "%u", &positions);
        if (ret != 1) {
            av_log(ctx, AV_LOG_ERROR, "expr_int_format(): Invalid number of positions"
                    " to print: '%s'\n", argv[2]);
            return AVERROR(EINVAL);
        }
    }

    feclearexcept(FE_ALL_EXCEPT);
    intval = res;
    if ((ret = fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW))) {
        av_log(ctx, AV_LOG_ERROR, "Conversion of floating-point result to int failed. Control register: 0x%08x. Conversion result: %d\n", ret, intval);
        return AVERROR(EINVAL);
    }

    if (argc == 3)
        av_strlcatf(fmt_str, sizeof(fmt_str), "0%u", positions);
    av_strlcatf(fmt_str, sizeof(fmt_str), "%c", argv[1][0]);

    av_log(ctx, AV_LOG_DEBUG, "Formatting value %f (expr '%s') with spec '%s'\n",
            res, argv[0], fmt_str);

    av_bprintf(bp, fmt_str, intval);

    return 0;
}
Beispiel #7
0
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    ZPContext *s = ctx->priv;
    double nb_frames;
    int ret;

    if (s->in) {
        av_frame_free(&in);
        return 0;
    }

    s->finished = 0;
    s->var_values[VAR_IN_W]  = s->var_values[VAR_IW] = in->width;
    s->var_values[VAR_IN_H]  = s->var_values[VAR_IH] = in->height;
    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w;
    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h;
    s->var_values[VAR_IN]    = inlink->frame_count + 1;
    s->var_values[VAR_ON]    = outlink->frame_count + 1;
    s->var_values[VAR_PX]    = s->x;
    s->var_values[VAR_PY]    = s->y;
    s->var_values[VAR_X]     = 0;
    s->var_values[VAR_Y]     = 0;
    s->var_values[VAR_PZOOM] = s->prev_zoom;
    s->var_values[VAR_ZOOM]  = 1;
    s->var_values[VAR_PDURATION] = s->prev_nb_frames;
    s->var_values[VAR_A]     = (double) in->width / in->height;
    s->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
    s->var_values[VAR_DAR]   = s->var_values[VAR_A] * s->var_values[VAR_SAR];
    s->var_values[VAR_HSUB]  = 1 << s->desc->log2_chroma_w;
    s->var_values[VAR_VSUB]  = 1 << s->desc->log2_chroma_h;

    if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str,
                                      var_names, s->var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
        av_frame_free(&in);
        return ret;
    }

    s->var_values[VAR_DURATION] = s->nb_frames = nb_frames;
    s->in = in;

    return 0;
}
Beispiel #8
0
static int func_eval_expr(AVFilterContext *ctx, AVBPrint *bp,
                          char *fct, unsigned argc, char **argv, int tag)
{
    DrawTextContext *s = ctx->priv;
    double res;
    int ret;

    ret = av_expr_parse_and_eval(&res, argv[0], var_names, s->var_values,
                                 NULL, NULL, fun2_names, fun2,
                                 &s->prng, 0, ctx);
    if (ret < 0)
        av_log(ctx, AV_LOG_ERROR,
               "Expression '%s' for the expr text expansion function is not valid\n",
               argv[0]);
    else
        av_bprintf(bp, "%f", res);

    return ret;
}
Beispiel #9
0
int av_parse_ratio(AVRational *q, const char *str, int max,
                   int log_offset, void *log_ctx)
{
    char c;
    int ret;

    if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) {
        double d;
        ret = av_expr_parse_and_eval(&d, str, NULL, NULL,
                                     NULL, NULL, NULL, NULL,
                                     NULL, log_offset, log_ctx);
        if (ret < 0)
            return ret;
        *q = av_d2q(d, max);
    } else {
        av_reduce(&q->num, &q->den, q->num, q->den, max);
    }

    return 0;
}
Beispiel #10
0
int av_parse_video_rate(AVRational *rate, const char *arg)
{
    int i, ret;
    int n = FF_ARRAY_ELEMS(video_rate_abbrs);
    double res;

    /* First, we check our abbreviation table */
    for (i = 0; i < n; ++i)
        if (!strcmp(video_rate_abbrs[i].abbr, arg)) {
            *rate = video_rate_abbrs[i].rate;
            return 0;
        }

    /* Then, we try to parse it as fraction */
    if ((ret = av_expr_parse_and_eval(&res, arg, NULL, NULL, NULL, NULL, NULL, NULL,
                                      NULL, 0, NULL)) < 0)
        return ret;
    *rate = av_d2q(res, 1001000);
    if (rate->num <= 0 || rate->den <= 0)
        return AVERROR(EINVAL);
    return 0;
}
Beispiel #11
0
static int get_aspect_ratio(AVFilterLink *inlink, AVRational *aspect_ratio)
{
    AVFilterContext *ctx = inlink->dst;
    AspectContext *s = inlink->dst->priv;
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
    double var_values[VARS_NB], res;
    int ret;

    var_values[VAR_W]     = inlink->w;
    var_values[VAR_H]     = inlink->h;
    var_values[VAR_A]     = (double) inlink->w / inlink->h;
    var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
    var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];
    var_values[VAR_HSUB]  = 1 << desc->log2_chroma_w;
    var_values[VAR_VSUB]  = 1 << desc->log2_chroma_h;

    /* evaluate new aspect ratio*/
    ret = av_expr_parse_and_eval(&res, s->ratio_expr,
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx);
    if (ret < 0) {
        ret = av_parse_ratio(aspect_ratio, s->ratio_expr, s->max, 0, ctx);
    } else
        *aspect_ratio = av_d2q(res, s->max);

    if (ret < 0) {
        av_log(ctx, AV_LOG_ERROR,
               "Error when evaluating the expression '%s'\n", s->ratio_expr);
        return ret;
    }
    if (aspect_ratio->num < 0 || aspect_ratio->den <= 0) {
        av_log(ctx, AV_LOG_ERROR,
                "Invalid string '%s' for aspect ratio\n", s->ratio_expr);
        return AVERROR(EINVAL);
    }
    return 0;
}
Beispiel #12
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;
}
Beispiel #13
0
static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_values, int i,
                               double *zoom, double *dx, double *dy)
{
    ZPContext *s = ctx->priv;
    AVFilterLink *outlink = ctx->outputs[0];
    int64_t pts = s->frame_count;
    int k, x, y, w, h, ret = 0;
    uint8_t *input[4];
    int px[4], py[4];
    AVFrame *out;

    var_values[VAR_PX]    = s->x;
    var_values[VAR_PY]    = s->y;
    var_values[VAR_PZOOM] = s->prev_zoom;
    var_values[VAR_PDURATION] = s->prev_nb_frames;
    var_values[VAR_TIME] = pts * av_q2d(outlink->time_base);
    var_values[VAR_FRAME] = i;
    var_values[VAR_ON] = outlink->frame_count + 1;
    if ((ret = av_expr_parse_and_eval(zoom, s->zoom_expr_str,
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        return ret;

    *zoom = av_clipd(*zoom, 1, 10);
    var_values[VAR_ZOOM] = *zoom;
    w = in->width * (1.0 / *zoom);
    h = in->height * (1.0 / *zoom);

    if ((ret = av_expr_parse_and_eval(dx, s->x_expr_str,
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        return ret;
    x = *dx = av_clipd(*dx, 0, FFMAX(in->width - w, 0));
    var_values[VAR_X] = *dx;
    x &= ~((1 << s->desc->log2_chroma_w) - 1);

    if ((ret = av_expr_parse_and_eval(dy, s->y_expr_str,
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        return ret;
    y = *dy = av_clipd(*dy, 0, FFMAX(in->height - h, 0));
    var_values[VAR_Y] = *dy;
    y &= ~((1 << s->desc->log2_chroma_h) - 1);

    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
    if (!out) {
        ret = AVERROR(ENOMEM);
        return ret;
    }

    px[1] = px[2] = AV_CEIL_RSHIFT(x, s->desc->log2_chroma_w);
    px[0] = px[3] = x;

    py[1] = py[2] = AV_CEIL_RSHIFT(y, s->desc->log2_chroma_h);
    py[0] = py[3] = y;

    s->sws = sws_alloc_context();
    if (!s->sws) {
        ret = AVERROR(ENOMEM);
        return ret;
    }

    for (k = 0; in->data[k]; k++)
        input[k] = in->data[k] + py[k] * in->linesize[k] + px[k];

    av_opt_set_int(s->sws, "srcw", w, 0);
    av_opt_set_int(s->sws, "srch", h, 0);
    av_opt_set_int(s->sws, "src_format", in->format, 0);
    av_opt_set_int(s->sws, "dstw", outlink->w, 0);
    av_opt_set_int(s->sws, "dsth", outlink->h, 0);
    av_opt_set_int(s->sws, "dst_format", outlink->format, 0);
    av_opt_set_int(s->sws, "sws_flags", SWS_BICUBIC, 0);

    if ((ret = sws_init_context(s->sws, NULL, NULL)) < 0)
        return ret;

    sws_scale(s->sws, (const uint8_t *const *)&input, in->linesize, 0, h, out->data, out->linesize);

    out->pts = pts;
    s->frame_count++;

    ret = ff_filter_frame(outlink, out);
    sws_freeContext(s->sws);
    s->sws = NULL;
    s->current_frame++;
    return ret;
}
Beispiel #14
0
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    QPContext *s = ctx->priv;
    AVBufferRef *out_qp_table_buf;
    AVFrame *out;
    const int8_t *in_qp_table;
    int type, stride, ret;

    if (!s->qp_expr_str || ctx->is_disabled)
        return ff_filter_frame(outlink, in);

    out_qp_table_buf = av_buffer_alloc(s->h * s->qstride);
    if (!out_qp_table_buf) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    out = av_frame_clone(in);
    if (!out) {
        av_buffer_unref(&out_qp_table_buf);
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    in_qp_table = av_frame_get_qp_table(in, &stride, &type);
    av_frame_set_qp_table(out, out_qp_table_buf, s->qstride, type);


    if (s->evaluate_per_mb) {
        int y, x;

        for (y = 0; y < s->h; y++)
            for (x = 0; x < s->qstride; x++) {
                int qp = in_qp_table ? in_qp_table[x + stride * y] : NAN;
                double var_values[] = { !!in_qp_table, qp, x, y, s->qstride, s->h, 0};
                static const char *var_names[] = { "known", "qp", "x", "y", "w", "h", NULL };
                double temp_val;
                int ret;

                ret = av_expr_parse_and_eval(&temp_val, s->qp_expr_str,
                                            var_names, var_values,
                                            NULL, NULL, NULL, NULL, 0, 0, ctx);
                if (ret < 0)
                    return ret;
                out_qp_table_buf->data[x + s->qstride * y] = lrintf(temp_val);
            }
    } else if (in_qp_table) {
        int y, x;

        for (y = 0; y < s->h; y++)
            for (x = 0; x < s->qstride; x++)
                out_qp_table_buf->data[x + s->qstride * y] = s->lut[129 +
                    ((int8_t)in_qp_table[x + stride * y])];
    } else {
        int y, x, qp = s->lut[0];

        for (y = 0; y < s->h; y++)
            for (x = 0; x < s->qstride; x++)
                out_qp_table_buf->data[x + s->qstride * y] = qp;
    }

    ret = ff_filter_frame(outlink, out);
fail:
    av_frame_free(&in);
    return ret;
}
Beispiel #15
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;
}
Beispiel #16
0
static int config_input(AVFilterLink *inlink)
{
    double x0, x1, x2, x3, x4, x5, x6, x7, q;
    AVFilterContext *ctx = inlink->dst;
    PerspectiveContext *s = ctx->priv;
    double (*ref)[2] = s->ref;
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
    double values[VAR_VARS_NB] = { [VAR_W] = inlink->w, [VAR_H] = inlink->h };
    int h = inlink->h;
    int w = inlink->w;
    int x, y, i, j, ret;

    for (i = 0; i < 4; i++) {
        for (j = 0; j < 2; j++) {
            if (!s->expr_str[i][j])
                return AVERROR(EINVAL);
            ret = av_expr_parse_and_eval(&s->ref[i][j], s->expr_str[i][j],
                                         var_names, &values[0],
                                         NULL, NULL, NULL, NULL,
                                         0, 0, ctx);
            if (ret < 0)
                return ret;
        }
    }

    s->hsub = desc->log2_chroma_w;
    s->vsub = desc->log2_chroma_h;
    s->nb_planes = av_pix_fmt_count_planes(inlink->format);
    if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
        return ret;

    s->height[1] = s->height[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
    s->height[0] = s->height[3] = inlink->h;

    s->pv = av_realloc_f(s->pv, w * h, 2 * sizeof(*s->pv));
    if (!s->pv)
        return AVERROR(ENOMEM);

    x6 = ((ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
          (ref[2][1] - ref[3][1]) -
         ( ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
          (ref[2][0] - ref[3][0])) * h;
    x7 = ((ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
          (ref[1][0] - ref[3][0]) -
         ( ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
          (ref[1][1] - ref[3][1])) * w;
    q =  ( ref[1][0] - ref[3][0]) * (ref[2][1] - ref[3][1]) -
         ( ref[2][0] - ref[3][0]) * (ref[1][1] - ref[3][1]);

    x0 = q * (ref[1][0] - ref[0][0]) * h + x6 * ref[1][0];
    x1 = q * (ref[2][0] - ref[0][0]) * w + x7 * ref[2][0];
    x2 = q *  ref[0][0] * w * h;
    x3 = q * (ref[1][1] - ref[0][1]) * h + x6 * ref[1][1];
    x4 = q * (ref[2][1] - ref[0][1]) * w + x7 * ref[2][1];
    x5 = q *  ref[0][1] * w * h;

    for (y = 0; y < h; y++){
        for (x = 0; x < w; x++){
            int u, v;

            u = (int)floor(SUB_PIXELS * (x0 * x + x1 * y + x2) /
                                        (x6 * x + x7 * y + q * w * h) + 0.5);
            v = (int)floor(SUB_PIXELS * (x3 * x + x4 * y + x5) /
                                        (x6 * x + x7 * y + q * w * h) + 0.5);

            s->pv[x + y * w][0] = u;
            s->pv[x + y * w][1] = v;
        }
    }

    for (i = 0; i < SUB_PIXELS; i++){
        double d = i / (double)SUB_PIXELS;
        double temp[4];
        double sum = 0;

        for (j = 0; j < 4; j++)
            temp[j] = get_coeff(j - d - 1);

        for (j = 0; j < 4; j++)
            sum += temp[j];

        for (j = 0; j < 4; j++)
            s->coeff[i][j] = (int)floor((1 << COEFF_BITS) * temp[j] / sum + 0.5);
    }

    return 0;
}
Beispiel #17
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;
}
Beispiel #18
0
int main(int argc, char **argv)
{
    int i;
    double d;
    const char *const *expr;
    static const char *const exprs[] = {
        "",
        "1;2",
        "-20",
        "-PI",
        "+PI",
        "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
        "80G/80Gi",
        "1k",
        "1Gi",
        "1gi",
        "1GiFoo",
        "1k+1k",
        "1Gi*3foo",
        "foo",
        "foo(",
        "foo()",
        "foo)",
        "sin",
        "sin(",
        "sin()",
        "sin)",
        "sin 10",
        "sin(1,2,3)",
        "sin(1 )",
        "1",
        "1foo",
        "bar + PI + E + 100f*2 + foo",
        "13k + 12f - foo(1, 2)",
        "1gi",
        "1Gi",
        "st(0, 123)",
        "st(1, 123); ld(1)",
        "lte(0, 1)",
        "lte(1, 1)",
        "lte(1, 0)",
        "lt(0, 1)",
        "lt(1, 1)",
        "gt(1, 0)",
        "gt(2, 7)",
        "gte(122, 122)",
        /* compute 1+2+...+N */
        "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)",
        /* compute Fib(N) */
        "st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)",
        "while(0, 10)",
        "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
        "isnan(1)",
        "isnan(NAN)",
        "isnan(INF)",
        "isinf(1)",
        "isinf(NAN)",
        "isinf(INF)",
        "floor(NAN)",
        "floor(123.123)",
        "floor(-123.123)",
        "trunc(123.123)",
        "trunc(-123.123)",
        "ceil(123.123)",
        "ceil(-123.123)",
        "sqrt(1764)",
        "isnan(sqrt(-1))",
        "not(1)",
        "not(NAN)",
        "not(0)",
        "6.0206dB",
        "-3.0103dB",
        "pow(0,1.23)",
        "pow(PI,1.23)",
        "PI^1.23",
        "pow(-1,1.23)",
        "if(1, 2)",
        "if(1, 1, 2)",
        "if(0, 1, 2)",
        "ifnot(0, 23)",
        "ifnot(1, NaN) + if(0, 1)",
        "ifnot(1, 1, 2)",
        "ifnot(0, 1, 2)",
        "taylor(1, 1)",
        "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)",
        "root(sin(ld(0))-1, 2)",
        "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
        "7000000B*random(0)",
        "squish(2)",
        "gauss(0.1)",
        "hypot(4,3)",
        "gcd(30,55)*print(min(9,1))",
        "bitor(42, 12)",
        "bitand(42, 12)",
        "bitand(NAN, 1)",
        "between(10, -3, 10)",
        "between(-4, -2, -1)",
        "between(1,2)",
        "clip(0, 2, 1)",
        "clip(0/0, 1, 2)",
        "clip(0, 0/0, 1)",
        NULL
    };
    int ret;

    for (expr = exprs; *expr; expr++) {
        printf("Evaluating '%s'\n", *expr);
        ret = av_expr_parse_and_eval(&d, *expr,
                               const_names, const_values,
                               NULL, NULL, NULL, NULL, NULL, 0, NULL);
        if (isnan(d))
            printf("'%s' -> nan\n\n", *expr);
        else
            printf("'%s' -> %f\n\n", *expr, d);
        if (ret < 0)
            printf("av_expr_parse_and_eval failed\n");
    }

    ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
                           const_names, const_values,
                           NULL, NULL, NULL, NULL, NULL, 0, NULL);
    printf("%f == 12.7\n", d);
    if (ret < 0)
        printf("av_expr_parse_and_eval failed\n");
    ret = av_expr_parse_and_eval(&d, "80G/80Gi",
                           const_names, const_values,
                           NULL, NULL, NULL, NULL, NULL, 0, NULL);
    printf("%f == 0.931322575\n", d);
    if (ret < 0)
        printf("av_expr_parse_and_eval failed\n");

    if (argc > 1 && !strcmp(argv[1], "-t")) {
        for (i = 0; i < 1050; i++) {
            START_TIMER;
            ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
                                   const_names, const_values,
                                   NULL, NULL, NULL, NULL, NULL, 0, NULL);
            if (ret < 0)
                printf("av_expr_parse_and_eval failed\n");
            STOP_TIMER("av_expr_parse_and_eval");
        }
    }

    return 0;
}
Beispiel #19
0
int main(int argc, char **argv)
{
    size_t buf_size = 256;
    char *buf = av_malloc(buf_size);
    const char *outfilename = NULL, *infilename = NULL;
    FILE *outfile = NULL, *infile = NULL;
    const char *prompt = "=> ";
    int count = 0, echo = 0;
    char c;

    av_max_alloc(MAX_BLOCK_SIZE);

    while ((c = getopt(argc, argv, "ehi:o:p:")) != -1) {
        switch (c) {
        case 'e':
            echo = 1;
            break;
        case 'h':
            usage();
            return 0;
        case 'i':
            infilename = optarg;
            break;
        case 'o':
            outfilename = optarg;
            break;
        case 'p':
            prompt = optarg;
            break;
        case '?':
            return 1;
        }
    }

    if (!infilename || !strcmp(infilename, "-"))
        infilename = "/dev/stdin";
    infile = fopen(infilename, "r");
    if (!infile) {
        fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
        return 1;
    }

    if (!outfilename || !strcmp(outfilename, "-"))
        outfilename = "/dev/stdout";
    outfile = fopen(outfilename, "w");
    if (!outfile) {
        fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
        return 1;
    }

    while ((c = fgetc(infile)) != EOF) {
        if (c == '\n') {
            double d;

            buf[count] = 0;
            if (buf[0] != '#') {
                av_expr_parse_and_eval(&d, buf,
                                       NULL, NULL,
                                       NULL, NULL, NULL, NULL, NULL, 0, NULL);
                if (echo)
                    fprintf(outfile, "%s ", buf);
                fprintf(outfile, "%s%f\n", prompt, d);
            }
            count = 0;
        } else {
            if (count >= buf_size-1) {
                if (buf_size == MAX_BLOCK_SIZE) {
                    av_log(NULL, AV_LOG_ERROR, "Memory allocation problem, "
                           "max block size '%zd' reached\n", MAX_BLOCK_SIZE);
                    return 1;
                }
                buf_size = FFMIN(buf_size, MAX_BLOCK_SIZE / 2) * 2;
                buf = av_realloc_f((void *)buf, buf_size, 1);
                if (!buf) {
                    av_log(NULL, AV_LOG_ERROR, "Memory allocation problem occurred\n");
                    return 1;
                }
            }
            buf[count++] = c;
        }
    }

    av_free(buf);
    return 0;
}
Beispiel #20
0
int main(int argc, char **argv)
{
    int i;
    double d;
    const char *const *expr;
    static const char *const exprs[] = {
        "",
        "1;2",
        "-20",
        "-PI",
        "+PI",
        "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
        "80G/80Gi",
        "1k",
        "1Gi",
        "1gi",
        "1GiFoo",
        "1k+1k",
        "1Gi*3foo",
        "foo",
        "foo(",
        "foo()",
        "foo)",
        "sin",
        "sin(",
        "sin()",
        "sin)",
        "sin 10",
        "sin(1,2,3)",
        "sin(1 )",
        "1",
        "1foo",
        "bar + PI + E + 100f*2 + foo",
        "13k + 12f - foo(1, 2)",
        "1gi",
        "1Gi",
        "st(0, 123)",
        "st(1, 123); ld(1)",
        "lte(0, 1)",
        "lte(1, 1)",
        "lte(1, 0)",
        "lt(0, 1)",
        "lt(1, 1)",
        "gt(1, 0)",
        "gt(2, 7)",
        "gte(122, 122)",
        /* compute 1+2+...+N */
        "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)",
        /* compute Fib(N) */
        "st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)",
        "while(0, 10)",
        "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
        "isnan(1)",
        "isnan(NAN)",
        "isnan(INF)",
        "isinf(1)",
        "isinf(NAN)",
        "isinf(INF)",
        "floor(NAN)",
        "floor(123.123)",
        "floor(-123.123)",
        "trunc(123.123)",
        "trunc(-123.123)",
        "ceil(123.123)",
        "ceil(-123.123)",
        "sqrt(1764)",
        "isnan(sqrt(-1))",
        "not(1)",
        "not(NAN)",
        "not(0)",
        "6.0206dB",
        "-3.0103dB",
        NULL
    };

    for (expr = exprs; *expr; expr++) {
        printf("Evaluating '%s'\n", *expr);
        av_expr_parse_and_eval(&d, *expr,
                               const_names, const_values,
                               NULL, NULL, NULL, NULL, NULL, 0, NULL);
        if (isnan(d))
            printf("'%s' -> nan\n\n", *expr);
        else
            printf("'%s' -> %f\n\n", *expr, d);
    }

    av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
                           const_names, const_values,
                           NULL, NULL, NULL, NULL, NULL, 0, NULL);
    printf("%f == 12.7\n", d);
    av_expr_parse_and_eval(&d, "80G/80Gi",
                           const_names, const_values,
                           NULL, NULL, NULL, NULL, NULL, 0, NULL);
    printf("%f == 0.931322575\n", d);

    if (argc > 1 && !strcmp(argv[1], "-t")) {
        for (i = 0; i < 1050; i++) {
            START_TIMER;
            av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
                                   const_names, const_values,
                                   NULL, NULL, NULL, NULL, NULL, 0, NULL);
            STOP_TIMER("av_expr_parse_and_eval");
        }
    }

    return 0;
}
static int qsvscale_config_props(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    AVFilterLink *inlink = outlink->src->inputs[0];
    QSVScaleContext  *s = ctx->priv;
    int64_t w, h;
    double var_values[VARS_NB], res;
    char *expr;
    int ret;

    var_values[VAR_PI]    = M_PI;
    var_values[VAR_PHI]   = M_PHI;
    var_values[VAR_E]     = M_E;
    var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;
    var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;
    var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
    var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
    var_values[VAR_A]     = (double) inlink->w / inlink->h;
    var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
    var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];

    /* evaluate width and height */
    av_expr_parse_and_eval(&res, (expr = s->w_expr),
                           var_names, var_values,
                           NULL, NULL, NULL, NULL, NULL, 0, ctx);
    s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
    if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        goto fail;
    s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
    /* evaluate again the width, as it may depend on the output height */
    if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        goto fail;
    s->w = res;

    w = s->w;
    h = s->h;

    /* sanity check params */
    if (w <  -1 || h <  -1) {
        av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
        return AVERROR(EINVAL);
    }
    if (w == -1 && h == -1)
        s->w = s->h = 0;

    if (!(w = s->w))
        w = inlink->w;
    if (!(h = s->h))
        h = inlink->h;
    if (w == -1)
        w = av_rescale(h, inlink->w, inlink->h);
    if (h == -1)
        h = av_rescale(w, inlink->h, inlink->w);

    if (w > INT_MAX || h > INT_MAX ||
        (h * inlink->w) > INT_MAX  ||
        (w * inlink->h) > INT_MAX)
        av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n");

    outlink->w = w;
    outlink->h = h;

    ret = init_scale_session(ctx, inlink->w, inlink->h, w, h);
    if (ret < 0)
        return ret;

    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
           inlink->w, inlink->h, outlink->w, outlink->h);

    if (inlink->sample_aspect_ratio.num)
        outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
                                                             outlink->w*inlink->h},
                                                inlink->sample_aspect_ratio);
    else
        outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;

    return 0;

fail:
    av_log(NULL, AV_LOG_ERROR,
           "Error when evaluating the expression '%s'\n", expr);
    return ret;
}
int main(int argc, char **argv)
{
    int buf_size = 0;
    char *buf = NULL;
    const char *outfilename = NULL, *infilename = NULL;
    FILE *outfile = NULL, *infile = NULL;
    const char *prompt = "=> ";
    int count = 0, echo = 0;
    int c;

#define GROW_ARRAY()                                                    \
    do {                                                                \
        if (!av_dynarray2_add((void **)&buf, &buf_size, 1, NULL)) {     \
            av_log(NULL, AV_LOG_ERROR,                                  \
                   "Memory allocation problem occurred\n");             \
            return 1;                                                   \
        }                                                               \
    } while (0)

    GROW_ARRAY();
    while ((c = getopt(argc, argv, "ehi:o:p:")) != -1) {
        switch (c) {
        case 'e':
            echo = 1;
            break;
        case 'h':
            usage();
            return 0;
        case 'i':
            infilename = optarg;
            break;
        case 'o':
            outfilename = optarg;
            break;
        case 'p':
            prompt = optarg;
            break;
        case '?':
            return 1;
        }
    }

    if (!infilename || !strcmp(infilename, "-")) {
        infilename = "stdin";
        infile = stdin;
    } else {
        infile = fopen(infilename, "r");
    }
    if (!infile) {
        fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
        return 1;
    }

    if (!outfilename || !strcmp(outfilename, "-")) {
        outfilename = "stdout";
        outfile = stdout;
    } else {
        outfile = fopen(outfilename, "w");
    }
    if (!outfile) {
        fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
        return 1;
    }

    while ((c = fgetc(infile)) != EOF) {
        if (c == '\n') {
            double d;

            buf[count] = 0;
            if (buf[0] != '#') {
                int ret = av_expr_parse_and_eval(&d, buf,
                                                 NULL, NULL,
                                                 NULL, NULL, NULL, NULL, NULL, 0, NULL);
                if (echo)
                    fprintf(outfile, "%s ", buf);
                if (ret >= 0) fprintf(outfile, "%s%f\n", prompt, d);
                else          fprintf(outfile, "%s%s\n", prompt, av_err2str(ret));
            }
            count = 0;
        } else {
            if (count >= buf_size-1)
                GROW_ARRAY();
            buf[count++] = c;
        }
    }

    av_free(buf);
    return 0;
}
Beispiel #23
0
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    ZPContext *s = ctx->priv;
    double var_values[VARS_NB], nb_frames, zoom, dx, dy;
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(in->format);
    AVFrame *out;
    int i, k, x, y, w, h, ret = 0;

    var_values[VAR_IN_W]  = var_values[VAR_IW] = in->width;
    var_values[VAR_IN_H]  = var_values[VAR_IH] = in->height;
    var_values[VAR_OUT_W] = var_values[VAR_OW] = s->w;
    var_values[VAR_OUT_H] = var_values[VAR_OH] = s->h;
    var_values[VAR_IN]    = inlink->frame_count + 1;
    var_values[VAR_ON]    = outlink->frame_count + 1;
    var_values[VAR_PX]    = s->x;
    var_values[VAR_PY]    = s->y;
    var_values[VAR_X]     = 0;
    var_values[VAR_Y]     = 0;
    var_values[VAR_PZOOM] = s->prev_zoom;
    var_values[VAR_ZOOM]  = 1;
    var_values[VAR_PDURATION] = s->prev_nb_frames;
    var_values[VAR_A]     = (double) in->width / in->height;
    var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
    var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];
    var_values[VAR_HSUB]  = 1 << desc->log2_chroma_w;
    var_values[VAR_VSUB]  = 1 << desc->log2_chroma_h;

    if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str,
                                      var_names, var_values,
                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
        goto fail;

    var_values[VAR_DURATION] = nb_frames;
    for (i = 0; i < nb_frames; i++) {
        int px[4];
        int py[4];
        uint8_t *input[4];
        int64_t pts = av_rescale_q(in->pts, inlink->time_base,
                                   outlink->time_base) + s->frame_count;

        var_values[VAR_TIME] = pts * av_q2d(outlink->time_base);
        var_values[VAR_FRAME] = i;
        var_values[VAR_ON] = outlink->frame_count + 1;
        if ((ret = av_expr_parse_and_eval(&zoom, s->zoom_expr_str,
                                          var_names, var_values,
                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
            goto fail;

        zoom = av_clipd(zoom, 1, 10);
        var_values[VAR_ZOOM] = zoom;
        w = in->width * (1.0 / zoom);
        h = in->height * (1.0 / zoom);

        if ((ret = av_expr_parse_and_eval(&dx, s->x_expr_str,
                                          var_names, var_values,
                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
            goto fail;
        x = dx = av_clipd(dx, 0, FFMAX(in->width - w, 0));
        var_values[VAR_X] = dx;
        x &= ~((1 << desc->log2_chroma_w) - 1);

        if ((ret = av_expr_parse_and_eval(&dy, s->y_expr_str,
                                          var_names, var_values,
                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
            goto fail;
        y = dy = av_clipd(dy, 0, FFMAX(in->height - h, 0));
        var_values[VAR_Y] = dy;
        y &= ~((1 << desc->log2_chroma_h) - 1);

        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
        if (!out) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        px[1] = px[2] = FF_CEIL_RSHIFT(x, desc->log2_chroma_w);
        px[0] = px[3] = x;

        py[1] = py[2] = FF_CEIL_RSHIFT(y, desc->log2_chroma_h);
        py[0] = py[3] = y;

        s->sws = sws_alloc_context();
        if (!s->sws) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

        for (k = 0; in->data[k]; k++)
            input[k] = in->data[k] + py[k] * in->linesize[k] + px[k];

        av_opt_set_int(s->sws, "srcw", w, 0);
        av_opt_set_int(s->sws, "srch", h, 0);
        av_opt_set_int(s->sws, "src_format", in->format, 0);
        av_opt_set_int(s->sws, "dstw", outlink->w, 0);
        av_opt_set_int(s->sws, "dsth", outlink->h, 0);
        av_opt_set_int(s->sws, "dst_format", outlink->format, 0);
        av_opt_set_int(s->sws, "sws_flags", SWS_BICUBIC, 0);

        if ((ret = sws_init_context(s->sws, NULL, NULL)) < 0)
            goto fail;

        sws_scale(s->sws, (const uint8_t *const *)&input, in->linesize, 0, h, out->data, out->linesize);

        out->pts = pts;
        s->frame_count++;

        ret = ff_filter_frame(outlink, out);
        if (ret < 0)
            break;

        sws_freeContext(s->sws);
        s->sws = NULL;
    }

    s->x = dx;
    s->y = dy;
    s->prev_zoom = zoom;
    s->prev_nb_frames = nb_frames;

fail:
    sws_freeContext(s->sws);
    s->sws = NULL;
    av_frame_free(&in);
    return ret;
}
Beispiel #24
0
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    SwapRectContext *s = ctx->priv;
    double var_values[VAR_VARS_NB];
    int x1[4], y1[4];
    int x2[4], y2[4];
    int aw[4], ah[4];
    int lw[4], lh[4];
    int pw[4], ph[4];
    double dw,  dh;
    double dx1, dy1;
    double dx2, dy2;
    int y, p, w, h, ret;

    var_values[VAR_W]   = inlink->w;
    var_values[VAR_H]   = inlink->h;
    var_values[VAR_A]   = (float) inlink->w / inlink->h;
    var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
    var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR];
    var_values[VAR_N]   = inlink->frame_count_out;
    var_values[VAR_T]   = in->pts == AV_NOPTS_VALUE ? NAN : in->pts * av_q2d(inlink->time_base);
    var_values[VAR_POS] = av_frame_get_pkt_pos(in) == -1 ? NAN : av_frame_get_pkt_pos(in);

    ret = av_expr_parse_and_eval(&dw, s->w,
                                 var_names, &var_values[0],
                                 NULL, NULL, NULL, NULL,
                                 0, 0, ctx);
    if (ret < 0)
        return ret;

    ret = av_expr_parse_and_eval(&dh, s->h,
                                 var_names, &var_values[0],
                                 NULL, NULL, NULL, NULL,
                                 0, 0, ctx);
    if (ret < 0)
        return ret;

    ret = av_expr_parse_and_eval(&dx1, s->x1,
                                 var_names, &var_values[0],
                                 NULL, NULL, NULL, NULL,
                                 0, 0, ctx);
    if (ret < 0)
        return ret;

    ret = av_expr_parse_and_eval(&dy1, s->y1,
                                 var_names, &var_values[0],
                                 NULL, NULL, NULL, NULL,
                                 0, 0, ctx);
    if (ret < 0)
        return ret;

    ret = av_expr_parse_and_eval(&dx2, s->x2,
                                 var_names, &var_values[0],
                                 NULL, NULL, NULL, NULL,
                                 0, 0, ctx);
    if (ret < 0)
        return ret;

    ret = av_expr_parse_and_eval(&dy2, s->y2,
                                 var_names, &var_values[0],
                                 NULL, NULL, NULL, NULL,
                                 0, 0, ctx);
    if (ret < 0)
        return ret;

    w = dw; h = dh; x1[0] = dx1; y1[0] = dy1; x2[0] = dx2; y2[0] = dy2;

    x1[0] = av_clip(x1[0], 0, inlink->w - 1);
    y1[0] = av_clip(y1[0], 0, inlink->w - 1);

    x2[0] = av_clip(x2[0], 0, inlink->w - 1);
    y2[0] = av_clip(y2[0], 0, inlink->w - 1);

    ah[1] = ah[2] = FF_CEIL_RSHIFT(h, s->desc->log2_chroma_h);
    ah[0] = ah[3] = h;
    aw[1] = aw[2] = FF_CEIL_RSHIFT(w, s->desc->log2_chroma_w);
    aw[0] = aw[3] = w;

    w = FFMIN3(w, inlink->w - x1[0], inlink->w - x2[0]);
    h = FFMIN3(h, inlink->h - y1[0], inlink->h - y2[0]);

    ph[1] = ph[2] = FF_CEIL_RSHIFT(h, s->desc->log2_chroma_h);
    ph[0] = ph[3] = h;
    pw[1] = pw[2] = FF_CEIL_RSHIFT(w, s->desc->log2_chroma_w);
    pw[0] = pw[3] = w;

    lh[1] = lh[2] = FF_CEIL_RSHIFT(inlink->h, s->desc->log2_chroma_h);
    lh[0] = lh[3] = inlink->h;
    lw[1] = lw[2] = FF_CEIL_RSHIFT(inlink->w, s->desc->log2_chroma_w);
    lw[0] = lw[3] = inlink->w;

    x1[1] = x1[2] = FF_CEIL_RSHIFT(x1[0], s->desc->log2_chroma_w);
    x1[0] = x1[3] = x1[0];
    y1[1] = y1[2] = FF_CEIL_RSHIFT(y1[0], s->desc->log2_chroma_h);
    y1[0] = y1[3] = y1[0];

    x2[1] = x2[2] = FF_CEIL_RSHIFT(x2[0], s->desc->log2_chroma_w);
    x2[0] = x2[3] = x2[0];
    y2[1] = y2[2] = FF_CEIL_RSHIFT(y2[0], s->desc->log2_chroma_h);
    y2[0] = y2[3] = y2[0];

    for (p = 0; p < s->nb_planes; p++) {
        if (ph[p] == ah[p] && pw[p] == aw[p]) {
            uint8_t *src = in->data[p] + y1[p] * in->linesize[p] + x1[p] * s->pixsteps[p];
            uint8_t *dst = in->data[p] + y2[p] * in->linesize[p] + x2[p] * s->pixsteps[p];

            for (y = 0; y < ph[p]; y++) {
                memcpy(s->temp, src, pw[p] * s->pixsteps[p]);
                memmove(src, dst, pw[p] * s->pixsteps[p]);
                memcpy(dst, s->temp, pw[p] * s->pixsteps[p]);
                src += in->linesize[p];
                dst += in->linesize[p];
            }
        }
    }

    return ff_filter_frame(outlink, in);
}
Beispiel #25
0
static int activate(AVFilterContext *ctx)
{
    ZPContext *s = ctx->priv;
    AVFilterLink *inlink = ctx->inputs[0];
    AVFilterLink *outlink = ctx->outputs[0];
    int status, ret = 0;
    int64_t pts;

    if (s->in && ff_outlink_frame_wanted(outlink)) {
        double zoom = -1, dx = -1, dy = -1;

        ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame,
                                  &zoom, &dx, &dy);
        if (ret < 0)
            return ret;
    }

    if (!s->in && (ret = ff_inlink_consume_frame(inlink, &s->in)) > 0) {
        double zoom = -1, dx = -1, dy = -1, nb_frames;

        s->finished = 0;
        s->var_values[VAR_IN_W]  = s->var_values[VAR_IW] = s->in->width;
        s->var_values[VAR_IN_H]  = s->var_values[VAR_IH] = s->in->height;
        s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w;
        s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h;
        s->var_values[VAR_IN]    = inlink->frame_count_out + 1;
        s->var_values[VAR_ON]    = outlink->frame_count_in + 1;
        s->var_values[VAR_PX]    = s->x;
        s->var_values[VAR_PY]    = s->y;
        s->var_values[VAR_X]     = 0;
        s->var_values[VAR_Y]     = 0;
        s->var_values[VAR_PZOOM] = s->prev_zoom;
        s->var_values[VAR_ZOOM]  = 1;
        s->var_values[VAR_PDURATION] = s->prev_nb_frames;
        s->var_values[VAR_A]     = (double) s->in->width / s->in->height;
        s->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
            (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
        s->var_values[VAR_DAR]   = s->var_values[VAR_A] * s->var_values[VAR_SAR];
        s->var_values[VAR_HSUB]  = 1 << s->desc->log2_chroma_w;
        s->var_values[VAR_VSUB]  = 1 << s->desc->log2_chroma_h;

        if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str,
                                          var_names, s->var_values,
                                          NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
            av_frame_free(&s->in);
            return ret;
        }

        s->var_values[VAR_DURATION] = s->nb_frames = nb_frames;

        ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame,
                                  &zoom, &dx, &dy);
        if (ret < 0)
            return ret;
    }
    if (ret < 0) {
        return ret;
    } else if (s->finished && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
        ff_outlink_set_status(outlink, status, pts);
        return 0;
    } else {
        if (ff_outlink_frame_wanted(outlink) && s->finished)
            ff_inlink_request_frame(inlink);
        return 0;
    }
}