00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ortp/ortp.h"
00021 #include "ortp/payloadtype.h"
00022 #include "utils.h"
00023
00024 char *payload_type_get_rtpmap(PayloadType *pt)
00025 {
00026 int len=(int)strlen(pt->mime_type)+15;
00027 char *rtpmap=(char *) ortp_malloc(len);
00028 if (pt->channels>0)
00029 snprintf(rtpmap,len,"%s/%i/%i",pt->mime_type,pt->clock_rate,pt->channels);
00030 else
00031 snprintf(rtpmap,len,"%s/%i",pt->mime_type,pt->clock_rate);
00032 return rtpmap;
00033 }
00034
00035 PayloadType *payload_type_new()
00036 {
00037 PayloadType *newpayload=(PayloadType *)ortp_new0(PayloadType,1);
00038 newpayload->flags|=PAYLOAD_TYPE_ALLOCATED;
00039 return newpayload;
00040 }
00041
00042
00043 PayloadType *payload_type_clone(PayloadType *payload)
00044 {
00045 PayloadType *newpayload=(PayloadType *)ortp_new0(PayloadType,1);
00046 memcpy(newpayload,payload,sizeof(PayloadType));
00047 newpayload->mime_type=ortp_strdup(payload->mime_type);
00048 if (payload->recv_fmtp!=NULL) {
00049 newpayload->recv_fmtp=ortp_strdup(payload->recv_fmtp);
00050 }
00051 if (payload->send_fmtp!=NULL){
00052 newpayload->send_fmtp=ortp_strdup(payload->send_fmtp);
00053 }
00054 newpayload->flags|=PAYLOAD_TYPE_ALLOCATED;
00055 return newpayload;
00056 }
00057
00058 static bool_t canWrite(PayloadType *pt){
00059 if (!(pt->flags & PAYLOAD_TYPE_ALLOCATED)) {
00060 ortp_error("Cannot change parameters of statically defined payload types: make your"
00061 " own copy using payload_type_clone() first.");
00062 return FALSE;
00063 }
00064 return TRUE;
00065 }
00066
00072 void payload_type_set_recv_fmtp(PayloadType *pt, const char *fmtp){
00073 if (canWrite(pt)){
00074 if (pt->recv_fmtp!=NULL) ortp_free(pt->recv_fmtp);
00075 if (fmtp!=NULL) pt->recv_fmtp=ortp_strdup(fmtp);
00076 else pt->recv_fmtp=NULL;
00077 }
00078 }
00079
00085 void payload_type_set_send_fmtp(PayloadType *pt, const char *fmtp){
00086 if (canWrite(pt)){
00087 if (pt->send_fmtp!=NULL) ortp_free(pt->send_fmtp);
00088 if (fmtp!=NULL) pt->send_fmtp=ortp_strdup(fmtp);
00089 else pt->send_fmtp=NULL;
00090 }
00091 }
00092
00093
00094
00095 void payload_type_append_recv_fmtp(PayloadType *pt, const char *fmtp){
00096 if (canWrite(pt)){
00097 if (pt->recv_fmtp==NULL)
00098 pt->recv_fmtp=ortp_strdup(fmtp);
00099 else{
00100 char *tmp=ortp_strdup_printf("%s;%s",pt->recv_fmtp,fmtp);
00101 ortp_free(pt->recv_fmtp);
00102 pt->recv_fmtp=tmp;
00103 }
00104 }
00105 }
00106
00107 void payload_type_append_send_fmtp(PayloadType *pt, const char *fmtp){
00108 if (canWrite(pt)){
00109 if (pt->send_fmtp==NULL)
00110 pt->send_fmtp=ortp_strdup(fmtp);
00111 else{
00112 char *tmp=ortp_strdup_printf("%s;%s",pt->send_fmtp,fmtp);
00113 ortp_free(pt->send_fmtp);
00114 pt->send_fmtp=tmp;
00115 }
00116 }
00117 }
00118
00119
00123 void payload_type_destroy(PayloadType *pt)
00124 {
00125 if (pt->mime_type) ortp_free(pt->mime_type);
00126 if (pt->recv_fmtp) ortp_free(pt->recv_fmtp);
00127 if (pt->send_fmtp) ortp_free(pt->send_fmtp);
00128 ortp_free(pt);
00129 }
00130
00142 bool_t fmtp_get_value(const char *fmtp, const char *param_name, char *result, size_t result_len){
00143 const char *pos=strstr(fmtp,param_name);
00144 if (pos){
00145 const char *equal=strchr(pos,'=');
00146 if (equal){
00147 int copied;
00148 const char *end=strchr(equal+1,';');
00149 if (end==NULL) end=fmtp+strlen(fmtp);
00150 copied=MIN(result_len-1,end-(equal+1));
00151 strncpy(result,equal+1,copied);
00152 result[copied]='\0';
00153 return TRUE;
00154 }
00155 }
00156 return FALSE;
00157 }
00158
00159
00160 int rtp_profile_get_payload_number_from_mime(RtpProfile *profile,const char *mime)
00161 {
00162 PayloadType *pt;
00163 int i;
00164 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
00165 {
00166 pt=rtp_profile_get_payload(profile,i);
00167 if (pt!=NULL)
00168 {
00169 if (strcasecmp(pt->mime_type,mime)==0){
00170 return i;
00171 }
00172 }
00173 }
00174 return -1;
00175 }
00176
00177 int rtp_profile_find_payload_number(RtpProfile*profile,const char *mime,int rate,int channels)
00178 {
00179 int i;
00180 PayloadType *pt;
00181 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
00182 {
00183 pt=rtp_profile_get_payload(profile,i);
00184 if (pt!=NULL)
00185 {
00186 if (strcasecmp(pt->mime_type,mime)==0 &&
00187 pt->clock_rate==rate &&
00188 (pt->channels==channels || channels<=0 || pt->channels<=0)) {
00189
00190
00191
00192 return i;
00193 }
00194 }
00195 }
00196 return -1;
00197 }
00198
00199 int rtp_profile_get_payload_number_from_rtpmap(RtpProfile *profile,const char *rtpmap)
00200 {
00201 int clock_rate, channels, ret;
00202 char* subtype = ortp_strdup( rtpmap );
00203 char* rate_str = NULL;
00204 char* chan_str = NULL;
00205
00206
00207
00208 rate_str = strchr(subtype, '/');
00209 if (rate_str && strlen(rate_str)>1) {
00210 *rate_str = 0;
00211 rate_str++;
00212
00213
00214 chan_str = strchr(rate_str, '/');
00215 if (chan_str && strlen(chan_str)>1) {
00216 *chan_str = 0;
00217 chan_str++;
00218 } else {
00219 chan_str = NULL;
00220 }
00221 } else {
00222 rate_str = NULL;
00223 }
00224
00225
00226 if (rate_str) clock_rate = atoi(rate_str);
00227 else clock_rate = 8000;
00228
00229
00230 if (chan_str) channels = atoi(chan_str);
00231 else channels = -1;
00232
00233
00234 ret=rtp_profile_find_payload_number(profile,subtype,clock_rate,channels);
00235 ortp_free(subtype);
00236 return ret;
00237 }
00238
00239 PayloadType * rtp_profile_find_payload(RtpProfile *prof,const char *mime,int rate,int channels)
00240 {
00241 int i;
00242 i=rtp_profile_find_payload_number(prof,mime,rate,channels);
00243 if (i>=0) return rtp_profile_get_payload(prof,i);
00244 return NULL;
00245 }
00246
00247
00248 PayloadType * rtp_profile_get_payload_from_mime(RtpProfile *profile,const char *mime)
00249 {
00250 int pt;
00251 pt=rtp_profile_get_payload_number_from_mime(profile,mime);
00252 if (pt==-1) return NULL;
00253 else return rtp_profile_get_payload(profile,pt);
00254 }
00255
00256
00257 PayloadType * rtp_profile_get_payload_from_rtpmap(RtpProfile *profile, const char *rtpmap)
00258 {
00259 int pt = rtp_profile_get_payload_number_from_rtpmap(profile,rtpmap);
00260 if (pt==-1) return NULL;
00261 else return rtp_profile_get_payload(profile,pt);
00262 }
00263
00264 int rtp_profile_move_payload(RtpProfile *prof,int oldpos,int newpos){
00265 prof->payload[newpos]=prof->payload[oldpos];
00266 prof->payload[oldpos]=NULL;
00267 return 0;
00268 }
00269
00270 RtpProfile * rtp_profile_new(const char *name)
00271 {
00272 RtpProfile *prof=(RtpProfile*)ortp_new0(RtpProfile,1);
00273 rtp_profile_set_name(prof,name);
00274 return prof;
00275 }
00276
00284 void rtp_profile_set_payload(RtpProfile *prof, int idx, PayloadType *pt){
00285 if (idx<0 || idx>=RTP_PROFILE_MAX_PAYLOADS) {
00286 ortp_error("Bad index %i",idx);
00287 return;
00288 }
00289 prof->payload[idx]=pt;
00290 }
00291
00297 void rtp_profile_clear_all(RtpProfile *obj){
00298 int i;
00299 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++){
00300 obj->payload[i]=0;
00301 }
00302 }
00303
00304
00311 void rtp_profile_set_name(RtpProfile *obj, const char *name){
00312 if (obj->name!=NULL) ortp_free(obj->name);
00313 obj->name=ortp_strdup(name);
00314 }
00315
00316
00317 RtpProfile * rtp_profile_clone(RtpProfile *prof)
00318 {
00319 int i;
00320 PayloadType *pt;
00321 RtpProfile *newprof=rtp_profile_new(prof->name);
00322 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++){
00323 pt=rtp_profile_get_payload(prof,i);
00324 if (pt!=NULL){
00325 rtp_profile_set_payload(newprof,i,pt);
00326 }
00327 }
00328 return newprof;
00329 }
00330
00331
00332
00333 RtpProfile * rtp_profile_clone_full(RtpProfile *prof)
00334 {
00335 int i;
00336 PayloadType *pt;
00337 RtpProfile *newprof=rtp_profile_new(prof->name);
00338 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++){
00339 pt=rtp_profile_get_payload(prof,i);
00340 if (pt!=NULL){
00341 rtp_profile_set_payload(newprof,i,payload_type_clone(pt));
00342 }
00343 }
00344 return newprof;
00345 }
00346
00347 void rtp_profile_destroy(RtpProfile *prof)
00348 {
00349 int i;
00350 PayloadType *payload;
00351 if (prof->name) {
00352 ortp_free(prof->name);
00353 prof->name = NULL;
00354 }
00355 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
00356 {
00357 payload=rtp_profile_get_payload(prof,i);
00358 if (payload!=NULL && (payload->flags & PAYLOAD_TYPE_ALLOCATED))
00359 payload_type_destroy(payload);
00360 }
00361 ortp_free(prof);
00362 }