static int process_frame(FFFrameSync *fs)
{
    AVFilterContext *ctx = fs->parent;
    ThresholdContext *s = fs->opaque;
    AVFilterLink *outlink = ctx->outputs[0];
    AVFrame *out, *in, *threshold, *min, *max;
    int ret;

    if ((ret = ff_framesync_get_frame(&s->fs, 0, &in,        0)) < 0 ||
        (ret = ff_framesync_get_frame(&s->fs, 1, &threshold, 0)) < 0 ||
        (ret = ff_framesync_get_frame(&s->fs, 2, &min,       0)) < 0 ||
        (ret = ff_framesync_get_frame(&s->fs, 3, &max,       0)) < 0)
        return ret;

    if (ctx->is_disabled) {
        out = av_frame_clone(in);
        if (!out)
            return AVERROR(ENOMEM);
    } else {
        int p;

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

        for (p = 0; p < s->nb_planes; p++) {
            if (!(s->planes & (1 << p))) {
                av_image_copy_plane(out->data[p], out->linesize[p],
                                    in->data[p], in->linesize[p],
                                    s->width[p] * s->bpc,
                                    s->height[p]);
                continue;
            }
            s->threshold(in->data[p], threshold->data[p],
                         min->data[p], max->data[p],
                         out->data[p],
                         in->linesize[p], threshold->linesize[p],
                         min->linesize[p], max->linesize[p],
                         out->linesize[p],
                         s->width[p], s->height[p]);
        }
    }

    out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);

    return ff_filter_frame(outlink, out);
}
Пример #2
0
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
    ThresholdContext *s = ctx->priv;
    ThreadData *td = arg;
    AVFrame *min = td->min;
    AVFrame *max = td->max;
    AVFrame *threshold = td->threshold;
    AVFrame *in = td->in;
    AVFrame *out = td->out;

    for (int p = 0; p < s->nb_planes; p++) {
        const int h = s->height[p];
        const int slice_start = (h * jobnr) / nb_jobs;
        const int slice_end = (h * (jobnr+1)) / nb_jobs;

        if (!(s->planes & (1 << p))) {
            av_image_copy_plane(out->data[p] + slice_start * out->linesize[p],
                                out->linesize[p],
                                in->data[p] + slice_start * in->linesize[p],
                                in->linesize[p],
                                s->width[p] * s->bpc,
                                slice_end - slice_start);
            continue;
        }
        s->threshold(in->data[p] + slice_start * in->linesize[p],
                     threshold->data[p] + slice_start * threshold->linesize[p],
                     min->data[p] + slice_start * min->linesize[p],
                     max->data[p] + slice_start * max->linesize[p],
                     out->data[p] + slice_start * out->linesize[p],
                     in->linesize[p], threshold->linesize[p],
                     min->linesize[p], max->linesize[p],
                     out->linesize[p],
                     s->width[p], slice_end - slice_start);
    }

    return 0;
}