Huge loss of precision when converting timestamps from NTP to RTP and viceversa
at srt/udp.c:
uint32_t timestampRTP_u32( int advanced, uint64_t i_ntp )
{
if (!advanced) {
i_ntp *= RTP_PTYPE_MPEGTS_CLOCKHZ;
i_ntp = i_ntp >> 32;
return (uint32_t)i_ntp;
}
else
{
// We just need the middle 32 bits, i.e. 65536Hz clock
i_ntp = i_ntp >> 16;
return (uint32_t)i_ntp;
}
}
And in general in all the conversions from NTP to RTP, shouldn't the shift occur before the multiplication?
In NTP, you have the seconds in the most significant 32 bits of the 64-bit timestamp. So if you grab that giant number and multiply by 90000, you have an overflow because now you have a number that does not fit in the 64bits of the uint64_t.
In the next line, you are discarding the lowest 32bits of the NTP (fractions of seconds) anyway, so you could just do that first and THEN multiply by 90000.
The same goes for converting RTP to NTP if you change this. You should first divide by 90000 and then shift 32 bits to the right to recover the NTP format (the fractions of seconds in the lowest 32 bits is lost in the conversion of course).
Here is a demostrated example. I have this NTP timestamp (the lowest 32 bits are erased for more clarity):
Then I multiply by 90000. A number with 19 digits is converted to a number with 24 digits (max for uint64_t is 20 digits)
If you do that in C++ instead of a calculator, the moment you do the multiplication you will have a number that does not make any sense because it is truncated.
I hope I made myself clear. Thanks!