From adff25412a2929de67e44da1abaf67f9a267bdf4 Mon Sep 17 00:00:00 2001 From: Alok Priyadarshi Date: Tue, 23 Mar 2021 14:29:48 -0700 Subject: avformat/rtpdec: attach producer reference time if available This produces true wallclock time at rtp source instead of the local wallclock time at rtp client. Signed-off-by: James Almer --- libavformat/internal.h | 8 ++++++++ libavformat/rtpdec.c | 19 +++++++++++++++++++ libavformat/utils.c | 9 +++++++++ 3 files changed, 36 insertions(+) diff --git a/libavformat/internal.h b/libavformat/internal.h index a810d51bba..d85b9a3d9b 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -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. diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index fd4601e654..1edb64b9bf 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -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; diff --git a/libavformat/utils.c b/libavformat/utils.c index 96a52e07d4..524765aeb4 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -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; -- cgit v1.2.3