2 * Copyright (C) 2002-2003 the xine project
4 * This file is part of xine, a free video player.
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 #include <vlc_strings.h>
30 static inline char *nl(char *data) {
31 char *nlptr = (data) ? strchr(data,'\n') : NULL;
32 return (nlptr) ? nlptr + 1 : NULL;
35 static int filter(const char *in, const char *filter, char **out, size_t outlen) {
37 int flen=strlen(filter);
42 len = (strchr(in,'\n')) ? (size_t)(strchr(in,'\n')-in) : strlen(in);
43 if (!strncmp(in,filter,flen)) {
44 if(in[flen]=='"') flen++;
45 if(in[len-1]==13) len--;
46 if(in[len-1]=='"') len--;
47 if( len-flen+1 > outlen )
49 printf("Discarding end of string to avoid overflow");
52 memcpy(*out, in+flen, len-flen+1);
59 static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
61 sdpplin_stream_t *desc;
63 unsigned char* decoded = NULL;
66 desc = calloc( 1, sizeof(sdpplin_stream_t) );
70 buf = malloc( BUFLEN );
74 decoded = malloc( BUFLEN );
78 if (filter(*data, "m=", &buf, BUFLEN)) {
79 desc->id = strdup(buf);
81 lprintf("sdpplin: no m= found.\n");
86 while (*data && **data && *data[0]!='m') {
89 if(filter(*data,"a=control:streamid=",&buf, BUFLEN)) {
90 /* This way negative values are mapped to unfeasibly high
91 * values, and will be discarded afterward
93 unsigned long tmp = strtoul(buf, NULL, 10);
94 if ( tmp > UINT16_MAX )
95 lprintf("stream id out of bound: %lu\n", tmp);
101 if(filter(*data,"a=MaxBitRate:integer;",&buf, BUFLEN)) {
102 desc->max_bit_rate=atoi(buf);
103 if (!desc->avg_bit_rate)
104 desc->avg_bit_rate=desc->max_bit_rate;
108 if(filter(*data,"a=MaxPacketSize:integer;",&buf, BUFLEN)) {
109 desc->max_packet_size=atoi(buf);
110 if (!desc->avg_packet_size)
111 desc->avg_packet_size=desc->max_packet_size;
115 if(filter(*data,"a=StartTime:integer;",&buf, BUFLEN)) {
116 desc->start_time=atoi(buf);
120 if(filter(*data,"a=Preroll:integer;",&buf, BUFLEN)) {
121 desc->preroll=atoi(buf);
125 if(filter(*data,"a=length:npt=",&buf, BUFLEN)) {
126 desc->duration=(uint32_t)(atof(buf)*1000);
130 if(filter(*data,"a=StreamName:string;",&buf, BUFLEN)) {
131 desc->stream_name=strdup(buf);
132 desc->stream_name_size=strlen(desc->stream_name);
136 if(filter(*data,"a=mimetype:string;",&buf, BUFLEN)) {
137 desc->mime_type=strdup(buf);
138 desc->mime_type_size=strlen(desc->mime_type);
142 if(filter(*data,"a=OpaqueData:buffer;",&buf, BUFLEN)) {
143 desc->mlti_data_size =
144 vlc_b64_decode_binary_to_buffer(decoded, BUFLEN, buf );
145 if ( desc->mlti_data_size ) {
146 desc->mlti_data = malloc(desc->mlti_data_size);
147 memcpy(desc->mlti_data, decoded, desc->mlti_data_size);
150 lprintf("mlti_data_size: %i\n", desc->mlti_data_size);
153 if(filter(*data,"a=ASMRuleBook:string;",&buf, BUFLEN)) {
154 desc->asm_rule_book=strdup(buf);
161 int len=strchr(*data,'\n')-(*data);
162 memcpy(buf, *data, len+1);
164 printf("libreal: sdpplin: not handled: '%s'\n", buf);
181 sdpplin_t *sdpplin_parse(char *data)
184 sdpplin_stream_t* stream;
189 desc = calloc( 1, sizeof(sdpplin_t) );
193 buf = malloc( BUFLEN );
200 decoded = malloc( BUFLEN );
209 while (data && *data) {
212 if (filter(data, "m=", &buf, BUFLEN)) {
213 if ( !desc->stream ) {
214 fprintf(stderr, "sdpplin.c: stream identifier found before stream count, skipping.");
217 stream=sdpplin_parse_stream(&data);
218 lprintf("got data for stream id %u\n", stream->stream_id);
219 if ( stream->stream_id >= desc->stream_count )
220 lprintf("stream id %u is greater than stream count %u\n", stream->stream_id, desc->stream_count);
222 desc->stream[stream->stream_id]=stream;
225 if(filter(data,"a=Title:buffer;",&buf, BUFLEN)) {
226 desc->title=vlc_b64_decode(buf);
232 if(filter(data,"a=Author:buffer;",&buf, BUFLEN)) {
233 desc->author=vlc_b64_decode(buf);
239 if(filter(data,"a=Copyright:buffer;",&buf, BUFLEN)) {
240 desc->copyright=vlc_b64_decode(buf);
241 if(desc->copyright) {
246 if(filter(data,"a=Abstract:buffer;",&buf, BUFLEN)) {
247 desc->abstract=vlc_b64_decode(buf);
253 if(filter(data,"a=StreamCount:integer;",&buf, BUFLEN)) {
254 /* This way negative values are mapped to unfeasibly high
255 * values, and will be discarded afterward
257 unsigned long tmp = strtoul(buf, NULL, 10);
258 if ( tmp > UINT16_MAX )
259 lprintf("stream count out of bound: %lu\n", tmp);
261 desc->stream_count = tmp;
262 desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
266 if(filter(data,"a=Flags:integer;",&buf, BUFLEN)) {
267 desc->flags=atoi(buf);
274 int len=strchr(data,'\n')-data;
275 memcpy(buf, data, len+1);
277 printf("libreal: sdpplin: not handled: '%s'\n", buf);
288 void sdpplin_free(sdpplin_t *description) {
292 if( !description ) return;
294 for( i=0; i<description->stream_count; i++ ) {
295 if( description->stream[i] ) {
296 free( description->stream[i]->id );
297 free( description->stream[i]->bandwidth );
298 free( description->stream[i]->range );
299 free( description->stream[i]->length );
300 free( description->stream[i]->rtpmap );
301 free( description->stream[i]->mimetype );
302 free( description->stream[i]->stream_name );
303 free( description->stream[i]->mime_type );
304 free( description->stream[i]->mlti_data );
305 free( description->stream[i]->rmff_flags );
306 free( description->stream[i]->asm_rule_book );
307 free( description->stream[i] );
310 if( description->stream_count )
311 free( description->stream );
313 free( description->owner );
314 free( description->session_name );
315 free( description->session_info );
316 free( description->uri );
317 free( description->email );
318 free( description->phone );
319 free( description->connection );
320 free( description->bandwidth );
321 free( description->title );
322 free( description->author );
323 free( description->copyright );
324 free( description->keywords );
325 free( description->asm_rule_book );
326 free( description->abstract );
327 free( description->range );