[FFmpeg-devel] Writing filters

James Darnley james.darnley at gmail.com
Wed Jun 11 21:00:39 CEST 2014


On 2014-06-11 17:40, Nicolas George wrote:
> Le tridi 23 prairial, an CCXXII, Clément Bœsch a écrit :
>> Yes, request_frame() is still a bit magic to me so I didn't feel
>> comfortable explaining it.
> 
>> It's important to note that the API evolved quite a bit since the
>> beginning. I *think* we can avoid request_frame in various cases nowadays
>> with the help of FF_LINK_FLAG_REQUEST_LOOP.
> 
> It is really not that complicated once you understand that the whole process
> is deeply recursive.
> 
> It all starts, for example, when the application asks a sink for a frame.
> The sink calls request_frame() on its input filter, and the input filter
> does the same, recursively, until it reaches a source. The source somehow
> produces a frame and calls filter_frame() on its output, which does
> the same, recursively, until it reaches the sink. Then everyone returns
> success.

That does sound like a simple explanation.  In this case I would wonder
why the filter_frame() chain is necessary.  I would have expected
request_frame() to return a frame (in some fashion) which then gets
processed.

(This is beginning to sound dangerously like bike-shedding.  I will just
try to understand what exists.)

> Of course, it is not that simple.
> 
> The first issue is filters that require several frames to produce one, tile
> for example. In that case, request_frame() has to loop until enough frames
> are received to produce one. The framework is now capable of doing it: if
> your filter requires just that, you can omit request_frame() and rely on the
> default.
> 
> The second issue is filters with several inputs: consider concat versus
> overlay, for example: only the filter knows what input needs a frame right
> now in order to produce output. In that case, request_frame() can definitely
> not be omitted, although it can rely on standard helpers for common cases.

This almost sounds like it reinforces what I thought above.  I would
expect a filter's own request_frame() should just call its inputs'
request_frame() functions as needed to make the frame.

I'm probably missing some considerations for random access, variable
frame rates, interleaved audio-video packets, whatever.  (Again, I want
to avoid arguing over the current design.)

On to an implementation question.

Let's say an Example filter needs several frames from its one and only
input.  Example receives a call to example_request_frame() which then
calls ff_request_frame() to get 1 frame from its input.  That "message"
goes through to the input which then puts 1 frame into
ff_filter_frame().  This eventually comes to Example's
example_filter_frame().  This function knows it needs more frames to be
able to do its work.

I assume that this function can finish/return without calling
ff_filter_frame() itself, right?

As I understand it, the return will go back though the functions to the
input.  The input can then return from request_frame().  This return
makes its way back to Example's example_request_frame().  The context
struct for Example (or whatever mechanism might be used) shows that more
input frames are required, so example_request_frame() will call
ff_request_frame() again.

Is the reason for the do { ff_request_frame() } while(); loops in
showwaves and showspectrum?  Frames are requested until filter_frame()
marks that it is done?

On the other side, if a filter makes 2 frames from every input frame,
can it call ff_filter_frame() twice from its own filter_frame()?

On the first call to ff_filter_frame() the "returns" come back to this
filter, then it makes its second call to ff_filter_frame.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 683 bytes
Desc: OpenPGP digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140611/a3468940/attachment.asc>


More information about the ffmpeg-devel mailing list