[FFmpeg-devel] [RFC] Flush API for libavfilter

Stefano Sabatini stefasab at gmail.com
Thu Oct 20 17:06:21 CEST 2011


On date Wednesday 2011-03-23 06:25:15 +0200, Mina Nagy Zaki encoded:
> On Tuesday 22 March 2011 17:35:39 Stefano Sabatini wrote:
[...]
> > Check: cmdutils.c:get_filtered_audio_buffer(), it implements a pull
> > model, correct me if I'm wrong.
> 
> I have already checked that, which is what lead me to the question in the first 
> place. I can't really read AVERROR_EOF from request_frame() because audio 
> filters don't(/shouldn't?) use it. get_filtered_audio_buffer() does a 
> request_frame() on aout which propagates all the way to asrc (without passing 
> through intermediate filters, because they don't/shouldn't use it) which then 
> does a filter_samples that propagates all the way to aout! If I try to 
> request_frame from the previous buffer it will reach asrc then eventually lead 
> to calling my own effect's filter_samples, so now do I filter in filter_samples or 
> request_frame :D  And in any case, asrc never returns AVERROR_EOF anyway.

Hi,

I was trying to get the af_sox.c filter in shape when I stumbled
across this.

Resuming, the problem is that when a filterchain source returns
AVERROR_EOF (e.g. becase the generated media has terminated) it is not
possible to notify the intermediate filters, which may keep cached
data which is never released.

For example some sox filters cache data, which is supposed to be
flushed through the drain API when *all* the input has been already
provided (so they won't return data *at all* if such a mechanism is
not implemented).

This can't be done with the current API (neither with audio nor with
video).

We may add a flag to avfilter_filter_samples()/avfilter_start_frame(),
which requests the filter to send all the cached data to output
(eventually calling avfilter_filter_samples()/start_frame() multiple
times).

It could work like this:

* the source filter set the flag when it's done with the last
  frame. That is: when request_frame() is called and no more frames
  are available, it calls avfilter_filter_samples() with a NULL frame
  with the flush flag set, before returning AVERROR_EOF.

* intermediate filters deal with the provided frame accordingly,
  e.g. the sox filter will use the drain API to flush all the cached
  samples, the last samples frame sent will have the flush flag set

Alternatively, we may just implement an avfilter_flush(), which forces
all the invoked filters to release cached data. This could be called
for example by a source on its output filters just before returning
AVERROR_EOF, and eventually requested by the filtergraph output end
through a flag in avfilter_request_frame(..., flag =
AVFILTER_FLAG_FLUSH).


More information about the ffmpeg-devel mailing list