Commit a3522f01 authored by Ghislain MARY's avatar Ghislain MARY

Put RTCP XR and RTCP FB handling in their own source code files + handle...

Put RTCP XR and RTCP FB handling in their own source code files + handle sending of RTCP XR packets.
parent 9d4dfddd
......@@ -45,6 +45,8 @@ LOCAL_SRC_FILES := \
src/payloadtype.c \
src/rtpprofile.c \
src/rtcp.c \
src/rtcp_fb.c \
src/rtcp_xr.c \
src/utils.c \
src/rtcpparse.c \
src/event.c \
......
......@@ -205,6 +205,8 @@
<ClCompile Include="..\..\..\..\src\port.c" />
<ClCompile Include="..\..\..\..\src\posixtimer.c" />
<ClCompile Include="..\..\..\..\src\rtcp.c" />
<ClCompile Include="..\..\..\..\src\rtcp_fb.c" />
<ClCompile Include="..\..\..\..\src\rtcp_xr.c" />
<ClCompile Include="..\..\..\..\src\rtcpparse.c" />
<ClCompile Include="..\..\..\..\src\rtpparse.c" />
<ClCompile Include="..\..\..\..\src\rtpprofile.c" />
......
......@@ -256,15 +256,7 @@ typedef struct _RtcpStream
OrtpRtcpXrMediaCallbacks xr_media_callbacks;
int interval;
bool_t enabled; /*tells whether we can send RTCP packets */
uint32_t last_rtcp_xr_rcvr_rtt_s; /* The time of the last RTCP XR rcvr rtt packet sent, in send timestamp unit */
uint32_t last_rtcp_xr_stat_summary_s; /* The time of the last RTCP XR stat summary packet sent, in send timestamp unit */
uint32_t last_rtcp_xr_voip_metrics_s; /* The time of the last RTCP XR voip metrics packet sent, in send timestamp unit */
uint32_t rtcp_xr_rcvr_rtt_interval; /* The interval in timestamp unit for RTCP XR rcvr rtt packet sending */
uint32_t rtcp_xr_stat_summary_interval; /* The interval in timestamp unit for RTCP XR stat summary packet sending */
uint32_t rtcp_xr_voip_metrics_interval; /* The interval in timestamp unit for RTCP XR voip metrics packet sending */
int rtcp_xr_rcvr_rtt_interval_ms; /* The interval in milliseconds for RTCP XR rcvr rtt packet sending */
int rtcp_xr_stat_summary_interval_ms; /* The interval in milliseconds for RTCP XR stat summary packet sending */
int rtcp_xr_voip_metrics_interval_ms; /* The interval in milliseconds for RTCP XR voip metrics packet sending */
bool_t rtcp_xr_dlrr_to_send;
uint8_t rtcp_fb_fir_seq_nr; /* The FIR command sequence number */
uint32_t last_rtcp_fb_pli_snt;
} RtcpStream;
......@@ -429,9 +421,6 @@ ORTP_PUBLIC void rtp_session_set_rtcp_report_interval(RtpSession *session, int v
ORTP_PUBLIC void rtp_session_set_target_upload_bandwidth(RtpSession *session, int target_bandwidth);
ORTP_PUBLIC void rtp_session_configure_rtcp_xr(RtpSession *session, const OrtpRtcpXrConfiguration *config);
ORTP_PUBLIC void rtp_session_set_rtcp_xr_rcvr_rtt_interval(RtpSession *session, int value_ms);
ORTP_PUBLIC void rtp_session_set_rtcp_xr_stat_summary_interval(RtpSession *session, int value_ms);
ORTP_PUBLIC void rtp_session_set_rtcp_xr_voip_metrics_interval(RtpSession *session, int value_ms);
ORTP_PUBLIC void rtp_session_set_rtcp_xr_media_callbacks(RtpSession *session, const OrtpRtcpXrMediaCallbacks *cbs);
ORTP_PUBLIC void rtp_session_set_ssrc_changed_threshold(RtpSession *session, int numpackets);
......@@ -497,8 +486,10 @@ ORTP_PUBLIC void rtp_session_set_source_description(RtpSession *session, const c
ORTP_PUBLIC void rtp_session_add_contributing_source(RtpSession *session, uint32_t csrc,
const char *cname, const char *name, const char *email, const char *phone,
const char *loc, const char *tool, const char *note);
ORTP_PUBLIC void rtp_session_remove_contributing_sources(RtpSession *session, uint32_t csrc);
ORTP_PUBLIC mblk_t* rtp_session_create_rtcp_sdes_packet(RtpSession *session);
/* DEPRECATED: Use rtp_session_remove_contributing_source instead of rtp_session_remove_contributing_sources */
#define rtp_session_remove_contributing_sources rtp_session_remove_contributing_source
ORTP_PUBLIC void rtp_session_remove_contributing_source(RtpSession *session, uint32_t csrc);
ORTP_PUBLIC mblk_t* rtp_session_create_rtcp_sdes_packet(RtpSession *session, bool_t full);
ORTP_PUBLIC void rtp_session_get_last_recv_time(RtpSession *session, struct timeval *tv);
ORTP_PUBLIC int rtp_session_bye(RtpSession *session, const char *reason);
......
......@@ -11,6 +11,8 @@ set(SOURCE_FILES
port.c
posixtimer.c
rtcp.c
rtcp_fb.c
rtcp_xr.c
rtcpparse.c
rtpparse.c
rtpprofile.c
......
......@@ -32,7 +32,9 @@ libortp_la_SOURCES= str_utils.c \
telephonyevents.c \
payloadtype.c \
rtpprofile.c \
rtcp.c \
rtcp.c \
rtcp_fb.c \
rtcp_xr.c \
utils.c utils.h \
rtcpparse.c \
event.c \
......
This diff is collapsed.
/*
The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
Copyright (C) 2011-2014 Belledonne Communications
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ortp/ortp.h"
#include "ortp/rtpsession.h"
#include "ortp/rtcp.h"
#include "rtpsession_priv.h"
static mblk_t * rtp_session_create_rtcp_fb_pli(RtpSession *session) {
int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t);
mblk_t *h= allocb(size, 0);
rtcp_common_header_t *ch;
rtcp_fb_header_t *fbh;
/* Fill PLI */
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);
fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session));
fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session));
/* Fill common header */
rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_PLI, msgdsize(h));
return h;
}
static mblk_t * rtp_session_create_rtcp_fb_fir(RtpSession *session) {
int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_fir_fci_t);
mblk_t *h = allocb(size, 0);
rtcp_common_header_t *ch;
rtcp_fb_header_t *fbh;
rtcp_fb_fir_fci_t *fci;
/* Fill FIR */
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_fir_fci_t *)h->b_wptr;
h->b_wptr += sizeof(rtcp_fb_fir_fci_t);
fbh->packet_sender_ssrc = htonl(0);
fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session));
fci->ssrc = htonl(rtp_session_get_send_ssrc(session));
fci->seq_nr = session->rtcp.rtcp_fb_fir_seq_nr++;
fci->pad1 = 0;
fci->pad2 = 0;
/* Fill common header */
rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_FIR, msgdsize(h));
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;
int additional_bytes;
int size;
mblk_t *h;
rtcp_common_header_t *ch;
rtcp_fb_header_t *fbh;
rtcp_fb_rpsi_fci_t *fci;
int i;
/* Calculate packet size and allocate memory. */
bit_string_len_in_bytes = (bit_string_len / 8) + (((bit_string_len % 8) == 0) ? 0 : 1);
additional_bytes = bit_string_len_in_bytes - 2;
if (additional_bytes < 0) additional_bytes = 0;
size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_rpsi_fci_t) + additional_bytes;
h = allocb(size, 0);
/* 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));
if (bit_string_len <= 16) {
fci->pb = 16 - bit_string_len;
memset(&fci->bit_string, 0, 2);
} else {
fci->pb = (bit_string_len - 16) % 32;
memset(&fci->bit_string, 0, bit_string_len_in_bytes);
}
fci->payload_type = rtp_session_get_recv_payload_type(session) & 0x7F;
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;
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)
&& ((st->snd_last_ts - rtcp_st->last_rtcp_fb_pli_snt) > 1000)) {
rtcp_st->last_rtcp_fb_pli_snt = st->snd_last_ts;
m = NULL; //make_sr(session);
m_pli = rtp_session_create_rtcp_fb_pli(session);
concatb(m, m_pli);
/* send the compound packet */
//notify_sent_rtcp(session, m);
ortp_message("Sending RTCP SR compound message with PLI on session [%p]", session);
rtp_session_rtcp_send(session, m);
}
}
void rtp_session_send_rtcp_fb_fir(RtpSession *session) {
mblk_t *m;
mblk_t *m_fir;
PayloadType *pt = rtp_profile_get_payload(session->snd.profile, session->snd.pt);
if (payload_type_get_flags(pt) & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
m = NULL; //make_sr(session);
m_fir = rtp_session_create_rtcp_fb_fir(session);
concatb(m, m_fir);
/* send the compound packet */
//notify_sent_rtcp(session, m);
ortp_message("Sending RTCP SR compound message with FIR on session [%p]", 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;
PayloadType *pt = rtp_profile_get_payload(session->snd.profile, session->snd.pt);
if (payload_type_get_flags(pt) & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
m = NULL; //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;
PayloadType *pt = rtp_profile_get_payload(session->snd.profile, session->snd.pt);
if (payload_type_get_flags(pt) & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
m = NULL; //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);
}
}
This diff is collapsed.
......@@ -40,20 +40,12 @@
#endif
#endif
extern mblk_t *rtcp_create_simple_bye_packet(uint32_t ssrc, const char *reason);
extern int rtcp_sr_init(RtpSession *session, char *buf, int size);
extern int rtcp_rr_init(RtpSession *session, char *buf, int size);
/* this function initialize all session parameter's that depend on the payload type */
static void payload_type_changed(RtpSession *session, PayloadType *pt){
jitter_control_set_payload(&session->rtp.jittctl,pt);
rtp_session_set_time_jump_limit(session,session->rtp.time_jump);
rtp_session_set_rtcp_report_interval(session,session->rtcp.interval);
rtp_session_set_rtcp_xr_rcvr_rtt_interval(session, session->rtcp.rtcp_xr_rcvr_rtt_interval_ms);
rtp_session_set_rtcp_xr_stat_summary_interval(session, session->rtcp.rtcp_xr_stat_summary_interval_ms);
rtp_session_set_rtcp_xr_voip_metrics_interval(session, session->rtcp.rtcp_xr_voip_metrics_interval_ms);
if (pt->type==PAYLOAD_VIDEO){
session->permissive=TRUE;
ortp_message("Using permissive algorithm");
......@@ -432,43 +424,6 @@ void rtp_session_set_target_upload_bandwidth(RtpSession *session, int target_ban
rtp_session_schedule_first_rtcp_send(session);
}
void rtp_session_configure_rtcp_xr(RtpSession *session, const OrtpRtcpXrConfiguration *config) {
if (config != NULL) {
session->rtcp.xr_conf = *config;
}
}
static void set_rtcp_xr_interval(RtpSession *session, uint32_t *interval, int *interval_ms, int value_ms) {
int sendpt = rtp_session_get_send_payload_type(session);
if (sendpt != -1) {
PayloadType *pt = rtp_profile_get_payload(session->snd.profile, sendpt);
if (pt != NULL){
*interval_ms = value_ms;
*interval = (value_ms * pt->clock_rate) / 1000;
}
}
}
void rtp_session_set_rtcp_xr_rcvr_rtt_interval(RtpSession *session, int value_ms) {
set_rtcp_xr_interval(session, &session->rtcp.rtcp_xr_rcvr_rtt_interval, &session->rtcp.rtcp_xr_rcvr_rtt_interval_ms, value_ms);
}
void rtp_session_set_rtcp_xr_stat_summary_interval(RtpSession *session, int value_ms) {
set_rtcp_xr_interval(session, &session->rtcp.rtcp_xr_stat_summary_interval, &session->rtcp.rtcp_xr_stat_summary_interval_ms, value_ms);
}
void rtp_session_set_rtcp_xr_voip_metrics_interval(RtpSession *session, int value_ms) {
set_rtcp_xr_interval(session, &session->rtcp.rtcp_xr_voip_metrics_interval, &session->rtcp.rtcp_xr_voip_metrics_interval_ms, value_ms);
}
void rtp_session_set_rtcp_xr_media_callbacks(RtpSession *session, const OrtpRtcpXrMediaCallbacks *cbs) {
if (cbs != NULL) {
memcpy(&session->rtcp.xr_media_callbacks, cbs, sizeof(session->rtcp.xr_media_callbacks));
} else {
memset(&session->rtcp.xr_media_callbacks, 0, sizeof(session->rtcp.xr_media_callbacks));
}
}
/**
* Set the RTP profile to be used for the sending by this session. By default, all session are created by
* rtp_session_new() are initialized with the AV profile, as defined in RFC 3551. The application
......@@ -967,7 +922,7 @@ __rtp_session_sendm_with_ts (RtpSession * session, mblk_t *mp, uint32_t packet_t
error = rtp_session_rtp_send (session, mp);
/*send RTCP packet if needed */
rtp_session_rtcp_process_send(session);
rtp_session_run_rtcp_send_scheduler(session);
/* receives rtcp packet if session is send-only*/
/*otherwise it is done in rtp_session_recvm_with_ts */
if (session->mode==RTP_SESSION_SENDONLY) rtp_session_rtcp_recv(session);
......@@ -1209,7 +1164,7 @@ rtp_session_recvm_with_ts (RtpSession * session, uint32_t user_ts)
{
ortp_debug ("No mp for timestamp queried");
}
rtp_session_rtcp_process_recv(session);
rtp_session_run_rtcp_send_scheduler(session);
if (session->flags & RTP_SESSION_SCHEDULED)
{
......
......@@ -1277,7 +1277,7 @@ static int process_rtcp_packet( RtpSession *session, mblk_t *block, struct socka
static void reply_to_collaborative_rtcp_xr_packet(RtpSession *session, mblk_t *block) {
if (rtcp_is_XR(block) && (rtcp_XR_get_block_type(block) == RTCP_XR_RCVR_RTT)) {
rtp_session_send_rtcp_xr_dlrr(session);
session->rtcp.rtcp_xr_dlrr_to_send = TRUE;
}
}
......@@ -1325,7 +1325,6 @@ static void rtp_process_incoming_packet(RtpSession * session, mblk_t * mp, bool_
that a message has been received*/
mblk_t * copy = copymsg(mp);
/* post an event to notify the application */
update_avg_rtcp_size(session, msgdsize(mp));
rtp_session_notify_inc_rtcp(session,mp);
/* reply to collaborative RTCP XR packets if needed. */
if (session->rtcp.xr_conf.enabled == TRUE){
......
......@@ -59,9 +59,17 @@ int rtp_session_rtcp_send (RtpSession * session, mblk_t * m);
void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_ts, struct sockaddr *addr, socklen_t addrlen);
void rtp_session_schedule_first_rtcp_send(RtpSession *session);
void rtp_session_run_rtcp_send_scheduler(RtpSession *session);
void update_avg_rtcp_size(RtpSession *session, int bytes);
mblk_t * rtp_session_network_simulate(RtpSession *session, mblk_t *input, bool_t *is_rtp_packet);
void ortp_network_simulator_destroy(OrtpNetworkSimulatorCtx *sim);
void rtcp_common_header_init(rtcp_common_header_t *ch, RtpSession *s,int type, int rc, int bytes_len);
mblk_t * make_xr_rcvr_rtt(RtpSession *session);
mblk_t * make_xr_dlrr(RtpSession *session);
mblk_t * make_xr_stat_summary(RtpSession *session);
mblk_t * make_xr_voip_metrics(RtpSession *session);
#endif
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