From 5a9a142f4e404fe5b9e3066f6cda72022cbd569e Mon Sep 17 00:00:00 2001 From: Sebastian Reimers Date: Wed, 4 Sep 2024 23:33:47 +0200 Subject: [PATCH 1/2] rtp/rtcp: add RTCP Generic NACK packet (RFC 4585 6.2.1) --- include/re_rtp.h | 2 ++ src/rtp/rtcp.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/re_rtp.h b/include/re_rtp.h index 449ad1a28..db65339fe 100644 --- a/include/re_rtp.h +++ b/include/re_rtp.h @@ -268,6 +268,8 @@ int rtcp_send_app(struct rtp_sock *rs, const char name[4], const uint8_t *data, size_t len); int rtcp_send_fir(struct rtp_sock *rs, uint32_t ssrc); int rtcp_send_nack(struct rtp_sock *rs, uint16_t fsn, uint16_t blp); +int rtcp_send_gnack(struct rtp_sock *rs, uint32_t ssrc, uint16_t fsn, + uint16_t blp); int rtcp_send_pli(struct rtp_sock *rs, uint32_t fb_ssrc); int rtcp_send_fir_rfc5104(struct rtp_sock *rs, uint32_t ssrc, uint8_t fir_seqn); diff --git a/src/rtp/rtcp.c b/src/rtp/rtcp.c index 51142a726..c3520c265 100644 --- a/src/rtp/rtcp.c +++ b/src/rtp/rtcp.c @@ -89,6 +89,36 @@ int rtcp_send_nack(struct rtp_sock *rs, uint16_t fsn, uint16_t blp) } +static int encode_gnack(struct mbuf *mb, void *arg) +{ + struct gnack *fci = arg; + + int err = mbuf_write_u16(mb, htons(fci->pid)); + err |= mbuf_write_u16(mb, htons(fci->blp)); + return err; +} + + +/** + * Send an RTCP Generic NACK packet (RFC 4585 6.2.1) + * + * @param rs RTP Socket + * @param ssrc SSRC of the target encoder + * @param fsn First Sequence Number lost + * @param blp Bitmask of lost packets + * + * @return 0 for success, otherwise errorcode + */ +int rtcp_send_gnack(struct rtp_sock *rs, uint32_t ssrc, uint16_t fsn, + uint16_t blp) +{ + struct gnack fci = {fsn, blp}; + return rtcp_quick_send(rs, RTCP_RTPFB, RTCP_RTPFB_GNACK, + rtp_sess_ssrc(rs), ssrc, &encode_gnack, + &fci); +} + + /** * Send an RTCP Picture Loss Indication (PLI) packet * From 415bbf64751c887d65e3a1521b834d060b57259c Mon Sep 17 00:00:00 2001 From: Sebastian Reimers Date: Wed, 4 Sep 2024 23:46:17 +0200 Subject: [PATCH 2/2] test/rtcp: add rtcp_send_gnack test --- test/rtcp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/rtcp.c b/test/rtcp.c index 1641866f3..011e813d9 100644 --- a/test/rtcp.c +++ b/test/rtcp.c @@ -198,6 +198,8 @@ struct agent { struct sa laddr_rtcp; unsigned rtp_count; unsigned psfb_count; + unsigned rtpfb_count; + unsigned gnack_count; }; @@ -222,6 +224,12 @@ static void rtcp_recv_handler(const struct sa *src, struct rtcp_msg *msg, switch (msg->hdr.pt) { + case RTCP_RTPFB: + if (msg->r.fb.fci.gnackv->pid == 42) + ++ag->gnack_count; + ++ag->rtpfb_count; + break; + case RTCP_PSFB: ++ag->psfb_count; re_cancel(); @@ -266,6 +274,9 @@ static int test_rtcp_loop_base(bool mux) rtcp_start(a.rtp_sock, "cname", &b.laddr_rtcp); rtcp_start(b.rtp_sock, "cname", &a.laddr_rtcp); + err = rtcp_send_gnack(a.rtp_sock, rtp_sess_ssrc(b.rtp_sock), 42, 0); + TEST_ERR(err); + err = rtcp_send_pli(a.rtp_sock, rtp_sess_ssrc(b.rtp_sock)); TEST_ERR(err); @@ -276,6 +287,8 @@ static int test_rtcp_loop_base(bool mux) ASSERT_EQ(0, a.psfb_count); ASSERT_EQ(0, b.rtp_count); ASSERT_EQ(1, b.psfb_count); + ASSERT_EQ(1, b.rtpfb_count); + ASSERT_EQ(1, b.gnack_count); out: mem_deref(b.rtp_sock);