History

lavfi/vf_libplacebo: generalize frame update to multiple inputs

In the event that some frame mixes are OK while others are not, the priority goes: 1. Errors in updating any frame -> return error 2. Any input incomplete -> request frames and return 3. Any inputs OK -> ignore EOF streams and render remaining inputs 4. No inputs OK -> set output to most recent status This logic ensures that we can continue rendering the remaining streams, no matter which streams reach their end of life, until we have no streams left at which point we forward the last EOF.

Niklas Haas committed 3 years ago

Commit d6250101 parent 6c41c3f1 file · +34 −18Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/vf_libplacebo.c+34−18
@@ -980,9 +980,8 @@ static void drain_input_pts(LibplaceboInput *in, int64_t until) · 979 unmodified lines
980980
981981 static int libplacebo_activate(AVFilterContext *ctx)
982982 {
983− int ret, retry = 0;
983+ int ret, ok = 0, retry = 0;
984984 LibplaceboContext *s = ctx->priv;
985− LibplaceboInput *in = &s->inputs[0];
986985 AVFilterLink *outlink = ctx->outputs[0];
987986 int64_t pts, out_pts;
988987
@@ -1014,26 +1013,43 @@ static int libplacebo_activate(AVFilterContext *ctx) · 25 unmodified lines
10141013 return 0;
10151014 }
10161015
1017− if (s->status && out_pts >= s->status_pts) {
1018− ff_outlink_set_status(outlink, s->status, s->status_pts);
1019− return 0;
1020− }
1016+ /* Update all input queues to the chosen out_pts */
1017+ for (int i = 0; i < s->nb_inputs; i++) {
1018+ LibplaceboInput *in = &s->inputs[i];
1019+ if (in->status && out_pts >= in->status_pts) {
1020+ in->qstatus = PL_QUEUE_EOF;
1021+ continue;
1022+ }
10211023
1022− in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
1023− .pts = out_pts * av_q2d(outlink->time_base),
1024− .radius = pl_frame_mix_radius(&s->params),
1025− .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
1026− ));
1024+ in->qstatus = pl_queue_update(in->queue, &in->mix, pl_queue_params(
1025+ .pts = out_pts * av_q2d(outlink->time_base),
1026+ .radius = pl_frame_mix_radius(&s->params),
1027+ .vsync_duration = av_q2d(av_inv_q(outlink->frame_rate)),
1028+ ));
1029+
1030+ switch (in->qstatus) {
1031+ case PL_QUEUE_MORE:
1032+ ff_inlink_request_frame(in->link);
1033+ retry = true;
1034+ break;
1035+ case PL_QUEUE_OK:
1036+ ok = true;
1037+ break;
1038+ case PL_QUEUE_ERR:
1039+ return AVERROR_EXTERNAL;
1040+ }
1041+ }
10271042
1028− switch (in->qstatus) {
1029− case PL_QUEUE_MORE:
1030− ff_inlink_request_frame(in->link);
1043+ if (retry) {
10311044 return 0;
1032− case PL_QUEUE_OK:
1033− drain_input_pts(in, out_pts);
1045+ } else if (ok) {
1046+ /* Got any valid frame mixes, drain PTS queue and render output */
1047+ for (int i = 0; i < s->nb_inputs; i++)
1048+ drain_input_pts(&s->inputs[i], out_pts);
10341049 return output_frame(ctx, out_pts);
1035− case PL_QUEUE_ERR:
1036− return AVERROR_EXTERNAL;
1050+ } else if (s->status) {
1051+ ff_outlink_set_status(outlink, s->status, s->status_pts);
1052+ return 0;
10371053 }
10381054
10391055 return AVERROR_BUG;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t