10

Is it possible to read an absolute timestamp from an H.264 stream sent trough RTSP from an Axis camera?

It will be necessary to know when the frame has been taken by the camera.

Thanks Andrea

agamesh
  • 559
  • 1
  • 10
  • 26
Grifo
  • 999
  • 4
  • 12
  • 16

4 Answers4

6

as Ralf already said - the RTP timestamps are relative to a random clock - they are only useful for computing the difference between two frames (or RTP-packets in general). For synchronizing these relative values to a wall clock you can use the RTCP sender - just have a look on the links Ralf provided.

For Axis-products using H.264 this works pretty good. In case you're also using MPEG4, the Axis firmware is buggy and the absolute timestamps in RTCP SR are not reliable - in this case you have to synchronize the relative RTP timestamps to your clients wall clock.

jenseb
  • 1,593
  • 1
  • 10
  • 13
5

Assuming the cameras firmware works properly and it's synchronized with NTP regularly, you can extract the absolute timestamp from RTCP Sender Report. But this functionality is not available in FFMpeg library API, you have to use header libavformat/rtsp.h in order to access internal data structures. And then you have to calculate the ntp timestamp for every frame:

RTSPState* rtsp_state = (RTSPState*) pFormatCtx->priv_data;
RTSPStream* rtsp_stream = rtsp_state->rtsp_streams[0];
RTPDemuxContext* rtp_demux_context = (RTPDemuxContext*) rtsp_stream->transport_priv;

int32_t d_ts = rtp_demux_context->timestamp - rtp_demux_context->last_rtcp_timestamp;
uint64_t last_ntp_time = rtp_demux_context->last_rtcp_ntp_time;
uint32_t seconds = ((last_ntp_time >> 32) & 0xffffffff)-2208988800;
uint32_t fraction  = (last_ntp_time & 0xffffffff);
double useconds = ((double) fraction / 0xffffffff);
double base_time = seconds+useconds;

double frame_ntp_time = base_time+d_ts/90000.0;

Full example is here.

Islam Sabyrgaliyev
  • 340
  • 1
  • 5
  • 10
  • Interesting. Is `rtp_demux_context->last_rtcp_ntp_time` supposed to be constant though? On my camera, it's always `-9223372036854775808`. `first_rtcp_ntp_time` as well. `frame_ntp_time` gives me the relative time since the start of the stream rather than the wall clock though. – John M. Jul 20 '20 at 18:57
  • No, `last_rtcp_ntp_time` should be updating periodically. In my experience not all cameras implement the protocol in a proper way. I have succesfully tested with Dahua and Hikvision, but with HiWatch was similar problem as yours – Islam Sabyrgaliyev Jul 21 '20 at 04:20
  • Mine's actually a Hikvision. Which Hikvision model is yours? – John M. Jul 21 '20 at 05:09
  • Unfortunately I don't remember the model, it was 3 years ago. – Islam Sabyrgaliyev Jul 21 '20 at 06:03
4

Timestamps are contained in the RTP stream. RTSP is a protocol that can be used to start/control an RTP media session. I'm assuming that RTP used and you can look at the RTP header here.

Ralf
  • 9,405
  • 2
  • 28
  • 46
  • 1
    But I think that the timestamp sued by the RTP protocol is RELATIVE, not absolute. Isn't it? Timestamp: 32 bytes; gives the sampling instant of the first audio/video byte in the packet; used to remove jitter introduced by the network - clock frequency depends on applications - random initial value - several packets may have equal timestamps (eg. same video frame), or even in disorder (eg. interpolated frames in MPEG – Grifo May 27 '11 at 12:28
  • 4
    If I understand you correctly, you want the original presentation time. RTCP Sender Reports can be used for this purpose: they contain both an RTP timestamp and an NTP timestamp. See http://tools.ietf.org/html/rfc3550#section-6.4.1 and http://tools.ietf.org/html/rfc3550#section-4 – Ralf May 27 '11 at 13:29
0

There is a program called openRTSP (livemedia-utils on Debian, live-media on Arch) that fetches a parameter o:

openRTSP -r rtsp://109.98.78.106
[...]
o=- 1613080009143448 1 IN IP4 109.98.78.106

Without having read the source code, I think it to be the NTS system time stamp from the Sender Report RTCP Packets Islam Sabyrgaliyev mentioned.

date -d@$( echo $(openRTSP -r rtsp://109.98.78.106 2>&1 | grep -Po '(?<=o=-\s)\d+' | head -n1 ) / 1000000 | bc )
Thu Feb 11 10:46:07 PM CET 2021
Suuuehgi
  • 4,547
  • 3
  • 27
  • 32