[FFmpeg-user] missing a selected frame

Stéphane Chauveau stephane at chauveau-central.net
Fri Jul 19 12:22:41 EEST 2019


On 7/19/19 9:18 AM, Moritz Barsnick wrote:
> On Fri, Jul 19, 2019 at 00:21:53 +0200, Ulf Zibis wrote:
>> ./ffmpeg -y -v warning -i debug/CYD_1.5m_x264.mp4 -vf
>> select='eq(t\,10.16)+eq(t\,10.2)+eq(t\,10.24)+eq(t\,10.28)+eq(t\,10.32)+eq(t\,10.36)+eq(t\,10.4)+eq(t\,10.44)+eq(t\,17.52)+eq(t\,47.96)+eq(t\,49.08)+eq(t\,49.2)+eq(t\,55.72)+eq(t\,83.0)'
>> -q 5 -c:a copy -vsync vfr debug/outsides/CYD_1.5m_x264_%02d.png
> I'm not sure how ffmpeg's expression evaluation calculates 't' (means I
> couldn't find it in the source), but seeing that your av_ts2minutestr()
> certainly does it differently, I may point out: floating point equality
> is a bitch. ;-) I'm saying: 10.2 may not be equal to 10.2,
> computer-mathematically speaking.

Using eq() on floating points is indeed a bad idea because of floating 
point rounding.

It is probably better to use the frame number or the pts but if you 
really want to use time then you need to test an interval of time using 
the between() function.

The size of that interval and the number of digits of the reference time 
must be carefully chosen.

Here, the times 17.52, 49.08, ... appear to be given with a precision of 
1/100s which is probably quite close to the framerate of your video.

If that is possible you should try to add one digit to get a precision 
of 1ms.

The size of the interval of time should be smaller than the framerate 
(so no more than 1 frame per interval) but larger than the precision 
used on the time values to insure that the rounded value remains in the 
interval.

Assuming  time values with 2 decimals (so 10ms precision), a good 
interval could be +/- 15ms so a total interval of 30ms and a maximum 
framerate of 33 FPS which is not a lot.

With 3 decimals (so 1ms precisions), you could use an interval of +/- 
2ms so a total interval of 4ms and a maximum framerate of 250 FPS which 
should be good enough.

So my advice is to add a 3rd digit to your time values and to replace, 
for instance,  eq(t\,47.96) by something like 
between(47.963\,t-0.002\,t+0.002).

You can easily experiment with different intervals by creating two 
variables. For example, with your current times with only 2 decimals, 
you could try something like

-vf  
select='st(0\,t-0.015)\;st(1\,t+0.015)\;between(10.16\,ld(0)\,ld(1))+between(10.2\,ld(0)\,ld(1))+....'







More information about the ffmpeg-user mailing list