1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-10-06 05:47:18 +02:00

fftools/ffmpeg_sched: choke inputs during filtergraph configuration

Currently, while the filter graph is being initially created, the scheduler
continues demuxing frames on the last input that happened to be active before
the filter graph was complete.

This can lead to an excess number of decoded frames "piling" up on this input,
regardless of whether or not it will actually be requested by the configured
filter graph. Suspending the filter graph during this initialization phase
reduces the amount of wasted memory.
This commit is contained in:
Niklas Haas
2025-09-04 15:11:46 +02:00
parent 23f1f094f8
commit 5f4cbb5617
3 changed files with 25 additions and 0 deletions

View File

@@ -2878,6 +2878,7 @@ static const char *unknown_if_null(const char *str)
static int send_frame(FilterGraph *fg, FilterGraphThread *fgt,
InputFilter *ifilter, AVFrame *frame)
{
FilterGraphPriv *fgp = fgp_from_fg(fg);
InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
FrameData *fd;
AVFrameSideData *sd;
@@ -2986,6 +2987,11 @@ static int send_frame(FilterGraph *fg, FilterGraphThread *fgt,
if (reason.len > 1)
reason.str[reason.len - 2] = '\0'; // remove last comma
av_log(fg, AV_LOG_INFO, "Reconfiguring filter graph%s%s\n", reason.len ? " because " : "", reason.str);
} else {
/* Choke all input to avoid buffering excessive frames while the
* initial filter graph is being configured, and before we have a
* preferred input */
sch_filter_choke_inputs(fgp->sch, fgp->sch_idx);
}
ret = configure_filtergraph(fg, fgt);

View File

@@ -2510,6 +2510,18 @@ int sch_filter_command(Scheduler *sch, unsigned fg_idx, AVFrame *frame)
return send_to_filter(sch, fg, fg->nb_inputs, frame);
}
void sch_filter_choke_inputs(Scheduler *sch, unsigned fg_idx)
{
SchFilterGraph *fg;
av_assert0(fg_idx < sch->nb_filters);
fg = &sch->filters[fg_idx];
pthread_mutex_lock(&sch->schedule_lock);
fg->best_input = fg->nb_inputs;
schedule_update_locked(sch);
pthread_mutex_unlock(&sch->schedule_lock);
}
static int task_cleanup(Scheduler *sch, SchedulerNode node)
{
switch (node.type) {

View File

@@ -443,6 +443,13 @@ int sch_filter_send(Scheduler *sch, unsigned fg_idx, unsigned out_idx,
int sch_filter_command(Scheduler *sch, unsigned fg_idx, struct AVFrame *frame);
/**
* Called by filtergraph tasks to choke all filter inputs, preventing them from
* receiving more frames until woken up again by the scheduler. Used during
* initial graph configuration to avoid unnecessary buffering.
*/
void sch_filter_choke_inputs(Scheduler *sch, unsigned fg_idx);
/**
* Called by encoder tasks to obtain frames for encoding. Will wait for a frame
* to become available and return it in frame.