static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { AVFilterContext *ctx = inlink->dst; AlphaMergeContext *merge = ctx->priv; int ret = 0; int is_alpha = (inlink == ctx->inputs[1]); struct FFBufQueue *queue = (is_alpha ? &merge->queue_alpha : &merge->queue_main); ff_bufqueue_add(ctx, queue, buf); do { AVFrame *main_buf, *alpha_buf; if (!ff_bufqueue_peek(&merge->queue_main, 0) || !ff_bufqueue_peek(&merge->queue_alpha, 0)) break; main_buf = ff_bufqueue_get(&merge->queue_main); alpha_buf = ff_bufqueue_get(&merge->queue_alpha); merge->frame_requested = 0; draw_frame(ctx, main_buf, alpha_buf); ret = ff_filter_frame(ctx->outputs[0], main_buf); av_frame_free(&alpha_buf); } while (ret >= 0); return ret; }
static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AlphaMergeContext *merge = ctx->priv; int is_alpha = (inlink == ctx->inputs[1]); struct FFBufQueue *queue = (is_alpha ? &merge->queue_alpha : &merge->queue_main); ff_bufqueue_add(ctx, queue, inlink->cur_buf); inlink->cur_buf = NULL; while (1) { AVFilterBufferRef *main_buf, *alpha_buf; if (!ff_bufqueue_peek(&merge->queue_main, 0) || !ff_bufqueue_peek(&merge->queue_alpha, 0)) break; main_buf = ff_bufqueue_get(&merge->queue_main); alpha_buf = ff_bufqueue_get(&merge->queue_alpha); ctx->outputs[0]->out_buf = main_buf; ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(main_buf, ~0)); merge->frame_requested = 0; draw_frame(ctx, main_buf, alpha_buf); ff_end_frame(ctx->outputs[0]); avfilter_unref_buffer(alpha_buf); } return 0; }
static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; AlphaMergeContext *merge = ctx->priv; int in, ret; merge->frame_requested = 1; while (merge->frame_requested) { in = ff_bufqueue_peek(&merge->queue_main, 0) ? 1 : 0; ret = ff_request_frame(ctx->inputs[in]); if (ret < 0) return ret; } return 0; }
static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; ATADenoiseContext *s = ctx->priv; int ret = 0; ret = ff_request_frame(ctx->inputs[0]); if (ret == AVERROR_EOF && !ctx->is_disabled && s->available) { AVFrame *buf = av_frame_clone(ff_bufqueue_peek(&s->q, s->available)); if (!buf) return AVERROR(ENOMEM); ret = filter_frame(ctx->inputs[0], buf); s->available--; } return ret; }
static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; ATADenoiseContext *s = ctx->priv; AVFrame *out, *in; int i; if (s->q.available != s->size) { if (s->q.available < s->mid) { for (i = 0; i < s->mid; i++) { out = av_frame_clone(buf); if (!out) { av_frame_free(&buf); return AVERROR(ENOMEM); } ff_bufqueue_add(ctx, &s->q, out); } } if (s->q.available < s->size) { ff_bufqueue_add(ctx, &s->q, buf); s->available++; } return 0; } in = ff_bufqueue_peek(&s->q, s->mid); if (!ctx->is_disabled) { ThreadData td; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { av_frame_free(&buf); return AVERROR(ENOMEM); } for (i = 0; i < s->size; i++) { AVFrame *frame = ff_bufqueue_peek(&s->q, i); s->data[0][i] = frame->data[0]; s->data[1][i] = frame->data[1]; s->data[2][i] = frame->data[2]; s->linesize[0][i] = frame->linesize[0]; s->linesize[1][i] = frame->linesize[1]; s->linesize[2][i] = frame->linesize[2]; } td.in = in; td.out = out; ctx->internal->execute(ctx, s->filter_slice, &td, NULL, FFMIN3(s->planeheight[1], s->planeheight[2], ff_filter_get_nb_threads(ctx))); av_frame_copy_props(out, in); } else { out = av_frame_clone(in); if (!out) { av_frame_free(&buf); return AVERROR(ENOMEM); } } in = ff_bufqueue_get(&s->q); av_frame_free(&in); ff_bufqueue_add(ctx, &s->q, buf); return ff_filter_frame(outlink, out); }