* [FFmpeg-devel] [PATCH 2/3] lavf: add and use AVRTCPSenderReport struct
2025-06-24 18:02 [FFmpeg-devel] [PATCH 1/3] lavf/rtpdec: fix RTCP SR packet length check Marvin Scholz
@ 2025-06-24 18:02 ` Marvin Scholz
2025-06-24 18:02 ` [FFmpeg-devel] [PATCH 3/3] lavf: add AV_PKT_DATA_RTCP_SR side data type Marvin Scholz
1 sibling, 0 replies; 3+ messages in thread
From: Marvin Scholz @ 2025-06-24 18:02 UTC (permalink / raw)
To: ffmpeg-devel
This will be used in a future commit to expose the SR as side-data.
---
libavcodec/defs.h | 14 ++++++++++++++
libavformat/rtpdec.c | 34 ++++++++++++++++++++--------------
libavformat/rtpdec.h | 4 ++--
libavformat/rtspdec.c | 2 +-
4 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/libavcodec/defs.h b/libavcodec/defs.h
index e0df60213b..8ce5d424c9 100644
--- a/libavcodec/defs.h
+++ b/libavcodec/defs.h
@@ -333,6 +333,20 @@ typedef struct AVProducerReferenceTime {
int flags;
} AVProducerReferenceTime;
+/**
+ * RTCP SR (Sender Report) information
+ *
+ * The received sender report information for an RTSP
+ * stream, exposed as AV_PKT_DATA_RTCP_SR side data.
+ */
+typedef struct AVRTCPSenderReport {
+ uint32_t ssrc; ///< Synchronization source identifier
+ uint64_t ntp_timestamp; ///< NTP time when the report was sent
+ uint32_t rtp_timestamp; ///< RTP time when the report was sent
+ uint32_t sender_nb_packets; ///< Total number of packets sent
+ uint32_t sender_nb_bytes; ///< Total number of bytes sent (excluding headers or padding)
+} AVRTCPSenderReport;
+
/**
* Encode extradata length to a buffer. Used by xiph codecs.
*
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 97aabcf542..9c9d66f33d 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -192,14 +192,20 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf,
return AVERROR_INVALIDDATA;
}
+ s->last_sr.ssrc = AV_RB32(buf + 4);
+ s->last_sr.ntp_timestamp = AV_RB64(buf + 8);
+ s->last_sr.rtp_timestamp = AV_RB32(buf + 16);
+ s->last_sr.sender_nb_packets = AV_RB32(buf + 20);
+ s->last_sr.sender_nb_bytes = AV_RB32(buf + 24);
+
+ s->pending_sr = 1;
s->last_rtcp_reception_time = av_gettime_relative();
- s->last_rtcp_ntp_time = AV_RB64(buf + 8);
- s->last_rtcp_timestamp = AV_RB32(buf + 16);
+
if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
- s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
+ s->first_rtcp_ntp_time = s->last_sr.ntp_timestamp;
if (!s->base_timestamp)
- s->base_timestamp = s->last_rtcp_timestamp;
- s->rtcp_ts_offset = (int32_t)(s->last_rtcp_timestamp - s->base_timestamp);
+ s->base_timestamp = s->last_sr.rtp_timestamp;
+ s->rtcp_ts_offset = (int32_t)(s->last_sr.rtp_timestamp - s->base_timestamp);
}
break;
@@ -367,11 +373,11 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
avio_wb32(pb, extended_max); /* max sequence received */
avio_wb32(pb, stats->jitter >> 4); /* jitter */
- if (s->last_rtcp_ntp_time == AV_NOPTS_VALUE) {
+ if (s->last_sr.ntp_timestamp == AV_NOPTS_VALUE) {
avio_wb32(pb, 0); /* last SR timestamp */
avio_wb32(pb, 0); /* delay since last SR */
} else {
- uint32_t middle_32_bits = s->last_rtcp_ntp_time >> 16; // this is valid, right? do we need to handle 64 bit values special?
+ uint32_t middle_32_bits = s->last_sr.ntp_timestamp >> 16; // this is valid, right? do we need to handle 64 bit values special?
uint32_t delay_since_last = av_rescale(av_gettime_relative() - s->last_rtcp_reception_time,
65536, AV_TIME_BASE);
@@ -538,7 +544,7 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
if (!s)
return NULL;
s->payload_type = payload_type;
- s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
+ s->last_sr.ntp_timestamp = AV_NOPTS_VALUE;
s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
s->ic = s1;
s->st = st;
@@ -596,8 +602,8 @@ static int rtp_set_prft(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp) {
if (!prft)
return AVERROR(ENOMEM);
- rtcp_time = ff_parse_ntp_time(s->last_rtcp_ntp_time) - NTP_OFFSET_US;
- delta_timestamp = (int32_t)(timestamp - s->last_rtcp_timestamp);
+ rtcp_time = ff_parse_ntp_time(s->last_sr.ntp_timestamp) - NTP_OFFSET_US;
+ delta_timestamp = (int32_t)(timestamp - s->last_sr.rtp_timestamp);
delta_time = av_rescale_q(delta_timestamp, s->st->time_base, AV_TIME_BASE_Q);
prft->wallclock = rtcp_time + delta_time;
@@ -616,20 +622,20 @@ 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 (s->last_sr.ntp_timestamp != 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) {
+ if (s->last_sr.ntp_timestamp != AV_NOPTS_VALUE && s->ic->nb_streams > 1) {
int64_t addend;
int delta_timestamp;
/* compute pts from timestamp with received ntp_time */
- delta_timestamp = timestamp - s->last_rtcp_timestamp;
+ delta_timestamp = timestamp - s->last_sr.rtp_timestamp;
/* convert to the PTS timebase */
- addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time,
+ addend = av_rescale(s->last_sr.ntp_timestamp - s->first_rtcp_ntp_time,
s->st->time_base.den,
(uint64_t) s->st->time_base.num << 32);
pkt->pts = s->range_start_offset + s->rtcp_ts_offset + addend +
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 5a02e72dc2..c06f44b86c 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -173,11 +173,11 @@ struct RTPDemuxContext {
/*@}*/
/* rtcp sender statistics receive */
- uint64_t last_rtcp_ntp_time;
int64_t last_rtcp_reception_time;
uint64_t first_rtcp_ntp_time;
- uint32_t last_rtcp_timestamp;
int64_t rtcp_ts_offset;
+ AVRTCPSenderReport last_sr; ///< Last RTCP SR data
+ int pending_sr; ///< Indicates if there is a SR pending to be attached as sidedata
/* rtcp sender statistics */
unsigned int packet_count;
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 10078ce2fa..88a57b01ef 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -553,7 +553,7 @@ static int rtsp_read_play(AVFormatContext *s)
if (!rtpctx)
continue;
ff_rtp_reset_packet_queue(rtpctx);
- rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
+ rtpctx->last_sr.ntp_timestamp = AV_NOPTS_VALUE;
rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
rtpctx->base_timestamp = 0;
rtpctx->timestamp = 0;
--
2.39.5 (Apple Git-154)
_______________________________________________
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".
^ permalink raw reply [flat|nested] 3+ messages in thread
* [FFmpeg-devel] [PATCH 3/3] lavf: add AV_PKT_DATA_RTCP_SR side data type
2025-06-24 18:02 [FFmpeg-devel] [PATCH 1/3] lavf/rtpdec: fix RTCP SR packet length check Marvin Scholz
2025-06-24 18:02 ` [FFmpeg-devel] [PATCH 2/3] lavf: add and use AVRTCPSenderReport struct Marvin Scholz
@ 2025-06-24 18:02 ` Marvin Scholz
1 sibling, 0 replies; 3+ messages in thread
From: Marvin Scholz @ 2025-06-24 18:02 UTC (permalink / raw)
To: ffmpeg-devel
---
libavcodec/packet.c | 1 +
libavcodec/packet.h | 6 ++++++
libavformat/rtpdec.c | 18 ++++++++++++++++++
3 files changed, 25 insertions(+)
diff --git a/libavcodec/packet.c b/libavcodec/packet.c
index 5104eb98b1..2aace71c7d 100644
--- a/libavcodec/packet.c
+++ b/libavcodec/packet.c
@@ -308,6 +308,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type)
case AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM: return "IAMF Recon Gain Info Parameter Data";
case AV_PKT_DATA_FRAME_CROPPING: return "Frame Cropping";
case AV_PKT_DATA_LCEVC: return "LCEVC NAL data";
+ case AV_PKT_DATA_RTCP_SR: return "RTCP Sender Report";
}
return NULL;
}
diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index 71bc2e0575..8ac4ef54ca 100644
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -345,6 +345,12 @@ enum AVPacketSideDataType {
*/
AV_PKT_DATA_LCEVC,
+ /**
+ * Contains the last received RTCP SR (Sender Report) information
+ * in the form of the AVRTCPSenderReport struct.
+ */
+ AV_PKT_DATA_RTCP_SR,
+
/**
* The number of side data types.
* This is not part of the public API/ABI in the sense that it may
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 9c9d66f33d..9d93e9023a 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -611,12 +611,30 @@ static int rtp_set_prft(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp) {
return 0;
}
+static int rtp_add_sr_sidedata(RTPDemuxContext *s, AVPacket *pkt) {
+ AVRTCPSenderReport *sr =
+ (AVRTCPSenderReport *) av_packet_new_side_data(
+ pkt, AV_PKT_DATA_RTCP_SR, sizeof(AVRTCPSenderReport));
+ if (!sr)
+ return AVERROR(ENOMEM);
+
+ memcpy(sr, &s->last_sr, sizeof(AVRTCPSenderReport));
+ s->pending_sr = 0;
+ return 0;
+}
+
/**
* This was the second switch in rtp_parse packet.
* Normalizes time, if required, sets stream_index, etc.
*/
static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp)
{
+ if (s->pending_sr) {
+ int ret = rtp_add_sr_sidedata(s, pkt);
+ if (ret < 0)
+ av_log(s->ic, AV_LOG_WARNING, "rtpdec: failed to add SR sidedata\n");
+ }
+
if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE)
return; /* Timestamp already set by depacketizer */
if (timestamp == RTP_NOTS_VALUE)
--
2.39.5 (Apple Git-154)
_______________________________________________
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".
^ permalink raw reply [flat|nested] 3+ messages in thread