[FFmpeg-devel] [PATCH] libavfilter-soc: Make overlay handle still images

Vitor Sessak vitor1001
Thu May 7 22:54:52 CEST 2009


Michael Niedermayer wrote:
> On Thu, May 07, 2009 at 10:45:53PM +0300, 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.
> 
> I think repeatly providing a frame with the same PTS ad infinitum is not
> correct
> 
> 
>> 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.)
>>
>>
>> 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?
> 
> returning -1 is not good, it should be AVERROR_EOF and this must be
> documented in the header.
> 
> also poll_frame() likely should similarly return AVERROR_EOF

I saw that avfilter.h does not say what to do in case of EOF. What I 
suggest is:

1- request_frame() should return AVERROR_EOF
2- poll_frame() should return 1

The last point seems weird, but for me it is very practical in two cases:

1- Filters that do not implement poll_frame() (like vsrc_movie, that can 
decodes always more as needed) will keep behaving correctly

2- Filters that need to do considerable work to know if the file reached 
EOF or not. Think again of vsrc_movie with a truncated file. The only 
way to know that there is no more frames is to try (and fail) to decode 
the last one. Putting all this code in poll_frame() would make 
everything a big mess.

And the header should document that here EOF actually means "no more 
frames" instead of EOF...

-Vitor



More information about the ffmpeg-devel mailing list