diff mbox series

[FFmpeg-devel] avformat/rtpdec: attach producer reference time if available

Message ID 20210323212948.256616-1-alokpr@gmail.com
State New
Headers show
Series [FFmpeg-devel] avformat/rtpdec: attach producer reference time if available
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Alok Priyadarshi March 23, 2021, 9:29 p.m. UTC
This produces true wallclock time at rtp source instead of the
local wallclock time at rtp client.
---
 libavformat/internal.h |  8 ++++++++
 libavformat/rtpdec.c   | 20 ++++++++++++++++++++
 libavformat/utils.c    |  9 +++++++++
 3 files changed, 37 insertions(+)

Comments

James Almer March 23, 2021, 10:03 p.m. UTC | #1
On 3/23/2021 6:29 PM, Alok Priyadarshi wrote:
> This produces true wallclock time at rtp source instead of the
> local wallclock time at rtp client.
> ---
>   libavformat/internal.h |  8 ++++++++
>   libavformat/rtpdec.c   | 20 ++++++++++++++++++++
>   libavformat/utils.c    |  9 +++++++++
>   3 files changed, 37 insertions(+)
> 
> diff --git a/libavformat/internal.h b/libavformat/internal.h
> index 17a6ab07d3..1e10cde00e 100644
> --- a/libavformat/internal.h
> +++ b/libavformat/internal.h
> @@ -254,6 +254,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.
> diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
> index 3d5b200099..b935dba1b8 100644
> --- a/libavformat/rtpdec.c
> +++ b/libavformat/rtpdec.c
> @@ -30,6 +30,7 @@
>   #include "url.h"
>   #include "rtpdec.h"
>   #include "rtpdec_formats.h"
> +#include "internal.h"
>   
>   #define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
>   
> @@ -583,6 +584,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.
> @@ -594,6 +608,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;
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 7e5767ec60..569922beaf 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -4734,6 +4734,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;

Applied, thanks.
Alok Priyadarshi March 25, 2021, 4:49 a.m. UTC | #2
Hi James,

This patch had a bug in the calculation of prft time. I did not account for
the timebase differences between media timestamp and wall clock. I have
sent a new patch for review.

-Alok


On Tue, Mar 23, 2021 at 3:04 PM James Almer <jamrial@gmail.com> wrote:

> On 3/23/2021 6:29 PM, Alok Priyadarshi wrote:
> > This produces true wallclock time at rtp source instead of the
> > local wallclock time at rtp client.
> > ---
> >   libavformat/internal.h |  8 ++++++++
> >   libavformat/rtpdec.c   | 20 ++++++++++++++++++++
> >   libavformat/utils.c    |  9 +++++++++
> >   3 files changed, 37 insertions(+)
> >
> > diff --git a/libavformat/internal.h b/libavformat/internal.h
> > index 17a6ab07d3..1e10cde00e 100644
> > --- a/libavformat/internal.h
> > +++ b/libavformat/internal.h
> > @@ -254,6 +254,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.
> > diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
> > index 3d5b200099..b935dba1b8 100644
> > --- a/libavformat/rtpdec.c
> > +++ b/libavformat/rtpdec.c
> > @@ -30,6 +30,7 @@
> >   #include "url.h"
> >   #include "rtpdec.h"
> >   #include "rtpdec_formats.h"
> > +#include "internal.h"
> >
> >   #define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
> >
> > @@ -583,6 +584,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.
> > @@ -594,6 +608,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;
> > diff --git a/libavformat/utils.c b/libavformat/utils.c
> > index 7e5767ec60..569922beaf 100644
> > --- a/libavformat/utils.c
> > +++ b/libavformat/utils.c
> > @@ -4734,6 +4734,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;
>
> Applied, thanks.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/libavformat/internal.h b/libavformat/internal.h
index 17a6ab07d3..1e10cde00e 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -254,6 +254,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.
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 3d5b200099..b935dba1b8 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -30,6 +30,7 @@ 
 #include "url.h"
 #include "rtpdec.h"
 #include "rtpdec_formats.h"
+#include "internal.h"
 
 #define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
 
@@ -583,6 +584,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.
@@ -594,6 +608,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;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 7e5767ec60..569922beaf 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -4734,6 +4734,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;