* [FFmpeg-devel] [PATCH 1/3] lavf/rtpdec: fix RTCP SR packet length check
@ 2025-06-24 18:02 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 ` [FFmpeg-devel] [PATCH 3/3] lavf: add AV_PKT_DATA_RTCP_SR side data type Marvin Scholz
0 siblings, 2 replies; 3+ messages in thread
From: Marvin Scholz @ 2025-06-24 18:02 UTC (permalink / raw)
To: ffmpeg-devel
The minimum valid packet length is 28, given that the length includes
the packet header.
This didn't cause any issues so far as the code did not care about the
last two fields in the SR section, but will be relevant in a future
commit.
---
libavformat/rtpdec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 2e2cbf5477..97aabcf542 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -187,7 +187,7 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf,
switch (buf[1]) {
case RTCP_SR:
- if (payload_len < 20) {
+ if (payload_len < 28) {
av_log(s->ic, AV_LOG_ERROR, "Invalid RTCP SR packet length\n");
return AVERROR_INVALIDDATA;
}
--
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 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
end of thread, other threads:[~2025-06-24 18:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [FFmpeg-devel] [PATCH 3/3] lavf: add AV_PKT_DATA_RTCP_SR side data type Marvin Scholz
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git