mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
Parse rtcp-fb attributes contained in SDP.
This commit is contained in:
parent
cc4095de90
commit
ad64b94401
5 changed files with 134 additions and 26 deletions
|
|
@ -76,28 +76,34 @@ static void add_rtcp_fb_nack_attribute(belle_sdp_media_description_t *media_desc
|
|||
belle_sdp_media_description_add_attribute(media_desc, BELLE_SDP_ATTRIBUTE(attribute));
|
||||
}
|
||||
|
||||
static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, const SalMediaDescription *md, const SalStreamDescription *stream, int nb_avpf_pt) {
|
||||
static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, const SalMediaDescription *md, const SalStreamDescription *stream) {
|
||||
MSList *pt_it;
|
||||
PayloadType *pt;
|
||||
PayloadTypeAvpfParams avpf_params;
|
||||
belle_sdp_rtcp_fb_attribute_t *attribute = belle_sdp_rtcp_fb_attribute_new();
|
||||
|
||||
belle_sdp_rtcp_fb_attribute_set_id(attribute, -1);
|
||||
belle_sdp_rtcp_fb_attribute_set_type(attribute, BELLE_SDP_RTCP_FB_TRR_INT);
|
||||
belle_sdp_rtcp_fb_attribute_set_trr_int(attribute, md->avpf_rr_interval);
|
||||
belle_sdp_media_description_add_attribute(media_desc, BELLE_SDP_ATTRIBUTE(attribute));
|
||||
if ((stream->type == SalVideo) && (nb_avpf_pt > 0)) {
|
||||
if (nb_avpf_pt == ms_list_size(stream->payloads)) {
|
||||
add_rtcp_fb_nack_attribute(media_desc, -1, BELLE_SDP_RTCP_FB_PLI);
|
||||
add_rtcp_fb_nack_attribute(media_desc, -1, BELLE_SDP_RTCP_FB_SLI);
|
||||
add_rtcp_fb_nack_attribute(media_desc, -1, BELLE_SDP_RTCP_FB_RPSI);
|
||||
} else {
|
||||
for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
|
||||
pt = (PayloadType *) pt_it->data;
|
||||
if (payload_type_get_flags(pt) & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
|
||||
add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_PLI);
|
||||
add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_SLI);
|
||||
add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_RPSI);
|
||||
}
|
||||
}
|
||||
|
||||
for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
|
||||
pt = (PayloadType *)pt_it->data;
|
||||
|
||||
/* AVPF/SAVPF profile is used so enable AVPF for all paylad types. */
|
||||
payload_type_set_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED);
|
||||
avpf_params = payload_type_get_avpf_params(pt);
|
||||
avpf_params.trr_interval = md->avpf_rr_interval;
|
||||
|
||||
/* Add rtcp-fb attributes according to the AVPF features of the payload types. */
|
||||
if (avpf_params.features & PAYLOAD_TYPE_AVPF_PLI) {
|
||||
add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_PLI);
|
||||
}
|
||||
if (avpf_params.features & PAYLOAD_TYPE_AVPF_SLI) {
|
||||
add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_SLI);
|
||||
}
|
||||
if (avpf_params.features & PAYLOAD_TYPE_AVPF_RPSI) {
|
||||
add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_RPSI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -134,13 +140,12 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
int rtp_port;
|
||||
int rtcp_port;
|
||||
bool_t different_rtp_and_rtcp_addr;
|
||||
int nb_avpf_pt = 0;
|
||||
|
||||
|
||||
rtp_addr=stream->rtp_addr;
|
||||
rtcp_addr=stream->rtcp_addr;
|
||||
rtp_port=stream->rtp_port;
|
||||
rtcp_port=stream->rtcp_port;
|
||||
|
||||
|
||||
media_desc = belle_sdp_media_description_create ( sal_stream_description_get_type_as_string(stream)
|
||||
,stream->rtp_port
|
||||
,1
|
||||
|
|
@ -149,7 +154,6 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
if (stream->payloads) {
|
||||
for ( pt_it=stream->payloads; pt_it!=NULL; pt_it=pt_it->next ) {
|
||||
pt= ( PayloadType* ) pt_it->data;
|
||||
if (payload_type_get_flags(pt) & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) nb_avpf_pt++;
|
||||
mime_param= belle_sdp_mime_parameter_create ( pt->mime_type
|
||||
, payload_type_get_number ( pt )
|
||||
, pt->clock_rate
|
||||
|
|
@ -175,7 +179,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
}else inet6=FALSE;
|
||||
belle_sdp_media_description_set_connection(media_desc,belle_sdp_connection_create("IN", inet6 ? "IP6" : "IP4", rtp_addr));
|
||||
}
|
||||
|
||||
|
||||
if ( stream->bandwidth>0 )
|
||||
belle_sdp_media_description_set_bandwidth ( media_desc,"AS",stream->bandwidth );
|
||||
|
||||
|
|
@ -238,7 +242,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
}
|
||||
|
||||
if ((stream->proto == SalProtoRtpAvpf) || (stream->proto == SalProtoRtpSavpf)) {
|
||||
add_rtcp_fb_attributes(media_desc, md, stream, nb_avpf_pt);
|
||||
add_rtcp_fb_attributes(media_desc, md, stream);
|
||||
}
|
||||
|
||||
if (stream->rtcp_xr.enabled == TRUE) {
|
||||
|
|
@ -324,9 +328,11 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr
|
|||
|
||||
static void sdp_parse_payload_types(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
|
||||
PayloadType *pt;
|
||||
PayloadTypeAvpfParams avpf_params;
|
||||
belle_sip_list_t* mime_param_it=NULL;
|
||||
belle_sdp_mime_parameter_t* mime_param;
|
||||
belle_sip_list_t* mime_params=belle_sdp_media_description_build_mime_parameters ( media_desc );
|
||||
memset(&avpf_params, 0, sizeof(avpf_params));
|
||||
for ( mime_param_it=mime_params
|
||||
; mime_param_it!=NULL
|
||||
; mime_param_it=mime_param_it->next ) {
|
||||
|
|
@ -338,6 +344,7 @@ static void sdp_parse_payload_types(belle_sdp_media_description_t *media_desc, S
|
|||
pt->mime_type=ms_strdup ( belle_sdp_mime_parameter_get_type ( mime_param ) );
|
||||
pt->channels=belle_sdp_mime_parameter_get_channel_count ( mime_param );
|
||||
payload_type_set_send_fmtp ( pt,belle_sdp_mime_parameter_get_parameters ( mime_param ) );
|
||||
payload_type_set_avpf_params(pt, avpf_params);
|
||||
stream->payloads=ms_list_append ( stream->payloads,pt );
|
||||
stream->ptime=belle_sdp_mime_parameter_get_ptime ( mime_param );
|
||||
ms_message ( "Found payload %s/%i fmtp=%s",pt->mime_type,pt->clock_rate,
|
||||
|
|
@ -441,6 +448,87 @@ static void sdp_parse_media_ice_parameters(belle_sdp_media_description_t *media_
|
|||
}
|
||||
}
|
||||
|
||||
static void enable_avpf_for_stream(SalStreamDescription *stream) {
|
||||
MSList *pt_it;
|
||||
PayloadType *pt;
|
||||
PayloadTypeAvpfParams avpf_params;
|
||||
|
||||
for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
|
||||
pt = (PayloadType *)pt_it->data;
|
||||
avpf_params = payload_type_get_avpf_params(pt);
|
||||
payload_type_set_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED);
|
||||
avpf_params.features |= PAYLOAD_TYPE_AVPF_FIR;
|
||||
avpf_params.trr_interval = 0;
|
||||
payload_type_set_avpf_params(pt, avpf_params);
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb_attribute, PayloadType *pt) {
|
||||
PayloadTypeAvpfParams avpf_params = payload_type_get_avpf_params(pt);
|
||||
switch (belle_sdp_rtcp_fb_attribute_get_type(fb_attribute)) {
|
||||
case BELLE_SDP_RTCP_FB_NACK:
|
||||
switch (belle_sdp_rtcp_fb_attribute_get_param(fb_attribute)) {
|
||||
case BELLE_SDP_RTCP_FB_PLI:
|
||||
avpf_params.features |= PAYLOAD_TYPE_AVPF_PLI;
|
||||
break;
|
||||
case BELLE_SDP_RTCP_FB_SLI:
|
||||
avpf_params.features |= PAYLOAD_TYPE_AVPF_SLI;
|
||||
break;
|
||||
case BELLE_SDP_RTCP_FB_RPSI:
|
||||
avpf_params.features |= PAYLOAD_TYPE_AVPF_RPSI;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BELLE_SDP_RTCP_FB_TRR_INT:
|
||||
avpf_params.trr_interval = (unsigned char)belle_sdp_rtcp_fb_attribute_get_trr_int(fb_attribute);
|
||||
break;
|
||||
case BELLE_SDP_RTCP_FB_ACK:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
payload_type_set_avpf_params(pt, avpf_params);
|
||||
}
|
||||
|
||||
static void sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
|
||||
belle_sip_list_t *it;
|
||||
belle_sdp_attribute_t *attribute;
|
||||
belle_sdp_rtcp_fb_attribute_t *fb_attribute;
|
||||
MSList *pt_it;
|
||||
PayloadType *pt;
|
||||
int8_t pt_num;
|
||||
|
||||
/* Handle rtcp-fb attributes that concern all payload types. */
|
||||
for (it = belle_sdp_media_description_get_attributes(media_desc); it != NULL; it = it->next) {
|
||||
attribute = BELLE_SDP_ATTRIBUTE(it->data);
|
||||
if (keywordcmp("rtcp-fb", belle_sdp_attribute_get_name(attribute)) == 0) {
|
||||
fb_attribute = BELLE_SDP_RTCP_FB_ATTRIBUTE(attribute);
|
||||
if (belle_sdp_rtcp_fb_attribute_get_id(fb_attribute) == -1) {
|
||||
for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
|
||||
pt = (PayloadType *)pt_it->data;
|
||||
apply_rtcp_fb_attribute_to_payload(fb_attribute, pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle rtcp-fb attributes that are specefic to a payload type. */
|
||||
for (it = belle_sdp_media_description_get_attributes(media_desc); it != NULL; it = it->next) {
|
||||
attribute = BELLE_SDP_ATTRIBUTE(it->data);
|
||||
if (keywordcmp("rtcp-fb", belle_sdp_attribute_get_name(attribute)) == 0) {
|
||||
fb_attribute = BELLE_SDP_RTCP_FB_ATTRIBUTE(attribute);
|
||||
pt_num = belle_sdp_rtcp_fb_attribute_get_id(fb_attribute);
|
||||
for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) {
|
||||
pt = (PayloadType *)pt_it->data;
|
||||
if (payload_type_get_number(pt) == (int)pt_num) {
|
||||
apply_rtcp_fb_attribute_to_payload(fb_attribute, pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sal_init_rtcp_xr_description(OrtpRtcpXrConfiguration *config) {
|
||||
config->enabled = FALSE;
|
||||
config->rcvr_rtt_mode = OrtpRtcpXrRcvrRttNone;
|
||||
|
|
@ -583,6 +671,12 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
/* Get ICE candidate attributes if any */
|
||||
sdp_parse_media_ice_parameters(media_desc, stream);
|
||||
|
||||
/* Get RTCP-FB attributes if any */
|
||||
if ((stream->proto == SalProtoRtpAvpf) || (stream->proto == SalProtoRtpSavpf)) {
|
||||
enable_avpf_for_stream(stream);
|
||||
sdp_parse_rtcp_fb_parameters(media_desc, stream);
|
||||
}
|
||||
|
||||
/* Get RTCP-XR attributes if any */
|
||||
stream->rtcp_xr = md->rtcp_xr; // Use session parameters if no stream parameters are defined
|
||||
sdp_parse_media_rtcp_xr_parameters(media_desc, &stream->rtcp_xr);
|
||||
|
|
|
|||
|
|
@ -2840,8 +2840,8 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
|
||||
if (proxy!=NULL) {
|
||||
from=linphone_proxy_config_get_identity(proxy);
|
||||
cp->avpf_enabled = proxy->avpf_enabled;
|
||||
cp->avpf_rr_interval = proxy->avpf_rr_interval;
|
||||
cp->avpf_enabled = linphone_proxy_config_is_avpf_enabled(proxy);
|
||||
cp->avpf_rr_interval = linphone_proxy_config_get_avpf_rr_interval(proxy);
|
||||
}
|
||||
|
||||
/* if no proxy or no identity defined for this proxy, default to primary contact*/
|
||||
|
|
@ -6438,6 +6438,7 @@ void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *para
|
|||
params->media_encryption=linphone_core_get_media_encryption(lc);
|
||||
params->in_conference=FALSE;
|
||||
params->privacy=LinphonePrivacyDefault;
|
||||
params->avpf_enabled=TRUE;
|
||||
}
|
||||
|
||||
void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id) {
|
||||
|
|
|
|||
|
|
@ -936,6 +936,13 @@ LINPHONE_PUBLIC LinphonePrivacyMask linphone_proxy_config_get_privacy(const Linp
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg, bool_t enable);
|
||||
|
||||
/**
|
||||
* Indicates whether AVPF/SAVPF is being used for calls using this proxy config.
|
||||
* @param[in] cfg #LinphoneProxyConfig object
|
||||
* @return True if AVPF/SAVPF is enabled, false otherwise.
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_proxy_config_is_avpf_enabled(LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* Set the interval between regular RTCP reports when using AVPF/SAVPF.
|
||||
* @param[in] cfg #LinphoneProxyConfig object
|
||||
|
|
|
|||
|
|
@ -324,9 +324,11 @@ static bool_t local_stream_not_already_used(const SalMediaDescription *result, c
|
|||
}
|
||||
|
||||
/*in answering mode, we consider that if we are able to make AVPF/SAVP/SAVPF, then we can do AVP as well*/
|
||||
static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote){
|
||||
if (local==remote) return TRUE;
|
||||
if ((remote==SalProtoRtpAvp) && ((local==SalProtoRtpSavp) || (local==SalProtoRtpAvpf) || (local==SalProtoRtpSavpf)))
|
||||
static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote) {
|
||||
if (local == remote) return TRUE;
|
||||
if ((remote == SalProtoRtpAvpf) && (local == SalProtoRtpSavpf))
|
||||
return TRUE;
|
||||
if ((remote == SalProtoRtpAvp) && ((local == SalProtoRtpSavp) || (local == SalProtoRtpAvpf) || (local == SalProtoRtpSavpf)))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1551,6 +1551,10 @@ void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg, bool_t enable)
|
|||
cfg->avpf_enabled = enable;
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_is_avpf_enabled(LinphoneProxyConfig *cfg) {
|
||||
return cfg->avpf_enabled;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_avpf_rr_interval(LinphoneProxyConfig *cfg, uint8_t interval) {
|
||||
if (interval > 5) interval = 5;
|
||||
cfg->avpf_rr_interval = interval;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue