Message ID | 20210323195221.251025-1-alokpr@gmail.com |
---|---|
State | Accepted |
Headers | show |
Series | [FFmpeg-devel] avformat/rtpdec: attach producer reference time if available | expand |
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 |
On 3/23/2021 4:52 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 | 27 +++++++++++++++++++++++++++ > libavformat/utils.c | 9 +++++++++ > 3 files changed, 44 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..61a6c73614 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,26 @@ 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; > + uint8_t *side_data; > + int side_data_size; > + > + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size); There's no need for this, there can be only one entry per side data type in a packet. av_packet_new_side_data() will replace the existing entry of type AV_PKT_DATA_PRFT in the packet if there's one. > + if (!side_data) { > + side_data_size = sizeof(AVProducerReferenceTime); > + side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_PRFT, side_data_size); > + } > + if (!side_data || side_data_size < sizeof(AVProducerReferenceTime)) > + return AVERROR(ENOMEM); > + > + prft = (AVProducerReferenceTime *)side_data; > + 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 +615,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; >
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..61a6c73614 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,26 @@ 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; + uint8_t *side_data; + int side_data_size; + + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size); + if (!side_data) { + side_data_size = sizeof(AVProducerReferenceTime); + side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_PRFT, side_data_size); + } + if (!side_data || side_data_size < sizeof(AVProducerReferenceTime)) + return AVERROR(ENOMEM); + + prft = (AVProducerReferenceTime *)side_data; + 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 +615,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;