From 2848c5617c7826e4c945c7aaf594464f8fe9484f Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 20 Jan 2010 15:29:19 +0100 Subject: [PATCH] sdp parser ready. --- linphone/coreapi/sal.h | 12 +++- linphone/coreapi/sal_eXosip2_sdp.c | 108 +++++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/linphone/coreapi/sal.h b/linphone/coreapi/sal.h index 12fd32bde..c1ea3ad9f 100644 --- a/linphone/coreapi/sal.h +++ b/linphone/coreapi/sal.h @@ -50,19 +50,29 @@ typedef enum { SAL_OTHER } SalStreamType; +typedef enum{ + SAL_PROTO_UNKNOWN, + SAL_PROTO_RTP_AVP, + SAL_PROTO_RTP_SAVP +}SalMediaProto; + typedef struct SalStreamDescription{ + SalMediaProto proto; SalStreamType type; + char addr[64]; int port; MSList *payloads; //mime_type); + if (pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED) + snprintf (attr,sizeof(attr),"%i %s/%i/%i", payload_type_get_number(pt), + pt->mime_type, pt->clock_rate,pt->channels); + else + snprintf (attr,sizeof(attr),"%i %s/%i", payload_type_get_number(pt), + pt->mime_type, pt->clock_rate); sdp_message_a_attribute_add (msg, line, osip_strdup ("rtpmap"), osip_strdup(attr)); @@ -168,3 +175,94 @@ char *media_description_to_sdp(const SalMediaDescription *desc){ sdp_message_to_str(msg,&tmp); return tmp; } + +static int payload_type_fill_from_rtpmap(PayloadType *pt, const char *rtpmap){ + if (rtpmap==NULL){ + PayloadType *refpt=rtp_profile_get_payload(&av_profile,payload_type_get_number(pt)); + if (refpt){ + pt->mime_type=ms_strdup(refpt->mime_type); + pt->clock_rate=refpt->clock_rate; + }else{ + ms_error("payload number %i has no rtpmap and is unknown in AV Profile, ignored.", + payload_type_get_number(pt)); + return -1; + } + }else{ + char *mime=ms_strdup(rtpmap); + char *p=strchr(mime,'/'); + if (p){ + char *chans; + *p='\0'; + p++; + chans=strchr(p,'/'); + if (chans){ + *chans='\0'; + chans++; + pt->channels=atoi(chans); + }else pt->channels=1; + pt->clock_rate=atoi(p); + } + pt->mime_type=mime; + } + return 0; +} + +int sdp_to_media_description(const char *sdp, SalMediaDescription *desc){ + int i,j; + const char *mtype,*proto,*port,*addr,*number; + sdp_message_t *msg; + sdp_bandwidth_t *sbw=NULL; + sdp_message_init(&msg); + if (sdp_message_parse(msg,sdp)!=0){ + ms_error("Fail to parse sdp message !"); + sdp_message_free(msg); + return -1; + } + addr=sdp_message_c_addr_get (msg, -1, 0); + if (addr) + strncpy(desc->addr,addr,sizeof(desc->addr)); + /* for each m= line */ + for (i=0; !sdp_message_endof_media (msg, i) && istreams[i]; + + memset(stream,0,sizeof(*stream)); + mtype = sdp_message_m_media_get(msg, i); + proto = sdp_message_m_proto_get (msg, i); + port = sdp_message_m_port_get(msg, i); + stream->proto=SAL_PROTO_UNKNOWN; + if (proto){ + if (strcasecmp(proto,"RTP/AVP")==0) + stream->proto=SAL_PROTO_RTP_AVP; + else if (strcasecmp(proto,"RTP/SAVP")==0){ + stream->proto=SAL_PROTO_RTP_SAVP; + } + } + addr = sdp_message_c_addr_get (msg, i, 0); + if (addr != NULL) + strncpy(stream->addr,addr,sizeof(stream->addr)); + stream->ptime=_sdp_message_get_a_ptime(msg,i); + if (strcasecmp("audio", mtype) == 0){ + stream->type=SAL_AUDIO; + }else if (strcasecmp("video", mtype) == 0){ + stream->type=SAL_VIDEO; + }else stream->type=SAL_OTHER; + for(j=0;(sbw=sdp_message_bandwidth_get(msg,i,j))!=NULL;++j){ + if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth); + } + /* for each payload type */ + for (j=0;((number=sdp_message_m_payload_get (msg, i,j)) != NULL); j++){ + const char *rtpmap,*fmtp; + int ptn=atoi(number); + PayloadType *pt=payload_type_new(); + payload_type_set_number(pt,ptn); + /* get the rtpmap associated to this codec, if any */ + rtpmap=sdp_message_a_attr_value_get_with_pt(msg, i,ptn,"rtpmap"); + payload_type_fill_from_rtpmap(pt,rtpmap); + /* get the fmtp, if any */ + fmtp=sdp_message_a_attr_value_get_with_pt(msg, i, ptn,"fmtp"); + payload_type_set_send_fmtp(pt,fmtp); + } + } + return 0; +}