int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) { int i; int nb = 0; for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (sal_stream_description_active(&md->streams[i])) nb++; } return nb; }
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){ int i; for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){ SalStreamDescription *ss=&md->streams[i]; if (!sal_stream_description_active(ss)) continue; ss->dir=stream_dir; } }
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type){ int i; for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){ SalStreamDescription *ss=&md->streams[i]; if (!sal_stream_description_active(ss)) continue; if (ss->proto==proto && ss->type==type) return ss; } return NULL; }
bool_t sal_media_description_has_dtls(const SalMediaDescription *md) { int i; if (md->nb_streams == 0) return FALSE; for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; if (sal_stream_description_has_dtls(&md->streams[i]) != TRUE) return FALSE; } return TRUE; }
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 < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i) { if (!sal_stream_description_active(&md->streams[i])) continue; 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 < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i) { if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].type == type) { if (idx-- == 0) return &md->streams[i]; } } return NULL; }
static const SalStreamDescription *find_local_matching_stream(const SalMediaDescription *result, const SalMediaDescription *local_capabilities, const SalStreamDescription *remote_stream) { int i; for(i=0; i<local_capabilities->nb_streams; ++i) { const SalStreamDescription *ss=&local_capabilities->streams[i]; if (!sal_stream_description_active(ss)) continue; if (ss->type==remote_stream->type && proto_compatible(ss->proto,remote_stream->proto) && local_stream_not_already_used(result,ss)) return ss; } return NULL; }
static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDescription * smd, SalStreamType sal_stream_type) { int count; if (smd != NULL) { for (count = 0; count < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++count) { if (sal_stream_description_active(&smd->streams[count]) && smd->streams[count].type == sal_stream_type) { return &smd->streams[count]; } } } return NULL; }
int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2) { int result = SAL_MEDIA_DESCRIPTION_UNCHANGED; int i; if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED; if (md1->addr[0]!='\0' && md2->addr[0]!='\0' && ms_is_multicast(md1->addr) != ms_is_multicast(md2->addr)) result |= SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED; if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED; if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; /* ICE */ if (strcmp(md1->ice_ufrag, md2->ice_ufrag) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; if (strcmp(md1->ice_pwd, md2->ice_pwd) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; for(i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){ if (!sal_stream_description_active(&md1->streams[i]) && !sal_stream_description_active(&md2->streams[i])) continue; result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]); } return result; }
bool_t sal_media_description_has_ipv6(const SalMediaDescription *md){ int i; if (md->nb_streams == 0) return FALSE; for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].rtp_addr[0] != '\0'){ if (!sal_stream_description_has_ipv6(&md->streams[i])) return FALSE; }else{ if (strchr(md->addr,':') == NULL) return FALSE; } } return TRUE; }
/*check for the presence of at least one stream with requested direction */ static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){ int i; /* we are looking for at least one stream with requested direction, inactive streams are ignored*/ for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){ const SalStreamDescription *ss=&md->streams[i]; if (!sal_stream_description_active(ss)) continue; if (ss->dir==stream_dir) { return TRUE; } /*compatibility check for phones that only used the null address and no attributes */ if (ss->dir==SalStreamSendRecv && stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->rtp_addr))){ return TRUE; } } return FALSE; }