src/payloadtype.c

00001 /*
00002   The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
00003   Copyright (C) 2001  Simon MORLAT simon.morlat@linphone.org
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the Free Software
00017   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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); /*assuming this is the last param */
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                                 /*we don't look at channels if it is undefined
00190                                 ie a negative or zero value*/
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         /* find the slash after the subtype */
00208         rate_str = strchr(subtype, '/');
00209         if (rate_str && strlen(rate_str)>1) {
00210                 *rate_str = 0;
00211                 rate_str++;
00212                 
00213                 /* Look for another slash */
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         // Use default clock rate if none given 
00226         if (rate_str) clock_rate = atoi(rate_str);
00227         else clock_rate = 8000;
00228 
00229         // Use default number of channels if none given 
00230         if (chan_str) channels = atoi(chan_str);
00231         else channels = -1;
00232 
00233         //printf("Searching for payload %s at freq %i with %i channels\n",subtype,clock_rate,ch1annels);
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 /* ! payload are not cloned*/
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 /*clone a profile and its payloads */
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 }

Generated on Fri Feb 15 00:08:47 2008 for oRTP by  doxygen 1.5.4