Exemple #1
0
static int check_frame(struct sxplayer_frame *f, double t, int opt_test_flags)
{
    const double skip          = (opt_test_flags & FLAG_SKIP)          ? TESTVAL_SKIP          :  0;
    const double trim_duration = (opt_test_flags & FLAG_TRIM_DURATION) ? TESTVAL_TRIM_DURATION : -1;
    const double playback_time = av_clipd(t, 0, trim_duration < 0 ? DBL_MAX : trim_duration);

    const double frame_ts = f ? f->ts : -1;
    const double estimated_time_from_ts = frame_ts - skip;
    const double diff_ts = fabs(playback_time - estimated_time_from_ts);

    if (!f) {
        fprintf(stderr, "no frame obtained for t=%f\n", t);
        return -1;
    }

    if (!(opt_test_flags & FLAG_AUDIO)) {
        const uint32_t c = *(const uint32_t *)f->data;
        const int r = c >> (N+16) & 0xf;
        const int g = c >> (N+ 8) & 0xf;
        const int b = c >> (N+ 0) & 0xf;
        const int frame_id = r<<(N*2) | g<<N | b;

        const double video_ts = frame_id * 1. / SOURCE_FPS;
        const double estimated_time_from_color = video_ts - skip;
        const double diff_color = fabs(playback_time - estimated_time_from_color);

        if (diff_color > 1./SOURCE_FPS) {
            fprintf(stderr, "requested t=%f (clipped to %f with trim_duration=%f),\n"
                    "got video_ts=%f (frame id #%d), corresponding to t=%f (with skip=%f)\n"
                    "diff_color: %f\n",
                    t, playback_time, trim_duration,
                    video_ts, frame_id, estimated_time_from_color, skip,
                    diff_color);
            return -1;
        }
    }
    if (diff_ts > 1./SOURCE_FPS) {
        fprintf(stderr, "requested t=%f (clipped to %f with trim_duration=%f),\n"
                "got frame_ts=%f, corresponding to t=%f (with skip=%f)\n"
                "diff_ts: %f\n",
                t, playback_time, trim_duration,
                frame_ts, estimated_time_from_ts, skip,
                diff_ts);
        return -1;
    }
    return 0;
}
Exemple #2
0
static void filter_dblp(void **d, void **p, const void **s,
                        int nb_samples, int channels,
                        float mult, int clip)
{
    int n, c;

    for (c = 0; c < channels; c++) {
        const double *src = s[c];
        double *dst = d[c];
        double *prv = p[c];

        for (n = 0; n < nb_samples; n++) {
            double current = src[n];

            dst[n] = current + (current - prv[0]) * mult;
            prv[0] = current;
            if (clip) {
                dst[n] = av_clipd(dst[n], -1, 1);
            }
        }
    }
}
Exemple #3
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;
}
Exemple #4
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;
}
Exemple #5
0
static int plot_freqs(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    AVFilterLink *outlink = ctx->outputs[0];
    ShowFreqsContext *s = ctx->priv;
    const int win_size = s->win_size;
    char *colors, *color, *saveptr = NULL;
    AVFrame *out;
    int ch, n;

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

    for (n = 0; n < outlink->h; n++)
        memset(out->data[0] + out->linesize[0] * n, 0, outlink->w * 4);

    /* fill FFT input with the number of samples available */
    for (ch = 0; ch < s->nb_channels; ch++) {
        const float *p = (float *)in->extended_data[ch];

        for (n = 0; n < in->nb_samples; n++) {
            s->fft_data[ch][n].re = p[n] * s->window_func_lut[n];
            s->fft_data[ch][n].im = 0;
        }
        for (; n < win_size; n++) {
            s->fft_data[ch][n].re = 0;
            s->fft_data[ch][n].im = 0;
        }
    }

    /* run FFT on each samples set */
    for (ch = 0; ch < s->nb_channels; ch++) {
        av_fft_permute(s->fft, s->fft_data[ch]);
        av_fft_calc(s->fft, s->fft_data[ch]);
    }

#define RE(x, ch) s->fft_data[ch][x].re
#define IM(x, ch) s->fft_data[ch][x].im
#define M(a, b) (sqrt((a) * (a) + (b) * (b)))

    colors = av_strdup(s->colors);
    if (!colors) {
        av_frame_free(&out);
        return AVERROR(ENOMEM);
    }

    for (ch = 0; ch < s->nb_channels; ch++) {
        uint8_t fg[4] = { 0xff, 0xff, 0xff, 0xff };
        int prev_y = -1, f;
        double a;

        color = av_strtok(ch == 0 ? colors : NULL, " |", &saveptr);
        if (color)
            av_parse_color(fg, color, -1, ctx);

        a = av_clipd(M(RE(0, ch), 0) / s->scale, 0, 1);
        plot_freq(s, ch, a, 0, fg, &prev_y, out, outlink);

        for (f = 1; f < s->nb_freq; f++) {
            a = av_clipd(M(RE(f, ch), IM(f, ch)) / s->scale, 0, 1);

            plot_freq(s, ch, a, f, fg, &prev_y, out, outlink);
        }
    }

    av_free(colors);
    out->pts = in->pts;
    return ff_filter_frame(outlink, out);
}
Exemple #6
0
static inline void plot_freq(ShowFreqsContext *s, int ch,
                             double a, int f, uint8_t fg[4], int *prev_y,
                             AVFrame *out, AVFilterLink *outlink)
{
    const int w = s->w;
    const float avg = s->avg_data[ch][f];
    const float bsize = get_bsize(s, f);
    const int sx = get_sx(s, f);
    int end = outlink->h;
    int x, y, i;

    switch(s->ascale) {
    case AS_SQRT:
        a = 1.0 - sqrt(a);
        break;
    case AS_CBRT:
        a = 1.0 - cbrt(a);
        break;
    case AS_LOG:
        a = log(av_clipd(a, 1e-6, 1)) / log(1e-6);
        break;
    case AS_LINEAR:
        a = 1.0 - a;
        break;
    }

    switch (s->cmode) {
    case COMBINED:
        y = a * outlink->h - 1;
        break;
    case SEPARATE:
        end = (outlink->h / s->nb_channels) * (ch + 1);
        y = (outlink->h / s->nb_channels) * ch + a * (outlink->h / s->nb_channels) - 1;
        break;
    }
    if (y < 0)
        return;

    switch (s->avg) {
    case 0:
        y = s->avg_data[ch][f] = !outlink->frame_count ? y : FFMIN(avg, y);
        break;
    case 1:
        break;
    default:
        s->avg_data[ch][f] = avg + y * (y - avg) / (FFMIN(outlink->frame_count + 1, s->avg) * y);
        y = s->avg_data[ch][f];
        break;
    }

    switch(s->mode) {
    case LINE:
        if (*prev_y == -1) {
            *prev_y = y;
        }
        if (y <= *prev_y) {
            for (x = sx + 1; x < sx + bsize && x < w; x++)
                draw_dot(out, x, y, fg);
            for (i = y; i <= *prev_y; i++)
                draw_dot(out, sx, i, fg);
        } else {
            for (i = *prev_y; i <= y; i++)
                draw_dot(out, sx, i, fg);
            for (x = sx + 1; x < sx + bsize && x < w; x++)
                draw_dot(out, x, i - 1, fg);
        }
        *prev_y = y;
        break;
    case BAR:
        for (x = sx; x < sx + bsize && x < w; x++)
            for (i = y; i < end; i++)
                draw_dot(out, x, i, fg);
        break;
    case DOT:
        for (x = sx; x < sx + bsize && x < w; x++)
            draw_dot(out, x, y, fg);
        break;
    }
}