00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "real.h"
00027
00028
00029
00030
00031
00032 static char *b64_decode(const char *in, char *out, int *size) {
00033
00034 char dtable[256];
00035 int i,k;
00036 unsigned int j;
00037
00038 for (i = 0; i < 255; i++) {
00039 dtable[i] = 0x80;
00040 }
00041 for (i = 'A'; i <= 'Z'; i++) {
00042 dtable[i] = 0 + (i - 'A');
00043 }
00044 for (i = 'a'; i <= 'z'; i++) {
00045 dtable[i] = 26 + (i - 'a');
00046 }
00047 for (i = '0'; i <= '9'; i++) {
00048 dtable[i] = 52 + (i - '0');
00049 }
00050 dtable['+'] = 62;
00051 dtable['/'] = 63;
00052 dtable['='] = 0;
00053
00054 k=0;
00055
00056 for (j=0; j<strlen(in); j+=4) {
00057 char a[4], b[4];
00058
00059 for (i = 0; i < 4; i++) {
00060 int c = in[i+j];
00061
00062 if (dtable[c] & 0x80) {
00063 printf("Illegal character '%c' in input.\n", c);
00064 exit(1);
00065 }
00066 a[i] = (char) c;
00067 b[i] = (char) dtable[c];
00068 }
00069
00070 out[k++] = (b[0] << 2) | (b[1] >> 4);
00071 out[k++] = (b[1] << 4) | (b[2] >> 2);
00072 out[k++] = (b[2] << 6) | b[3];
00073 i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
00074 if (i < 3) {
00075 out[k]=0;
00076 *size=k;
00077 return out;
00078 }
00079 }
00080 out[k]=0;
00081 *size=k;
00082 return out;
00083 }
00084
00085 static char *nl(char *data) {
00086
00087 char *nlptr = (data) ? strchr(data,'\n') : NULL;
00088 return (nlptr) ? nlptr + 1 : NULL;
00089 }
00090
00091 static int filter(const char *in, const char *filter, char **out) {
00092
00093 int flen=strlen(filter);
00094 int len;
00095
00096 if (!in) return 0;
00097
00098 len = (strchr(in,'\n')) ? strchr(in,'\n')-in : strlen(in);
00099 if (!strncmp(in,filter,flen)) {
00100 if(in[flen]=='"') flen++;
00101 if(in[len-1]==13) len--;
00102 if(in[len-1]=='"') len--;
00103 memcpy(*out, in+flen, len-flen+1);
00104 (*out)[len-flen]=0;
00105 return len-flen;
00106 }
00107 return 0;
00108 }
00109
00110 static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
00111
00112 sdpplin_stream_t *desc = malloc(sizeof(sdpplin_stream_t));
00113 char *buf = malloc(32000);
00114 char *decoded = malloc(32000);
00115 int handled;
00116
00117 if( !desc ) return NULL;
00118 memset(desc, 0, sizeof(sdpplin_stream_t));
00119
00120 if( !buf ) goto error;
00121 if( !decoded ) goto error;
00122
00123 if (filter(*data, "m=", &buf)) {
00124 desc->id = strdup(buf);
00125 } else {
00126 lprintf("sdpplin: no m= found.\n");
00127 goto error;
00128 }
00129 *data=nl(*data);
00130
00131 while (*data && **data && *data[0]!='m') {
00132 handled=0;
00133
00134 if(filter(*data,"a=control:streamid=",&buf)) {
00135 desc->stream_id=atoi(buf);
00136 handled=1;
00137 *data=nl(*data);
00138 }
00139 if(filter(*data,"a=MaxBitRate:integer;",&buf)) {
00140 desc->max_bit_rate=atoi(buf);
00141 if (!desc->avg_bit_rate)
00142 desc->avg_bit_rate=desc->max_bit_rate;
00143 handled=1;
00144 *data=nl(*data);
00145 }
00146 if(filter(*data,"a=MaxPacketSize:integer;",&buf)) {
00147 desc->max_packet_size=atoi(buf);
00148 if (!desc->avg_packet_size)
00149 desc->avg_packet_size=desc->max_packet_size;
00150 handled=1;
00151 *data=nl(*data);
00152 }
00153 if(filter(*data,"a=StartTime:integer;",&buf)) {
00154 desc->start_time=atoi(buf);
00155 handled=1;
00156 *data=nl(*data);
00157 }
00158 if(filter(*data,"a=Preroll:integer;",&buf)) {
00159 desc->preroll=atoi(buf);
00160 handled=1;
00161 *data=nl(*data);
00162 }
00163 if(filter(*data,"a=length:npt=",&buf)) {
00164 desc->duration=(uint32_t)(atof(buf)*1000);
00165 handled=1;
00166 *data=nl(*data);
00167 }
00168 if(filter(*data,"a=StreamName:string;",&buf)) {
00169 desc->stream_name=strdup(buf);
00170 desc->stream_name_size=strlen(desc->stream_name);
00171 handled=1;
00172 *data=nl(*data);
00173 }
00174 if(filter(*data,"a=mimetype:string;",&buf)) {
00175 desc->mime_type=strdup(buf);
00176 desc->mime_type_size=strlen(desc->mime_type);
00177 handled=1;
00178 *data=nl(*data);
00179 }
00180 if(filter(*data,"a=OpaqueData:buffer;",&buf)) {
00181 decoded = b64_decode(buf, decoded, &(desc->mlti_data_size));
00182 desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size);
00183 memcpy(desc->mlti_data, decoded, desc->mlti_data_size);
00184 handled=1;
00185 *data=nl(*data);
00186 lprintf("mlti_data_size: %i\n", desc->mlti_data_size);
00187 }
00188 if(filter(*data,"a=ASMRuleBook:string;",&buf)) {
00189 desc->asm_rule_book=strdup(buf);
00190 handled=1;
00191 *data=nl(*data);
00192 }
00193
00194 if(!handled) {
00195 #ifdef LOG
00196 int len=strchr(*data,'\n')-(*data);
00197 memcpy(buf, *data, len+1);
00198 buf[len]=0;
00199 printf("libreal: sdpplin: not handled: '%s'\n", buf);
00200 #endif
00201 *data=nl(*data);
00202 }
00203 }
00204 if( buf ) free(buf);
00205 if( decoded )free(decoded);
00206 return desc;
00207
00208 error:
00209 if( decoded ) free(decoded);
00210 if( desc ) free( desc );
00211 if( buf ) free( buf );
00212 return NULL;
00213 }
00214
00215 sdpplin_t *sdpplin_parse(char *data) {
00216
00217 sdpplin_t *desc = malloc(sizeof(sdpplin_t));
00218 sdpplin_stream_t *stream;
00219 char *buf=malloc(3200);
00220 char *decoded=malloc(3200);
00221 int handled;
00222 int len;
00223
00224 if( !desc ) return NULL;
00225 if( !buf ) {
00226 free( desc );
00227 return NULL;
00228 }
00229 if( !decoded ) {
00230 free( buf );
00231 free( desc );
00232 return NULL;
00233 }
00234 memset(desc, 0, sizeof(sdpplin_t));
00235
00236 while (data && *data) {
00237 handled=0;
00238
00239 if (filter(data, "m=", &buf)) {
00240 stream=sdpplin_parse_stream(&data);
00241 lprintf("got data for stream id %u\n", stream->stream_id);
00242 desc->stream[stream->stream_id]=stream;
00243 continue;
00244 }
00245 if(filter(data,"a=Title:buffer;",&buf)) {
00246 decoded=b64_decode(buf, decoded, &len);
00247 desc->title=strdup(decoded);
00248 handled=1;
00249 data=nl(data);
00250 }
00251 if(filter(data,"a=Author:buffer;",&buf)) {
00252 decoded=b64_decode(buf, decoded, &len);
00253 desc->author=strdup(decoded);
00254 handled=1;
00255 data=nl(data);
00256 }
00257 if(filter(data,"a=Copyright:buffer;",&buf)) {
00258 decoded=b64_decode(buf, decoded, &len);
00259 desc->copyright=strdup(decoded);
00260 handled=1;
00261 data=nl(data);
00262 }
00263 if(filter(data,"a=Abstract:buffer;",&buf)) {
00264 decoded=b64_decode(buf, decoded, &len);
00265 desc->abstract=strdup(decoded);
00266 handled=1;
00267 data=nl(data);
00268 }
00269 if(filter(data,"a=StreamCount:integer;",&buf)) {
00270 desc->stream_count=atoi(buf);
00271 desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
00272 handled=1;
00273 data=nl(data);
00274 }
00275 if(filter(data,"a=Flags:integer;",&buf)) {
00276 desc->flags=atoi(buf);
00277 handled=1;
00278 data=nl(data);
00279 }
00280
00281 if(!handled) {
00282 #ifdef LOG
00283 int len=strchr(data,'\n')-data;
00284 memcpy(buf, data, len+1);
00285 buf[len]=0;
00286 printf("libreal: sdpplin: not handled: '%s'\n", buf);
00287 #endif
00288 data=nl(data);
00289 }
00290 }
00291
00292 free(decoded);
00293 free(buf);
00294 return desc;
00295 }
00296
00297 void sdpplin_free(sdpplin_t *description) {
00298
00299 int i;
00300
00301 if( !description ) return;
00302
00303 for( i=0; i<description->stream_count; i++ ) {
00304 if( description->stream[i] ) {
00305 if( description->stream[i]->id ) free( description->stream[i]->id );
00306 if( description->stream[i]->bandwidth ) free( description->stream[i]->bandwidth );
00307 if( description->stream[i]->range ) free( description->stream[i]->range );
00308 if( description->stream[i]->length ) free( description->stream[i]->length );
00309 if( description->stream[i]->rtpmap ) free( description->stream[i]->rtpmap );
00310 if( description->stream[i]->mimetype ) free( description->stream[i]->mimetype );
00311 if( description->stream[i]->stream_name ) free( description->stream[i]->stream_name );
00312 if( description->stream[i]->mime_type ) free( description->stream[i]->mime_type );
00313 if( description->stream[i]->mlti_data ) free( description->stream[i]->mlti_data );
00314 if( description->stream[i]->rmff_flags ) free( description->stream[i]->rmff_flags );
00315 if( description->stream[i]->asm_rule_book ) free( description->stream[i]->asm_rule_book );
00316 free( description->stream[i] );
00317 }
00318 }
00319 if( description->stream_count ) free( description->stream );
00320
00321 if( description->owner ) free( description->owner );
00322 if( description->session_name ) free( description->session_name );
00323 if( description->session_info ) free( description->session_info );
00324 if( description->uri ) free( description->uri );
00325 if( description->email ) free( description->email );
00326 if( description->phone ) free( description->phone );
00327 if( description->connection ) free( description->connection );
00328 if( description->bandwidth ) free( description->bandwidth );
00329 if( description->title ) free( description->title );
00330 if( description->author ) free( description->author );
00331 if( description->copyright ) free( description->copyright );
00332 if( description->keywords ) free( description->keywords );
00333 if( description->asm_rule_book ) free( description->asm_rule_book );
00334 if( description->abstract ) free( description->abstract );
00335 if( description->range ) free( description->range );
00336 free(description);
00337 }