I remember when I first started RTP/RTCP two years ago, I encountered a problem about how to calculate the NTP timestamp in RTCP. Someone recently asked this question, so I wanted to post it, for your reference, give suggestions, and exchange ideas to promote progress.
I remember a customer said that using openrtsp (open source, you can get it from www.live555.com) could not record the RTP stream we sent out, so I went to another one, I tried to find that it really didn't work, so I caught the source code of openrtsp and found that it had to receive the RTCP package before recording the video. So I added RTCP, the results showed that video recording was okay, but it was always jitters when playing with VLC. So I went back and looked for the reason. I sorted it out and finally focused on the NTP timestamp.
The NTP timestamp consists of MSW and Lsw. MSW is easy to calculate. In seconds, Lsw has a headache. I checked the RTP document and talked about it fuzzy. NTP (rfc1305) the Unit is about 200 picoseconds, but I tried to use 200 picoseconds.
No way, I went to study the Darwin Streaming Server to see how people did it, grabbed the package, found several RTCP points, and drew a number axis, the packet capture tool Wireshark will display the NTP time (for example,), so I used to calculate it, and finally calculated that the unit is about 232 picoseconds. I substituted this value into my source code, sure enough.
Although the problem has been solved, there has been a knot in my mind, that is, I have never known how the value of 232 came from. I had to go back and look at rfc1305. It only says the unit is about 200 picoseconds, and 1 second = 1,000,000,000,000 picoseconds. This value seems a bit big, and 232 = 4294967296, obviously, 32bits cannot be accurate to 1 picoseconds, so I thought that I could not be accurate to 1 picoseconds, so I should do my best, so naturally I had to split 1,000,000,000,000 picoseconds into 232 copies:
1,000,000,000,000/4294967296 = 232.83064365386962890625
That's it !!
Now, let's look at the source code of VLC in a more efficient way:
/**
* @ Return NTP 64-bits timestamp in host byte order.
*/
Uint64_t ntptime64 (void)
{
Struct timespec ts;
# If defined (clock_realtime)
Clock_gettime (clock_realtime, & TS );
# Else
{
Struct timeval TV;
Gettimeofday (& TV, null );
TS. TV _sec = TV. TV _sec;
TS. TV _nsec = TV. TV _usec * 1000;
}
# Endif
/* Convert nanoseconds to 32-bits fraction (232 picosecond units )*/
Uint64_t t = (uint64_t) (TS. TV _nsec) <32;
T/= 1000000000;
/* There is 70 years (incl. 17 leap ones) offset to the Unix epoch.
* No leap seconds during that period since they were not specified Ted yet.
*/
Assert (T <0x100000000 );
T | = (70ll * 365 + 17) * 24*60*60 + ts. TV _sec) <32;
Return T;
}