[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