Commit c2c30b7b30 for ffmpeg
commit c2c30b7b308e7e70beb5a5ef4f3629c1cc737e29
Author: James Almer <jamrial@gmail.com>
Date: Wed Oct 21 16:32:46 2026 -0300
fftools/ffmpeg_filer: ensure all internal filtergraphs are removed if their outputs are unbound
If an internal filtergraph that's removed references another internal
filtergraph, we need to do another dry run to ensure said internal filtegraphs
it referenced are still needed.
Signed-off-by: James Almer <jamrial@gmail.com>
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 232ffbfff4..25c930f138 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -199,6 +199,8 @@ typedef struct OutputFilterPriv {
void *log_parent;
char log_name[32];
+#define NEEDED_EXPLICIT 1
+#define NEEDED_INTERNAL 2
int needed;
/* desired output stream properties */
@@ -921,7 +923,8 @@ int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc,
av_assert0(!opts->enc ||
ofilter->type == opts->enc->type);
- ofp->needed = ofilter->bound = 1;
+ ofp->needed = NEEDED_EXPLICIT;
+ ofilter->bound = 1;
av_freep(&ofilter->linklabel);
ofp->flags |= opts->flags;
@@ -1043,7 +1046,7 @@ static int ofilter_bind_ifilter(OutputFilter *ofilter, InputFilterPriv *ifp,
av_assert0(!ofilter->bound);
av_assert0(ofilter->type == ifp->ifilter.type);
- ofp->needed = ofilter->bound = 1;
+ ofilter->bound = 1;
av_freep(&ofilter->linklabel);
ofilter->output_name = av_strdup(opts->name);
@@ -1469,7 +1472,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter, int comm
return ret;
}
} else
- ofp_from_ofilter(ofilter)->needed = 1;
+ ofp_from_ofilter(ofilter)->needed = NEEDED_INTERNAL;
return 0;
}
}
@@ -1544,7 +1547,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter, int comm
return ret;
}
} else
- ofp_from_ofilter(ofilter)->needed = 1;
+ ofp_from_ofilter(ofilter)->needed = NEEDED_INTERNAL;
return 0;
}
}
@@ -1601,13 +1604,21 @@ int fg_finalise_bindings(void)
{
int ret;
+retry:
+ for (int i = 0; i < nb_filtergraphs; i++) {
+ FilterGraph *fg = filtergraphs[i];
+ for (int j = 0; j < fg->nb_outputs; j++) {
+ OutputFilter *output = fg->outputs[j];
+ ofp_from_ofilter(output)->needed &= ~NEEDED_INTERNAL;
+ }
+ }
for (int i = 0; i < nb_filtergraphs; i++) {
ret = bind_inputs(filtergraphs[i], 0);
if (ret < 0)
return ret;
}
- // check that all outputs were bound
+ // check that all outputs were marked as needed to be bound
for (int i = nb_filtergraphs - 1; i >= 0; i--) {
FilterGraph *fg = filtergraphs[i];
FilterGraphPriv *fgp = fgp_from_fg(filtergraphs[i]);
@@ -1634,7 +1645,7 @@ int fg_finalise_bindings(void)
memmove(&filtergraphs[i],
&filtergraphs[i + 1],
(nb_filtergraphs - i) * sizeof(*filtergraphs));
- break;
+ goto retry;
}
}
}