mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-02 02:16:24 +00:00
Handle AVPF and SAVPF profiles.
This commit is contained in:
parent
92b20e62fe
commit
2110281d2e
10 changed files with 132 additions and 80 deletions
|
|
@ -70,7 +70,7 @@ static void sdp_process(SalOp *h){
|
|||
strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
|
||||
h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
|
||||
|
||||
if (h->result->streams[i].proto == SalProtoRtpSavp) {
|
||||
if ((h->result->streams[i].proto == SalProtoRtpSavpf) || (h->result->streams[i].proto == SalProtoRtpSavp)) {
|
||||
h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
if ( stream->bandwidth>0 )
|
||||
belle_sdp_media_description_set_bandwidth ( media_desc,"AS",stream->bandwidth );
|
||||
|
||||
if ( stream->proto == SalProtoRtpSavp ) {
|
||||
if ((stream->proto == SalProtoRtpSavpf) || (stream->proto == SalProtoRtpSavp)) {
|
||||
/* add crypto lines */
|
||||
for ( j=0; j<SAL_CRYPTO_ALGO_MAX; j++ ) {
|
||||
MSCryptoSuiteNameParams desc;
|
||||
|
|
@ -469,11 +469,15 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
proto = belle_sdp_media_get_protocol ( media );
|
||||
stream->proto=SalProtoOther;
|
||||
if ( proto ) {
|
||||
if ( strcasecmp ( proto,"RTP/AVP" ) ==0 )
|
||||
stream->proto=SalProtoRtpAvp;
|
||||
else if ( strcasecmp ( proto,"RTP/SAVP" ) ==0 ) {
|
||||
stream->proto=SalProtoRtpSavp;
|
||||
}else{
|
||||
if (strcasecmp(proto, "RTP/AVP") == 0) {
|
||||
stream->proto = SalProtoRtpAvp;
|
||||
} else if (strcasecmp(proto, "RTP/SAVP") == 0) {
|
||||
stream->proto = SalProtoRtpSavp;
|
||||
} else if (strcasecmp(proto, "RTP/AVPF") == 0) {
|
||||
stream->proto = SalProtoRtpAvpf;
|
||||
} else if (strcasecmp(proto, "RTP/SAVPF") == 0) {
|
||||
stream->proto = SalProtoRtpSavpf;
|
||||
} else {
|
||||
strncpy(stream->proto_other,proto,sizeof(stream->proto_other)-1);
|
||||
}
|
||||
}
|
||||
|
|
@ -532,7 +536,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
}
|
||||
|
||||
/* Read crypto lines if any */
|
||||
if ( stream->proto == SalProtoRtpSavp ) {
|
||||
if ((stream->proto == SalProtoRtpSavpf) || (stream->proto == SalProtoRtpSavp)) {
|
||||
sdp_parse_media_crypto_parameters(media_desc, stream);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -670,24 +670,32 @@ static void call_failure(SalOp *op){
|
|||
break;
|
||||
case SalReasonUnsupportedContent: /*<this is for compatibility: linphone sent 415 because of SDP offer answer failure*/
|
||||
case SalReasonNotAcceptable:
|
||||
//media_encryption_mandatory
|
||||
if (call->params.media_encryption == LinphoneMediaEncryptionSRTP &&
|
||||
!linphone_core_is_media_encryption_mandatory(lc)) {
|
||||
ms_message("Outgoing call [%p] failed with SRTP and/or AVPF enabled", call);
|
||||
if ((call->state == LinphoneCallOutgoingInit)
|
||||
|| (call->state == LinphoneCallOutgoingProgress)
|
||||
|| (call->state == LinphoneCallOutgoingRinging) /* Push notification case */
|
||||
|| (call->state == LinphoneCallOutgoingEarlyMedia)) {
|
||||
int i;
|
||||
ms_message("Outgoing call [%p] failed with SRTP (SAVP) enabled",call);
|
||||
if (call->state==LinphoneCallOutgoingInit
|
||||
|| call->state==LinphoneCallOutgoingProgress
|
||||
|| call->state==LinphoneCallOutgoingRinging /*push case*/
|
||||
|| call->state==LinphoneCallOutgoingEarlyMedia){
|
||||
ms_message("Retrying call [%p] with AVP",call);
|
||||
/* clear SRTP local params */
|
||||
call->params.media_encryption = LinphoneMediaEncryptionNone;
|
||||
for(i=0; i<call->localdesc->n_active_streams; i++) {
|
||||
call->localdesc->streams[i].proto = SalProtoRtpAvp;
|
||||
memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
|
||||
for (i = 0; i < call->localdesc->n_active_streams; i++) {
|
||||
if (call->params.media_encryption == LinphoneMediaEncryptionSRTP) {
|
||||
if (call->params.avpf_enabled == TRUE) {
|
||||
if (i == 0) ms_message("Retrying call [%p] with SAVP", call);
|
||||
call->params.avpf_enabled = FALSE;
|
||||
linphone_core_restart_invite(lc, call);
|
||||
return;
|
||||
} else if (!linphone_core_is_media_encryption_mandatory(lc)) {
|
||||
if (i == 0) ms_message("Retrying call [%p] with AVP", call);
|
||||
call->params.media_encryption = LinphoneMediaEncryptionNone;
|
||||
memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
|
||||
linphone_core_restart_invite(lc, call);
|
||||
return;
|
||||
}
|
||||
} else if (call->params.avpf_enabled == TRUE) {
|
||||
if (i == 0) ms_message("Retrying call [%p] with AVP", call);
|
||||
call->params.avpf_enabled = FALSE;
|
||||
linphone_core_restart_invite(lc, call);
|
||||
return;
|
||||
}
|
||||
linphone_core_restart_invite(lc, call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
msg=_("Incompatible media parameters.");
|
||||
|
|
|
|||
|
|
@ -265,8 +265,8 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){
|
|||
bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",1);
|
||||
|
||||
for(i=0; i<md->n_active_streams; i++) {
|
||||
if (md->streams[i].proto == SalProtoRtpSavp) {
|
||||
if (keep_srtp_keys && old_md && old_md->streams[i].proto==SalProtoRtpSavp){
|
||||
if (is_encryption_active(&md->streams[i]) == TRUE) {
|
||||
if (keep_srtp_keys && old_md && is_encryption_active(&old_md->streams[i]) == TRUE){
|
||||
int j;
|
||||
ms_message("Keeping same crypto keys.");
|
||||
for(j=0;j<SAL_CRYPTO_ALGO_MAX;++j){
|
||||
|
|
@ -311,6 +311,13 @@ void linphone_call_increment_local_media_description(LinphoneCall *call){
|
|||
md->session_ver++;
|
||||
}
|
||||
|
||||
static SalMediaProto get_proto_from_call_params(LinphoneCallParams *params) {
|
||||
if ((params->media_encryption == LinphoneMediaEncryptionSRTP) && params->avpf_enabled) return SalProtoRtpSavpf;
|
||||
if (params->media_encryption == LinphoneMediaEncryptionSRTP) return SalProtoRtpSavp;
|
||||
if (params->avpf_enabled) return SalProtoRtpAvpf;
|
||||
return SalProtoRtpAvp;
|
||||
}
|
||||
|
||||
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
MSList *l;
|
||||
PayloadType *pt;
|
||||
|
|
@ -349,8 +356,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
strncpy(md->streams[0].name,"Audio",sizeof(md->streams[0].name)-1);
|
||||
md->streams[0].rtp_port=call->media_ports[0].rtp_port;
|
||||
md->streams[0].rtcp_port=call->media_ports[0].rtcp_port;
|
||||
md->streams[0].proto=(call->params.media_encryption == LinphoneMediaEncryptionSRTP) ?
|
||||
SalProtoRtpSavp : SalProtoRtpAvp;
|
||||
md->streams[0].proto=get_proto_from_call_params(&call->params);
|
||||
md->streams[0].type=SalAudio;
|
||||
if (call->params.down_ptime)
|
||||
md->streams[0].ptime=call->params.down_ptime;
|
||||
|
|
@ -961,10 +967,6 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
|
|||
return &call->current_params;
|
||||
}
|
||||
|
||||
static bool_t is_video_active(const SalStreamDescription *sd){
|
||||
return sd->rtp_port!=0 && sd->dir!=SalStreamInactive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns call parameters proposed by remote.
|
||||
*
|
||||
|
|
@ -976,19 +978,20 @@ const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call){
|
|||
memset(cp,0,sizeof(*cp));
|
||||
if (call->op){
|
||||
SalMediaDescription *md=sal_call_get_remote_media_description(call->op);
|
||||
if (md){
|
||||
SalStreamDescription *asd,*vsd,*secure_asd,*secure_vsd;
|
||||
if (md) {
|
||||
SalStreamDescription *sd;
|
||||
unsigned int i;
|
||||
unsigned int nb_audio_streams = sal_media_description_nb_active_streams_of_type(md, SalAudio);
|
||||
unsigned int nb_video_streams = sal_media_description_nb_active_streams_of_type(md, SalVideo);
|
||||
|
||||
asd=sal_media_description_find_stream(md,SalProtoRtpAvp,SalAudio);
|
||||
vsd=sal_media_description_find_stream(md,SalProtoRtpAvp,SalVideo);
|
||||
secure_asd=sal_media_description_find_stream(md,SalProtoRtpSavp,SalAudio);
|
||||
secure_vsd=sal_media_description_find_stream(md,SalProtoRtpSavp,SalVideo);
|
||||
if (secure_vsd){
|
||||
cp->has_video=is_video_active(secure_vsd);
|
||||
if (secure_asd || asd==NULL)
|
||||
cp->media_encryption=LinphoneMediaEncryptionSRTP;
|
||||
}else if (vsd){
|
||||
cp->has_video=is_video_active(vsd);
|
||||
for (i = 0; i < nb_video_streams; i++) {
|
||||
sd = sal_media_description_get_active_stream_of_type(md, SalVideo, i);
|
||||
if (is_video_active(sd) == TRUE) cp->has_video = TRUE;
|
||||
if (is_encryption_active(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP;
|
||||
}
|
||||
for (i = 0; i < nb_audio_streams; i++) {
|
||||
sd = sal_media_description_get_active_stream_of_type(md, SalAudio, i);
|
||||
if (is_encryption_active(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP;
|
||||
}
|
||||
if (!cp->has_video){
|
||||
if (md->bandwidth>0 && md->bandwidth<=linphone_core_get_edge_bw(call->core)){
|
||||
|
|
@ -1861,12 +1864,10 @@ static void configure_rtp_session_for_rtcp_xr(LinphoneCore *lc, LinphoneCall *ca
|
|||
const SalStreamDescription *localstream;
|
||||
const SalStreamDescription *remotestream;
|
||||
|
||||
localstream = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, type);
|
||||
if (!localstream) localstream = sal_media_description_find_stream(call->localdesc, SalProtoRtpAvp, type);
|
||||
localstream = sal_media_description_find_best_stream(call->localdesc, type);
|
||||
if (!localstream) return;
|
||||
localconfig = &localstream->rtcp_xr;
|
||||
remotestream = sal_media_description_find_stream(sal_call_get_remote_media_description(call->op), SalProtoRtpSavp, type);
|
||||
if (!remotestream) remotestream = sal_media_description_find_stream(sal_call_get_remote_media_description(call->op), SalProtoRtpAvp, type);
|
||||
remotestream = sal_media_description_find_best_stream(sal_call_get_remote_media_description(call->op), type);
|
||||
if (!remotestream) return;
|
||||
remoteconfig = &remotestream->rtcp_xr;
|
||||
|
||||
|
|
@ -1902,14 +1903,8 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
|
|||
int crypto_idx;
|
||||
|
||||
snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version());
|
||||
/* look for savp stream first */
|
||||
stream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpSavp,SalAudio);
|
||||
/* no savp audio stream, use avp */
|
||||
if (!stream)
|
||||
stream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalAudio);
|
||||
|
||||
stream = sal_media_description_find_best_stream(call->resultdesc, SalAudio);
|
||||
if (stream && stream->dir!=SalStreamInactive && stream->rtp_port!=0){
|
||||
playcard=lc->sound_conf.lsd_card ?
|
||||
lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
|
||||
|
|
@ -1965,8 +1960,8 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
|
|||
call->current_params.record_file=ms_strdup(call->params.record_file);
|
||||
}
|
||||
/* valid local tags are > 0 */
|
||||
if (stream->proto == SalProtoRtpSavp) {
|
||||
local_st_desc=sal_media_description_find_stream(call->localdesc,SalProtoRtpSavp,SalAudio);
|
||||
if (is_encryption_active(stream) == TRUE) {
|
||||
local_st_desc=sal_media_description_find_stream(call->localdesc,stream->proto,SalAudio);
|
||||
crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag);
|
||||
|
||||
if (crypto_idx >= 0) {
|
||||
|
|
@ -2020,17 +2015,10 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCore *lc=call->core;
|
||||
int used_pt=-1;
|
||||
|
||||
/* look for savp stream first */
|
||||
const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpSavp,SalVideo);
|
||||
char rtcp_tool[128]={0};
|
||||
snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version());
|
||||
const SalStreamDescription *vstream;
|
||||
|
||||
/* no savp audio stream, use avp */
|
||||
if (!vstream)
|
||||
vstream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalVideo);
|
||||
snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version());
|
||||
|
||||
/* shutdown preview */
|
||||
if (lc->previewstream!=NULL) {
|
||||
|
|
@ -2038,6 +2026,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
lc->previewstream=NULL;
|
||||
}
|
||||
|
||||
vstream = sal_media_description_find_best_stream(call->resultdesc, SalVideo);
|
||||
if (vstream!=NULL && vstream->dir!=SalStreamInactive && vstream->rtp_port!=0) {
|
||||
const char *rtp_addr=vstream->rtp_addr[0]!='\0' ? vstream->rtp_addr : call->resultdesc->addr;
|
||||
const char *rtcp_addr=vstream->rtcp_addr[0]!='\0' ? vstream->rtcp_addr : call->resultdesc->addr;
|
||||
|
|
@ -2088,7 +2077,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
cam=get_nowebcam_device();
|
||||
}
|
||||
if (!is_inactive){
|
||||
if (vstream->proto == SalProtoRtpSavp) {
|
||||
if (is_encryption_active(vstream) == TRUE) {
|
||||
int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, vstream->crypto_local_tag);
|
||||
if (crypto_idx >= 0) {
|
||||
media_stream_set_srtp_recv_key(&call->videostream->ms,vstream->crypto[0].algo,vstream->crypto[0].master_key);
|
||||
|
|
@ -2121,8 +2110,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
char *cname;
|
||||
bool_t use_arc=linphone_core_adaptive_rate_control_enabled(lc);
|
||||
#ifdef VIDEO_ENABLED
|
||||
const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalVideo);
|
||||
const SalStreamDescription *vstream=sal_media_description_find_best_stream(call->resultdesc,SalVideo);
|
||||
#endif
|
||||
|
||||
call->current_params.audio_codec = NULL;
|
||||
|
|
@ -2209,17 +2197,17 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript
|
|||
SalStreamDescription *new_stream;
|
||||
const SalStreamDescription *local_st_desc;
|
||||
|
||||
local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalAudio);
|
||||
old_stream = sal_media_description_find_stream(old_md, SalProtoRtpSavp, SalAudio);
|
||||
new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalAudio);
|
||||
local_st_desc = sal_media_description_find_secure_stream_of_type(call->localdesc, SalAudio);
|
||||
old_stream = sal_media_description_find_secure_stream_of_type(old_md, SalAudio);
|
||||
new_stream = sal_media_description_find_secure_stream_of_type(new_md, SalAudio);
|
||||
if (call->audiostream && local_st_desc && old_stream && new_stream &&
|
||||
update_stream_crypto_params(call,local_st_desc,old_stream,new_stream,&call->audiostream->ms)){
|
||||
}
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalVideo);
|
||||
old_stream = sal_media_description_find_stream(old_md, SalProtoRtpSavp, SalVideo);
|
||||
new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalVideo);
|
||||
local_st_desc = sal_media_description_find_secure_stream_of_type(call->localdesc, SalVideo);
|
||||
old_stream = sal_media_description_find_secure_stream_of_type(old_md, SalVideo);
|
||||
new_stream = sal_media_description_find_secure_stream_of_type(new_md, SalVideo);
|
||||
if (call->videostream && local_st_desc && old_stream && new_stream &&
|
||||
update_stream_crypto_params(call,local_st_desc,old_stream,new_stream,&call->videostream->ms)){
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2972,7 +2972,7 @@ bool_t linphone_core_media_description_has_srtp(const SalMediaDescription *md){
|
|||
|
||||
for(i=0;i<md->n_active_streams;i++){
|
||||
const SalStreamDescription *sd=&md->streams[i];
|
||||
if (sd->proto!=SalProtoRtpSavp){
|
||||
if (is_encryption_active(sd) != TRUE){
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1520,3 +1520,10 @@ const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc){
|
|||
return result;
|
||||
}
|
||||
|
||||
bool_t is_video_active(const SalStreamDescription *sd) {
|
||||
return (sd->rtp_port != 0) && (sd->dir != SalStreamInactive);
|
||||
}
|
||||
|
||||
bool_t is_encryption_active(const SalStreamDescription *sd) {
|
||||
return ((sd->proto == SalProtoRtpSavpf) || (sd->proto == SalProtoRtpSavp));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
}else{
|
||||
result->rtp_port=0;
|
||||
}
|
||||
if (result->proto == SalProtoRtpSavp) {
|
||||
if (is_encryption_active(result) == TRUE) {
|
||||
/* verify crypto algo */
|
||||
memset(result->crypto, 0, sizeof(result->crypto));
|
||||
if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE))
|
||||
|
|
@ -259,7 +259,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
|
|||
}else{
|
||||
result->rtp_port=0;
|
||||
}
|
||||
if (result->proto == SalProtoRtpSavp) {
|
||||
if (is_encryption_active(result) == TRUE) {
|
||||
/* select crypto algo */
|
||||
memset(result->crypto, 0, sizeof(result->crypto));
|
||||
if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], &result->crypto_local_tag, TRUE))
|
||||
|
|
@ -323,10 +323,11 @@ static bool_t local_stream_not_already_used(const SalMediaDescription *result, c
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*in answering mode, we consider that if we are able to make SAVP, then we can do AVP as well*/
|
||||
/*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) return TRUE;
|
||||
if ((remote==SalProtoRtpAvp) && ((local==SalProtoRtpSavp) || (local==SalProtoRtpAvpf) || (local==SalProtoRtpSavpf)))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ struct _LinphoneCallParams{
|
|||
char *session_name;
|
||||
SalCustomHeader *custom_headers;
|
||||
bool_t has_video;
|
||||
bool_t avpf_enabled; /* RTCP feedback messages are enabled */
|
||||
bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
|
||||
bool_t in_conference; /*in conference mode */
|
||||
bool_t low_bandwidth;
|
||||
|
|
@ -389,6 +390,8 @@ bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc);
|
|||
|
||||
LinphoneCall * is_a_linphone_call(void *user_pointer);
|
||||
LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer);
|
||||
bool_t is_video_active(const SalStreamDescription *sd);
|
||||
bool_t is_encryption_active(const SalStreamDescription *sd);
|
||||
|
||||
void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description);
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,39 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription *md, SalStreamType type) {
|
||||
unsigned int i;
|
||||
unsigned int nb = 0;
|
||||
for (i = 0; i < md->n_active_streams; ++i) {
|
||||
if (md->streams[i].type == type) nb++;
|
||||
}
|
||||
return nb;
|
||||
}
|
||||
|
||||
SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaDescription *md, SalStreamType type, unsigned int idx) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < md->n_active_streams; ++i) {
|
||||
if (md->streams[i].type == type) {
|
||||
if (idx-- == 0) return &md->streams[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SalStreamDescription * sal_media_description_find_secure_stream_of_type(SalMediaDescription *md, SalStreamType type) {
|
||||
SalStreamDescription *desc = sal_media_description_find_stream(md, SalProtoRtpSavpf, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpSavp, type);
|
||||
return desc;
|
||||
}
|
||||
|
||||
SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescription *md, SalStreamType type) {
|
||||
SalStreamDescription *desc = sal_media_description_find_stream(md, SalProtoRtpSavpf, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpSavp, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpAvpf, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpAvp, type);
|
||||
return desc;
|
||||
}
|
||||
|
||||
bool_t sal_media_description_empty(const SalMediaDescription *md){
|
||||
if (md->n_active_streams > 0) return FALSE;
|
||||
return TRUE;
|
||||
|
|
@ -515,6 +548,8 @@ const char* sal_media_proto_to_string(SalMediaProto type) {
|
|||
switch (type) {
|
||||
case SalProtoRtpAvp:return "RTP/AVP";
|
||||
case SalProtoRtpSavp:return "RTP/SAVP";
|
||||
case SalProtoRtpAvpf:return "RTP/AVPF";
|
||||
case SalProtoRtpSavpf:return "RTP/SAVPF";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ const char* sal_stream_type_to_string(SalStreamType type);
|
|||
typedef enum{
|
||||
SalProtoRtpAvp,
|
||||
SalProtoRtpSavp,
|
||||
SalProtoRtpAvpf,
|
||||
SalProtoRtpSavpf,
|
||||
SalProtoOther
|
||||
}SalMediaProto;
|
||||
const char* sal_media_proto_to_string(SalMediaProto type);
|
||||
|
|
@ -251,6 +253,10 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD
|
|||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
|
||||
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
||||
SalMediaProto proto, SalStreamType type);
|
||||
unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription *md, SalStreamType type);
|
||||
SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaDescription *md, SalStreamType type, unsigned int idx);
|
||||
SalStreamDescription * sal_media_description_find_secure_stream_of_type(SalMediaDescription *md, SalStreamType type);
|
||||
SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescription *md, SalStreamType type);
|
||||
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir);
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue