[FFmpeg-user] missing a selected frame

Ulf Zibis Ulf.Zibis at gmx.de
Fri Jul 19 18:54:04 EEST 2019


Am 19.07.19 um 15:58 schrieb Stéphane Chauveau:
>
> You don't get it. The problem is not that you need a better formula.
> The problem is that some values such as  10.2 cannot be exactly
> represented using floating point values.
>
> For example, let's consider a few examples using the printf builtin
> from bash.
>
> First, let's print 10.2 using  the default floating point precision
>
> # printf "%f\n"  10.2
> 10.20000
>
> Now, let's increase the number of digits after the decimal point.
>
> # for ((i=5;i<=40;i+=5)) ; do printf "%.${i}f\n" 10.2 ; done
>
> 10.20000
> 10.2000000000
> 10.200000000000000
> 10.19999999999999999983
> 10.1999999999999999998265277
> 10.199999999999999999826527652402
> 10.19999999999999999982652765240231929
> 10.1999999999999999998265276524023192905588
>
> As you can see, the actual value of 10.2  is
> 10.1999999999999999998265276524023192905588....
>
> The next value that can be represented using a 'double precision
> floating point is
>
> 10.2000000000000000006938893903907228377648....
>
> # for ((i=5;i<=40;i+=5)) ; do printf "%.${i}f\n"
> 10.2000000000000000004 ; done
>
> 10.20000
> 10.2000000000
> 10.200000000000000
> 10.20000000000000000069
> 10.2000000000000000006938894
> 10.200000000000000000693889390391
> 10.20000000000000000069388939039072284
> 10.2000000000000000006938893903907228377648
>
> There is nothing between those two values.
>
> If you do the same with 102.0 and 10.0 you will notice that those two
> values can be represented exactly. This is beause they are small
> integers and those can be represented exactly using floating point
> numbers.
>
> # for ((i=5;i<=40;i+=5)) ; do printf "%.${i}f\n" 102.0 ; done102.00000
>
> 102.0000000000
> 102.000000000000000
> 102.00000000000000000000
> 102.0000000000000000000000000
> 102.000000000000000000000000000000
> 102.00000000000000000000000000000000000
> 102.0000000000000000000000000000000000000000
>
> Consider the C expression
>
> ((double) 102) / ((double) 10)
>
> The conversion or 102 and 10  to floating point double precision
> values does not cause any rounding. So far so good.
>
> 102.00000000000000... / 10.0000000000000000000000000
>
> However, since 10.2 cannot be represented in floating point, the final
> result of the division is either
>
> 10.1999999999999999998265276524023192905588...
>
> or
>
> 10.2000000000000000006938893903907228377648...
>
> The divison operator will choose one of the two values. The parser
> also choose one of the two values when converting the string "10.2"
> into a floating point value. The problem is that you cannot be sure
> that both actions will do the same choice. Eventually, the test
> eq(t,10.2) becomes
>
> eq( 10.1999999999999999998265276524023192905588 ,
> 10.2000000000000000006938893903907228377648 )
>
> and the result of that comparison is FALSE.
Thanks, I know all this, but anyway a didactically expressive explanation.

> Your new formula does not work because it uses integer arithmetic. You
> are basically computing 102/10 = 10  which is obviously a lot worse
> than the two floating point approximations.
Oups yes, there was a bug in my formula, it should have been:

= frame->pts == AV_NOPTS_VALUE ? NAN : frame->pts *
inlink->time_base.num / (double)inlink->time_base.den;

Now I indeed see an advantage. All 14 frames have been caught. So now
the floating point representation limits from both sides seem to
compensate against each other.

> YOU CANNOT AVOID ROUNDING ERRORS WHEN USING FLOATING POINT ARITHMETIC.
> THIS IS IMPOSSIBLE EXCEPT IN SOME SPECIAL CASES THAT ARE NOT
> APPLICABLE HERE.

I believe, there would be much less such problems if the select fiter
internally would deal with µs instead s, even in float representation.
E.g. with the common time_base of 1/12800 on 25 fps streams there would
be no rounding error.

-Ulf


More information about the ffmpeg-user mailing list