[FFmpeg-devel] [PATCH] libavfilter-soc: Make overlay handle still images
Vitor Sessak
vitor1001
Thu May 7 23:26:12 CEST 2009
Martin Storsj? wrote:
> Hi Vitor,
>
> On Wed, 6 May 2009, Vitor Sessak wrote:
>
>> Just a question: how are you testing those changes?
>
> I'm testing it with the following command line:
>
> ffplay in.mov -vfilters "movie=0:png:overlay.png, scale=0:0 [over1], [in] [over1] overlay=10:10 [out]"
>
> and similarly with ffmpeg.
>
>
>>> + oldpts = over->pics[idx][1]->pts;
>>> if(avfilter_request_frame(link->src->inputs[idx]))
>>> return -1;
>>> + if(over->pics[idx][1]->pts == oldpts) {
>>> + /* no new pts, we're probably at eof, pull a frame
>>> + from the other queue to keep it moving */
>> The correct way to know if the video is over is to check if request_frame()
>> returned -1.
>
> That was my initial guess, too, but the movie source filter provides the
> last frame repeatedly instead of returning -1.
>
> This can easily be fixed by the first attached patch. (It contains checks
> both before and after movie_get_frame, to avoid unnecessary calls to the
> underlying layers after reaching eof.)
I like this patch. The only nit is that I think that just one check
should be enough. Please change that and follow Michael's suggestion of
AVERROR_EOF and I'll commit it (unless V?ctor wants to comment).
> When this is applied, the eof handling in the overlay filter can be fixed
> in a few other ways, named -overlay-eof2 and 4.
>
> The first one, -eof2, alters the frame pulling logic only slightly. The
> request_frame function returns -1 when unable to pull frames from both
> streams. Since a stream may contain only one frame, it requires the image
> copying to try to check over->pics[idx][1] if over->pics[idx][0] is null.
>
> The second way of solving it, -eof4, moves the last frame from
> over->pics[idx][1] into over->pics[idx][0] by a
> start_frame(link->src->inputs[idx], NULL) if there still is a frame in
> over->pics[idx][1]. This way, all input frames should be output too. (In
> the original overlay filter logic, the last input frame wouldn't be
> output.)
>
> Do these look sensible?
>
> This doesn't really address all issues in the overlay filter, but is at
> least a step in the right direction, and fixes the eof issue for me.
It does indeed a improves EOF handling, but the serious problem I told
you in my previous email remains (and there is no much point in
improving EOF handling of broke code). I'll try to explain a little
better how the filter library is supposed to work so you can see where
the bug is. Suppose your client application wants to feed two inputs to
a filter chain and get one output (that it prints to the screen, for
example). It will do something like:
while (1) {
if (filter chain consumed input 1) {
feed input 1 to the filter chain
if (eof(file1))
tell input filter1 to return AVERROR_EOF
}
if (filter chain consumed input 2) {
feed input 2 to the filter chain
if (eof(file2))
tell input filter2 to return AVERROR_EOF
}
if (avfilter_poll_frame(output_filter)) {
// We have a frame ready for consumption!
if (!avfilter_request_frame(output_filter))
break; // No more frames to output, EOF
else
show(output_filter->current_pic);
}
}
notice that if the video chain is just an overlay filter, every time
request_frame() is called, there are just _one_ frame available from
each input. That means that request_frame() in vf_overlay.c can only
call avfilter_request_frame() at most once for every input. And the
current code (even after your patch) may call it more than once for the
first output frame.
Sorry if everything looks very complicated, but overlay is certainly the
most complex filter API-wise...
-Vitor
PS: I will look at your other, less complicated, patches soon...
More information about the ffmpeg-devel
mailing list