]> git.sesse.net Git - ffmpeg/commitdiff
avformat/rtpdec: attach producer reference time if available
authorAlok Priyadarshi <alokpr@gmail.com>
Tue, 23 Mar 2021 21:29:48 +0000 (14:29 -0700)
committerJames Almer <jamrial@gmail.com>
Tue, 23 Mar 2021 22:02:47 +0000 (19:02 -0300)
This produces true wallclock time at rtp source instead of the
local wallclock time at rtp client.

Signed-off-by: James Almer <jamrial@gmail.com>
libavformat/internal.h
libavformat/rtpdec.c
libavformat/utils.c

index a810d51bba51f0511e9273c9ed58147b149287c5..d85b9a3d9bc0b49221861ff56ebb5979c8127630 100644 (file)
@@ -423,6 +423,14 @@ uint64_t ff_ntp_time(void);
  */
 uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us);
 
+/**
+ * Parse the NTP time in micro seconds (since NTP epoch).
+ *
+ * @param ntp_ts NTP time stamp formatted as per the RFC-5905.
+ * @return the time in micro seconds (since NTP epoch)
+ */
+uint64_t ff_parse_ntp_time(uint64_t ntp_ts);
+
 /**
  * Append the media-specific SDP fragment for the media stream c
  * to the buffer buff.
index fd4601e654cf81c10cf1e08f39976449faf244b5..1edb64b9bffb4208df5c5e07d75d2088a50c155a 100644 (file)
@@ -622,6 +622,19 @@ void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite,
         s->srtp_enabled = 1;
 }
 
+static int rtp_set_prft(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp) {
+    AVProducerReferenceTime *prft =
+        (AVProducerReferenceTime *) av_packet_new_side_data(
+            pkt, AV_PKT_DATA_PRFT, sizeof(AVProducerReferenceTime));
+    if (!prft)
+        return AVERROR(ENOMEM);
+
+    prft->wallclock = ff_parse_ntp_time(s->last_rtcp_ntp_time) - NTP_OFFSET_US +
+                      timestamp - s->last_rtcp_timestamp;
+    prft->flags = 24;
+    return 0;
+}
+
 /**
  * This was the second switch in rtp_parse packet.
  * Normalizes time, if required, sets stream_index, etc.
@@ -633,6 +646,12 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
     if (timestamp == RTP_NOTS_VALUE)
         return;
 
+    if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
+        if (rtp_set_prft(s, pkt, timestamp) < 0) {
+            av_log(s->ic, AV_LOG_WARNING, "rtpdec: failed to set prft");
+        }
+    }
+
     if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && s->ic->nb_streams > 1) {
         int64_t addend;
         int delta_timestamp;
index 96a52e07d4904bccf09c254eccab1f2384ff7474..524765aeb4374aa4070099e4db1862269d8bc832 100644 (file)
@@ -4706,6 +4706,15 @@ uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us)
     return ntp_ts;
 }
 
+uint64_t ff_parse_ntp_time(uint64_t ntp_ts)
+{
+    uint64_t sec = ntp_ts >> 32;
+    uint64_t frac_part = ntp_ts & 0xFFFFFFFFULL;
+    uint64_t usec = (frac_part * 1000000) / 0xFFFFFFFFULL;
+
+    return (sec * 1000000) + usec;
+}
+
 int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
 {
     const char *p;