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); }
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; }