Skip to content

Commit

Permalink
rtp: Add support for RFC5104 PSFB FIR.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lastique committed Jun 22, 2022
1 parent 7bcf5e4 commit a4896ad
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/re_rtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum rtcp_rtpfb {
enum rtcp_psfb {
RTCP_PSFB_PLI = 1, /**< Picture Loss Indication (PLI) */
RTCP_PSFB_SLI = 2, /**< Slice Loss Indication (SLI) */
RTCP_PSFB_FIR = 4, /**< Full INTRA-frame Request (FIR) (RFC 5104) */
RTCP_PSFB_AFB = 15, /**< Application layer Feedback Messages */
};

Expand Down Expand Up @@ -167,6 +168,10 @@ struct rtcp_msg {
uint16_t number;
uint8_t picid;
} *sliv;
struct fir_rfc5104 {
uint32_t ssrc;
uint8_t seq_n;
} *firv;
struct twcc {
uint16_t seq;
uint16_t count;
Expand Down Expand Up @@ -237,6 +242,7 @@ int rtcp_send_app(struct rtp_sock *rs, const char name[4],
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_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);
int rtcp_debug(struct re_printf *pf, const struct rtp_sock *rs);
void *rtcp_sock(const struct rtp_sock *rs);
int rtcp_stats(struct rtp_sock *rs, uint32_t ssrc, struct rtcp_stats *stats);
Expand Down
17 changes: 17 additions & 0 deletions src/rtp/fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

enum {
GNACK_SIZE = 4,
FIR_SIZE = 8,
SLI_SIZE = 4
};

Expand Down Expand Up @@ -253,6 +254,22 @@ int rtcp_psfb_decode(struct mbuf *mb, struct rtcp_msg *msg)
mbuf_advance(mb, sz);
break;

case RTCP_PSFB_FIR:
msg->r.fb.n /= 2u; /* each FCI entry size is 2 32-bit words */
sz = msg->r.fb.n * sizeof(*msg->r.fb.fci.firv);
msg->r.fb.fci.firv = mem_alloc(sz, NULL);
if (!msg->r.fb.fci.firv)
return ENOMEM;

if (mbuf_get_left(mb) < msg->r.fb.n * FIR_SIZE)
return EBADMSG;
for (i=0; i<msg->r.fb.n; i++) {
msg->r.fb.fci.firv[i].ssrc = ntohl(mbuf_read_u32(mb));
msg->r.fb.fci.firv[i].seq_n = mbuf_read_u8(mb);
mbuf_advance(mb, 3);
}
break;

default:
DEBUG_NOTICE("unknown PSFB fmt %d\n", msg->hdr.count);
break;
Expand Down
35 changes: 35 additions & 0 deletions src/rtp/rtcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,33 @@ int rtcp_send_pli(struct rtp_sock *rs, uint32_t fb_ssrc)
rtp_sess_ssrc(rs), fb_ssrc, NULL, NULL);
}

static int encode_fir_rfc5104_fci(struct mbuf *mb, void *arg)
{
struct fir_rfc5104 *fci = arg;
int err = mbuf_write_u32(mb, htonl(fci->ssrc));
err |= mbuf_write_u8(mb, fci->seq_n);
err |= mbuf_write_u8(mb, 0);
err |= mbuf_write_u8(mb, 0);
err |= mbuf_write_u8(mb, 0);
return err;
}

/**
* Send an RTCP Full INTRA-frame Request (FIR) packet according to RFC 5104
*
* @param rs RTP Socket
* @param ssrc SSRC of the target encoder
* @param fir_seqn FIR sequence number
*
* @return 0 for success, otherwise errorcode
*/
int rtcp_send_fir_rfc5104(struct rtp_sock *rs, uint32_t ssrc, uint8_t fir_seqn)
{
struct fir_rfc5104 fci = { ssrc, fir_seqn };
return rtcp_quick_send(rs, RTCP_PSFB, RTCP_PSFB_FIR,
rtp_sess_ssrc(rs), (uint32_t)0u,
&encode_fir_rfc5104_fci, &fci);
}

const char *rtcp_type_name(enum rtcp_type type)
{
Expand Down Expand Up @@ -272,6 +299,14 @@ int rtcp_msg_print(struct re_printf *pf, const struct rtcp_msg *msg)
err |= re_hprintf(pf, " AFB %u bytes",
msg->r.fb.n * 4);
}
else if (msg->hdr.count == RTCP_PSFB_FIR) {
err |= re_hprintf(pf, " FIR (RFC5104)");
for (i=0; i<msg->r.fb.n; i++) {
err |= re_hprintf(pf, " {ssrc=%08x seq_n=%02x}",
msg->r.fb.fci.firv[i].ssrc,
msg->r.fb.fci.firv[i].seq_n);
}
}
break;

default:
Expand Down

0 comments on commit a4896ad

Please sign in to comment.