diff options
author | Paul B Mahol <onemda@gmail.com> | 2022-03-07 14:01:11 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2022-03-07 15:29:39 +0100 |
commit | 7238541d3969f3ddfede80e01da7a82ad7d69190 (patch) | |
tree | b524ead319ee93df165b8558778216bd644df35e /libavfilter/vf_extractplanes.c | |
parent | 0f5c964c5737170cd52c2a9501e81ea12946a66d (diff) | |
download | ffmpeg-7238541d3969f3ddfede80e01da7a82ad7d69190.tar.gz |
avfilter/vf_extractplanes: switch to activate()
Fixes hang at end of input with this command:
ffmpeg -f lavfi -i testsrc2=d=50,format=yuv444p -lavfi \
"extractplanes=y+u+v[y][u][v];[y]tpad=start=0[y];[u]tpad=start=0[u];[v]negate[v];[y][u][v]vstack=3" -f null -
Diffstat (limited to 'libavfilter/vf_extractplanes.c')
-rw-r--r-- | libavfilter/vf_extractplanes.c | 105 |
1 files changed, 68 insertions, 37 deletions
diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c index 5b5fd6e232..0b26d92269 100644 --- a/libavfilter/vf_extractplanes.c +++ b/libavfilter/vf_extractplanes.c @@ -288,52 +288,82 @@ static void extract_from_packed(uint8_t *dst, int dst_linesize, } } -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) +static int extract_plane(AVFilterLink *outlink, AVFrame *frame) { - AVFilterContext *ctx = inlink->dst; + AVFilterContext *ctx = outlink->src; ExtractPlanesContext *s = ctx->priv; - int i, eof = 0, ret = 0; + const int idx = s->map[FF_OUTLINK_IDX(outlink)]; + AVFrame *out; + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) + return AVERROR(ENOMEM); + av_frame_copy_props(out, frame); + + if (s->is_packed) { + extract_from_packed(out->data[0], out->linesize[0], + frame->data[0], frame->linesize[0], + outlink->w, outlink->h, + s->depth, + s->step, idx); + } else { + av_image_copy_plane(out->data[0], out->linesize[0], + frame->data[idx], frame->linesize[idx], + s->linesize[idx], outlink->h); + } - for (i = 0; i < ctx->nb_outputs; i++) { - AVFilterLink *outlink = ctx->outputs[i]; - const int idx = s->map[i]; - AVFrame *out; + return ff_filter_frame(outlink, out); +} - if (ff_outlink_get_status(outlink)) - continue; +static int activate(AVFilterContext *ctx) +{ + AVFilterLink *inlink = ctx->inputs[0]; + int status, ret; + AVFrame *in; + int64_t pts; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - ret = AVERROR(ENOMEM); - break; + for (int i = 0; i < ctx->nb_outputs; i++) { + FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[i], ctx); + } + + ret = ff_inlink_consume_frame(inlink, &in); + if (ret < 0) + return ret; + if (ret > 0) { + for (int i = 0; i < ctx->nb_outputs; i++) { + if (ff_outlink_get_status(ctx->outputs[i])) + continue; + + ret = extract_plane(ctx->outputs[i], in); + if (ret < 0) + break; } - av_frame_copy_props(out, frame); - - if (s->is_packed) { - extract_from_packed(out->data[0], out->linesize[0], - frame->data[0], frame->linesize[0], - outlink->w, outlink->h, - s->depth, - s->step, idx); - } else { - av_image_copy_plane(out->data[0], out->linesize[0], - frame->data[idx], frame->linesize[idx], - s->linesize[idx], outlink->h); + + av_frame_free(&in); + if (ret < 0) + return ret; + } + + if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { + for (int i = 0; i < ctx->nb_outputs; i++) { + if (ff_outlink_get_status(ctx->outputs[i])) + continue; + ff_outlink_set_status(ctx->outputs[i], status, pts); } + return 0; + } - ret = ff_filter_frame(outlink, out); - if (ret == AVERROR_EOF) - eof++; - else if (ret < 0) - break; + for (int i = 0; i < ctx->nb_outputs; i++) { + if (ff_outlink_get_status(ctx->outputs[i])) + continue; + + if (ff_outlink_frame_wanted(ctx->outputs[i])) { + ff_inlink_request_frame(inlink); + return 0; + } } - av_frame_free(&frame); - if (eof == ctx->nb_outputs) - ret = AVERROR_EOF; - else if (ret == AVERROR_EOF) - ret = 0; - return ret; + return FFERROR_NOT_READY; } static av_cold int init(AVFilterContext *ctx) @@ -368,7 +398,6 @@ static const AVFilterPad extractplanes_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, .config_props = config_input, }, }; @@ -379,6 +408,7 @@ const AVFilter ff_vf_extractplanes = { .priv_size = sizeof(ExtractPlanesContext), .priv_class = &extractplanes_class, .init = init, + .activate = activate, FILTER_INPUTS(extractplanes_inputs), .outputs = NULL, FILTER_QUERY_FUNC(query_formats), @@ -411,6 +441,7 @@ const AVFilter ff_vf_alphaextract = { "grayscale image component."), .priv_size = sizeof(ExtractPlanesContext), .init = init_alphaextract, + .activate = activate, FILTER_INPUTS(extractplanes_inputs), FILTER_OUTPUTS(alphaextract_outputs), FILTER_QUERY_FUNC(query_formats), |