[FFmpeg-devel] lavfi: request_frame() return value.
Nicolas George
nicolas.george at normalesup.org
Sat Mar 16 00:25:32 CET 2013
Hi. A few words about the API contract of request_frame().
Here is the current situation:
* If request_frame() succeeds, it returns 0; it happens if and only if
request_frame() pushed (successfully) at least a frame on the same link.
* If request_frame() can not succeed for temporary external reasons (e.g. a
source needs input), it returns AVERROR(EAGAIN).
* It can always return an error code for other reasons (including EOF, which
is not an error); I will omit this case in the rest of this message.
The problem with these rules is this: if a filter does not produce always at
least one output frame for each input frame (for example: select can skip
frames, fps too if the output frame rate is lower than the input, tile needs
n input frames to produce one output frame), then it needs to implement some
kind of communication so that filter_frame() can inform request_frame() it
is done. Something like this:
int filter_frame(inlink, frame) {
...
if (can_produce_output) {
ff_filter_frame(outlink, out_frame);
self->request_fulfilled = 1;
}
return 0;
}
int request_frame(outlink) {
self->request_fulfilled = 0;
while (!self->request_fulfilled)
ff_request_frame(inlink);
return 0;
}
Add to that all error checks and EOF handling, and it can become somewhat
messy.
A special case of this is filters that use the min/max_samples feature: in
that case, the filter before the link thinks it has successfully pushed a
frame, and therefore returns 0, but the filter after the link did not
receive it yet.
I see several solutions for this:
0. Leave things as it is. The problem of the min/max_samples can be solved
by making it the responsibility of the filter: if a filter sets
min/max_samples on its input, it must implement a non-trivial
request_frame() as above to make sure a frame was actually received.
It works, but all in all that makes a lot of code, and there is room for
simplification. I see two main options that could make things easier:
1. Change the semantic of the return value 0: instead of "success, at least
one frame has been sent", it can become "success, some progress has been
made (a frame has been pushed, or I have accumulated more data to push a
frame later, or filters before me did)".
This is a change of API, but since all these functions are internal, it
only concerns the sinks and people maintaining private trees and forks
with additional filters.
2. Move the "while (!request_fulfilled) ff_request_frame(inlink);" logic to
the framework, namely ff_request_frame(). The request_fulfilled would
then be just a private field of AVFilterLink.
I see small pros and cons for each solution, but I do not see a real problem
with either. I wonder if people have an advice before considering
implementing one of them.
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130316/486bd3e4/attachment.asc>
More information about the ffmpeg-devel
mailing list