Commit d7661ae0 authored by Ghislain MARY's avatar Ghislain MARY

Implement RTCP PSFB SLI and RPSI packets.

parent c0c169f7
......@@ -292,6 +292,35 @@ typedef struct rtcp_fb_fir_fci {
uint16_t pad2;
} rtcp_fb_fir_fci_t;
#define rtcp_fb_fir_fci_get_ssrc(fci) ntohl((fci)->ssrc)
#define rtcp_fb_fir_fci_get_seq_nr(fci) (fci)->seq_nr
typedef struct rtcp_fb_sli_fci {
uint32_t value;
} rtcp_fb_sli_fci_t;
#define rtcp_fb_sli_fci_get_first(fci) \
((uint16_t)((ntohl((fci)->value) >> 19) & 0x00001FFF))
#define rtcp_fb_sli_fci_set_first(fci, first) \
((fci)->value) = htonl((ntohl((fci)->value) & 0x0007FFFF) | (((first) & 0x00001FFF) << 19))
#define rtcp_fb_sli_fci_get_number(fci) \
((uint16_t)((ntohl((fci)->value) >> 6) & 0x00001FFF))
#define rtcp_fb_sli_fci_set_number(fci, number) \
((fci)->value) = htonl((ntohl((fci)->value) & 0xFFF8003F) | (((number) & 0x00001FFF) << 6))
#define rtcp_fb_sli_fci_get_picture_id(fci) \
((uint8_t)(ntohl((fci)->value) & 0x0000003F))
#define rtcp_fb_sli_fci_set_picture_id(fci, picture_id) \
((fci)->value) = htonl((ntohl((fci)->value) & 0xFFFFFFC0) | ((picture_id) & 0x0000003F))
typedef struct rtcp_fb_rpsi_fci {
uint8_t pb;
uint8_t payload_type;
uint16_t bit_string[1];
} rtcp_fb_rpsi_fci_t;
#define rtcp_fb_rpsi_fci_get_payload_type(fci) (fci)->payload_type
#define rtcp_fb_rpsi_fci_get_bit_string(fci) ((uint8_t *)(fci)->bit_string)
#define MIN_RTCP_PSFB_PACKET_SIZE (sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t))
......@@ -414,8 +443,9 @@ ORTP_PUBLIC rtcp_psfb_type_t rtcp_PSFB_get_type(const mblk_t *m);
ORTP_PUBLIC uint32_t rtcp_PSFB_get_packet_sender_ssrc(const mblk_t *m);
ORTP_PUBLIC uint32_t rtcp_PSFB_get_media_source_ssrc(const mblk_t *m);
ORTP_PUBLIC rtcp_fb_fir_fci_t * rtcp_PSFB_fir_get_fci(const mblk_t *m, unsigned int idx);
ORTP_PUBLIC uint32_t rtcp_PSFB_fir_fci_get_ssrc(const rtcp_fb_fir_fci_t *fci);
ORTP_PUBLIC uint8_t rtcp_PSFB_fir_fci_get_seq_nr(const rtcp_fb_fir_fci_t *fci);
ORTP_PUBLIC rtcp_fb_sli_fci_t * rtcp_PSFB_sli_get_fci(const mblk_t *m, unsigned int idx);
ORTP_PUBLIC rtcp_fb_rpsi_fci_t * rtcp_PSFB_rpsi_get_fci(const mblk_t *m);
ORTP_PUBLIC uint16_t rtcp_PSFB_rpsi_get_fci_bit_string_len(const mblk_t *m);
#ifdef __cplusplus
......
......@@ -515,6 +515,8 @@ ORTP_PUBLIC void rtp_session_send_rtcp_xr_voip_metrics(RtpSession *session);
ORTP_PUBLIC void rtp_session_send_rtcp_fb_pli(RtpSession *session);
ORTP_PUBLIC void rtp_session_send_rtcp_fb_fir(RtpSession *session);
ORTP_PUBLIC void rtp_session_send_rtcp_fb_sli(RtpSession *session, uint16_t first, uint16_t number, uint8_t picture_id);
ORTP_PUBLIC void rtp_session_send_rtcp_fb_rpsi(RtpSession *session, uint8_t *bit_string, uint16_t bit_string_len);
/*private */
......
......@@ -833,6 +833,65 @@ static mblk_t * rtp_session_create_rtcp_fb_fir(RtpSession *session) {
return h;
}
static mblk_t * rtp_session_create_rtcp_fb_sli(RtpSession *session, uint16_t first, uint16_t number, uint8_t picture_id) {
int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_sli_fci_t);
mblk_t *h = allocb(size, 0);
rtcp_common_header_t *ch;
rtcp_fb_header_t *fbh;
rtcp_fb_sli_fci_t *fci;
/* Fill SLI */
ch = (rtcp_common_header_t *)h->b_wptr;
h->b_wptr += sizeof(rtcp_common_header_t);
fbh = (rtcp_fb_header_t *)h->b_wptr;
h->b_wptr += sizeof(rtcp_fb_header_t);
fci = (rtcp_fb_sli_fci_t *)h->b_wptr;
h->b_wptr += sizeof(rtcp_fb_sli_fci_t);
fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session));
fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session));
rtcp_fb_sli_fci_set_first(fci, first);
rtcp_fb_sli_fci_set_number(fci, number);
rtcp_fb_sli_fci_set_picture_id(fci, picture_id);
/* Fill common header */
rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_SLI, msgdsize(h));
return h;
}
static mblk_t * rtp_session_create_rtcp_fb_rpsi(RtpSession *session, uint8_t *bit_string, uint16_t bit_string_len) {
uint16_t bit_string_len_in_bytes = (bit_string_len / 8) + (((bit_string_len % 8) == 0) ? 0 : 1);
int additional_bytes = bit_string_len_in_bytes - 2;
int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_rpsi_fci_t) + additional_bytes;
mblk_t *h = allocb(size, 0);
rtcp_common_header_t *ch;
rtcp_fb_header_t *fbh;
rtcp_fb_rpsi_fci_t *fci;
int i;
/* Fill RPSI */
ch = (rtcp_common_header_t *)h->b_wptr;
h->b_wptr += sizeof(rtcp_common_header_t);
fbh = (rtcp_fb_header_t *)h->b_wptr;
h->b_wptr += sizeof(rtcp_fb_header_t);
fci = (rtcp_fb_rpsi_fci_t *)h->b_wptr;
h->b_wptr += sizeof(rtcp_fb_rpsi_fci_t);
fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session));
fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session));
fci->pb = (bit_string_len_in_bytes * 8) - bit_string_len;
fci->payload_type = rtp_session_get_recv_payload_type(session) & 0x7F;
memset(&fci->bit_string, 0, bit_string_len_in_bytes);
memcpy(&fci->bit_string, bit_string, bit_string_len / 8);
for (i = 0; i < (bit_string_len % 8); i++) {
fci->bit_string[bit_string_len_in_bytes - 1] |= (bit_string[bit_string_len_in_bytes - 1] & (1 << (7 - i)));
}
/* Fill common header */
rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_RPSI, msgdsize(h));
return h;
}
void rtp_session_send_rtcp_fb_pli(RtpSession *session) {
mblk_t *m;
mblk_t *m_pli;
......@@ -874,3 +933,45 @@ void rtp_session_send_rtcp_fb_fir(RtpSession *session) {
rtp_session_rtcp_send(session, m);
}
}
void rtp_session_send_rtcp_fb_sli(RtpSession *session, uint16_t first, uint16_t number, uint8_t picture_id) {
mblk_t *m;
mblk_t *m_sli;
RtpStream *st = &session->rtp;
RtcpStream *rtcp_st = &session->rtcp;
PayloadType *pt = rtp_profile_get_payload(session->snd.profile, session->snd.pt);
if (payload_type_get_flags(pt) & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
rtcp_st->last_rtcp_report_snt_r = st->rcv_last_app_ts;
rtcp_st->last_rtcp_report_snt_s = st->snd_last_ts;
m = make_sr(session);
m_sli = rtp_session_create_rtcp_fb_sli(session, first, number, picture_id);
concatb(m, m_sli);
/* send the compound packet */
notify_sent_rtcp(session, m);
ortp_message("Sending RTCP SR compound message with SLI on session [%p]", session);
rtp_session_rtcp_send(session, m);
}
}
void rtp_session_send_rtcp_fb_rpsi(RtpSession *session, uint8_t *bit_string, uint16_t bit_string_len) {
mblk_t *m;
mblk_t *m_rpsi;
RtpStream *st = &session->rtp;
RtcpStream *rtcp_st = &session->rtcp;
PayloadType *pt = rtp_profile_get_payload(session->snd.profile, session->snd.pt);
if (payload_type_get_flags(pt) & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
rtcp_st->last_rtcp_report_snt_r = st->rcv_last_app_ts;
rtcp_st->last_rtcp_report_snt_s = st->snd_last_ts;
m = make_sr(session);
m_rpsi = rtp_session_create_rtcp_fb_rpsi(session, bit_string, bit_string_len);
concatb(m, m_rpsi);
/* send the compound packet */
notify_sent_rtcp(session, m);
ortp_message("Sending RTCP SR compound message with RPSI on session [%p]", session);
rtp_session_rtcp_send(session, m);
}
}
......@@ -537,18 +537,29 @@ uint32_t rtcp_PSFB_get_media_source_ssrc(const mblk_t *m) {
}
rtcp_fb_fir_fci_t * rtcp_PSFB_fir_get_fci(const mblk_t *m, unsigned int idx) {
rtcp_common_header_t *ch = (rtcp_common_header_t *)m->b_rptr;
unsigned int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + ((idx + 1) * sizeof(rtcp_fb_fir_fci_t));
if (rtcp_common_header_get_length(ch) < (size / 8)) {
unsigned int rtcp_size = rtcp_get_size(m);
if (size > rtcp_size) {
return NULL;
}
return (rtcp_fb_fir_fci_t *)(m->b_rptr + size - sizeof(rtcp_fb_fir_fci_t));
}
uint32_t rtcp_PSFB_fir_fci_get_ssrc(const rtcp_fb_fir_fci_t *fci) {
return ntohl(fci->ssrc);
rtcp_fb_sli_fci_t * rtcp_PSFB_sli_get_fci(const mblk_t *m, unsigned int idx) {
unsigned int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + ((idx + 1) * sizeof(rtcp_fb_sli_fci_t));
unsigned int rtcp_size = rtcp_get_size(m);
if (size > rtcp_size) {
return NULL;
}
return (rtcp_fb_sli_fci_t *)(m->b_rptr + size - sizeof(rtcp_fb_sli_fci_t));
}
rtcp_fb_rpsi_fci_t * rtcp_PSFB_rpsi_get_fci(const mblk_t *m) {
return (rtcp_fb_rpsi_fci_t *)(m->b_rptr + sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t));
}
uint8_t rtcp_PSFB_fir_fci_get_seq_nr(const rtcp_fb_fir_fci_t *fci) {
return fci->seq_nr;
uint16_t rtcp_PSFB_rpsi_get_fci_bit_string_len(const mblk_t *m) {
rtcp_fb_rpsi_fci_t *fci = rtcp_PSFB_rpsi_get_fci(m);
uint16_t bit_string_len_in_bytes = rtcp_get_size(m) - (sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + 2);
return ((bit_string_len_in_bytes * 8) - fci->pb);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment