Mercurial > mplayer.hg
comparison stream/realrtsp/sdpplin.c @ 19271:64d82a45a05d
introduce new 'stream' directory for all stream layer related components and split them from libmpdemux
author | ben |
---|---|
date | Mon, 31 Jul 2006 17:39:17 +0000 |
parents | libmpdemux/realrtsp/sdpplin.c@bbb4cd6f43d6 |
children | 04281be4fbdd |
comparison
equal
deleted
inserted
replaced
19270:7d39b911f0bd | 19271:64d82a45a05d |
---|---|
1 /* | |
2 * This file was ported to MPlayer from xine CVS sdpplin.c,v 1.1 2002/12/24 01:30:22 | |
3 */ | |
4 | |
5 /* | |
6 * Copyright (C) 2002 the xine project | |
7 * | |
8 * This file is part of xine, a free video player. | |
9 * | |
10 * xine is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * xine is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
23 * | |
24 * | |
25 * sdp/sdpplin parser. | |
26 * | |
27 */ | |
28 | |
29 #include "config.h" | |
30 #include "../librtsp/rtsp.h" | |
31 #include "sdpplin.h" | |
32 #include "xbuffer.h" | |
33 #include "mp_msg.h" | |
34 | |
35 /* | |
36 #define LOG | |
37 */ | |
38 | |
39 /* | |
40 * Decodes base64 strings (based upon b64 package) | |
41 */ | |
42 | |
43 static char *b64_decode(const char *in, char *out, int *size) | |
44 { | |
45 char dtable[256]; /* Encode / decode table */ | |
46 int i,j,k; | |
47 | |
48 for (i = 0; i < 255; i++) { | |
49 dtable[i] = 0x80; | |
50 } | |
51 for (i = 'A'; i <= 'Z'; i++) { | |
52 dtable[i] = 0 + (i - 'A'); | |
53 } | |
54 for (i = 'a'; i <= 'z'; i++) { | |
55 dtable[i] = 26 + (i - 'a'); | |
56 } | |
57 for (i = '0'; i <= '9'; i++) { | |
58 dtable[i] = 52 + (i - '0'); | |
59 } | |
60 dtable['+'] = 62; | |
61 dtable['/'] = 63; | |
62 dtable['='] = 0; | |
63 | |
64 k=0; | |
65 | |
66 /*CONSTANTCONDITION*/ | |
67 for (j=0; j<strlen(in); j+=4) | |
68 { | |
69 char a[4], b[4]; | |
70 | |
71 for (i = 0; i < 4; i++) { | |
72 int c = in[i+j]; | |
73 | |
74 if (dtable[c] & 0x80) { | |
75 printf("Illegal character '%c' in input.\n", c); | |
76 // exit(1); | |
77 return NULL; | |
78 } | |
79 a[i] = (char) c; | |
80 b[i] = (char) dtable[c]; | |
81 } | |
82 out = xbuffer_ensure_size(out, k+4); | |
83 out[k++] = (b[0] << 2) | (b[1] >> 4); | |
84 out[k++] = (b[1] << 4) | (b[2] >> 2); | |
85 out[k++] = (b[2] << 6) | b[3]; | |
86 i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); | |
87 if (i < 3) { | |
88 out[k]=0; | |
89 *size=k; | |
90 return out; | |
91 } | |
92 } | |
93 out[k]=0; | |
94 *size=k; | |
95 return out; | |
96 } | |
97 | |
98 static char *nl(char *data) { | |
99 | |
100 char *nlptr = (data) ? strchr(data,'\n') : NULL; | |
101 return (nlptr) ? nlptr + 1 : NULL; | |
102 } | |
103 | |
104 static int filter(const char *in, const char *filter, char **out) { | |
105 | |
106 int flen=strlen(filter); | |
107 int len; | |
108 | |
109 if (!in) | |
110 return 0; | |
111 | |
112 len = (strchr(in,'\n')) ? strchr(in,'\n')-in : strlen(in); | |
113 | |
114 if (!strncmp(in,filter,flen)) | |
115 { | |
116 if(in[flen]=='"') flen++; | |
117 if(in[len-1]==13) len--; | |
118 if(in[len-1]=='"') len--; | |
119 *out = xbuffer_copyin(*out, 0, in+flen, len-flen+1); | |
120 (*out)[len-flen]=0; | |
121 | |
122 return len-flen; | |
123 } | |
124 | |
125 return 0; | |
126 } | |
127 static sdpplin_stream_t *sdpplin_parse_stream(char **data) { | |
128 | |
129 sdpplin_stream_t *desc=calloc(1,sizeof(sdpplin_stream_t)); | |
130 char *buf=xbuffer_init(32); | |
131 char *decoded=xbuffer_init(32); | |
132 int handled; | |
133 int got_mimetype; | |
134 | |
135 if (filter(*data, "m=", &buf)) { | |
136 desc->id = strdup(buf); | |
137 } else | |
138 { | |
139 printf("sdpplin: no m= found.\n"); | |
140 free(desc); | |
141 xbuffer_free(buf); | |
142 return NULL; | |
143 } | |
144 *data=nl(*data); | |
145 | |
146 got_mimetype = 0; | |
147 | |
148 while (*data && **data && *data[0]!='m') { | |
149 #ifdef LOG | |
150 { | |
151 int len=strchr(*data,'\n')-(*data); | |
152 buf = xbuffer_copyin(buf, 0, *data, len+1); | |
153 buf[len]=0; | |
154 printf("libreal: sdpplin_stream: '%s'\n", buf); | |
155 } | |
156 #endif | |
157 | |
158 handled=0; | |
159 | |
160 if(filter(*data,"a=control:streamid=",&buf)) { | |
161 desc->stream_id=atoi(buf); | |
162 handled=1; | |
163 *data=nl(*data); | |
164 } | |
165 | |
166 if(filter(*data,"a=MaxBitRate:integer;",&buf)) { | |
167 desc->max_bit_rate=atoi(buf); | |
168 if (!desc->avg_bit_rate) | |
169 desc->avg_bit_rate=desc->max_bit_rate; | |
170 handled=1; | |
171 *data=nl(*data); | |
172 } | |
173 | |
174 if(filter(*data,"a=MaxPacketSize:integer;",&buf)) { | |
175 desc->max_packet_size=atoi(buf); | |
176 if (!desc->avg_packet_size) | |
177 desc->avg_packet_size=desc->max_packet_size; | |
178 handled=1; | |
179 *data=nl(*data); | |
180 } | |
181 | |
182 if(filter(*data,"a=StartTime:integer;",&buf)) { | |
183 desc->start_time=atoi(buf); | |
184 handled=1; | |
185 *data=nl(*data); | |
186 } | |
187 | |
188 if(filter(*data,"a=Preroll:integer;",&buf)) { | |
189 desc->preroll=atoi(buf); | |
190 handled=1; | |
191 *data=nl(*data); | |
192 } | |
193 | |
194 if(filter(*data,"a=length:npt=",&buf)) { | |
195 desc->duration=(uint32_t)(atof(buf)*1000); | |
196 handled=1; | |
197 *data=nl(*data); | |
198 } | |
199 | |
200 if(filter(*data,"a=StreamName:string;",&buf)) { | |
201 desc->stream_name=strdup(buf); | |
202 desc->stream_name_size=strlen(desc->stream_name); | |
203 handled=1; | |
204 *data=nl(*data); | |
205 } | |
206 | |
207 if(filter(*data,"a=mimetype:string;",&buf)) { | |
208 desc->mime_type=strdup(buf); | |
209 desc->mime_type_size=strlen(desc->mime_type); | |
210 handled=1; | |
211 got_mimetype = 1; | |
212 *data=nl(*data); | |
213 } | |
214 | |
215 if(filter(*data,"a=OpaqueData:buffer;",&buf)) { | |
216 decoded = b64_decode(buf, decoded, &(desc->mlti_data_size)); | |
217 desc->mlti_data=malloc(desc->mlti_data_size); | |
218 memcpy(desc->mlti_data, decoded, desc->mlti_data_size); | |
219 handled=1; | |
220 *data=nl(*data); | |
221 #ifdef LOG | |
222 printf("mlti_data_size: %i\n", desc->mlti_data_size); | |
223 #endif | |
224 } | |
225 | |
226 if(filter(*data,"a=ASMRuleBook:string;",&buf)) { | |
227 desc->asm_rule_book=strdup(buf); | |
228 handled=1; | |
229 *data=nl(*data); | |
230 } | |
231 | |
232 if(!handled) { | |
233 #ifdef LOG | |
234 int len=strchr(*data,'\n')-(*data); | |
235 buf = xbuffer_copyin(buf, 0, *data, len+1); | |
236 buf[len]=0; | |
237 printf("libreal: sdpplin_stream: not handled: '%s'\n", buf); | |
238 #endif | |
239 *data=nl(*data); | |
240 } | |
241 } | |
242 | |
243 if (!got_mimetype) { | |
244 mp_msg(MSGT_OPEN, MSGL_V, "libreal: sdpplin_stream: no mimetype\n"); | |
245 desc->mime_type = strdup("audio/x-pn-realaudio"); | |
246 desc->mime_type_size = strlen(desc->mime_type); | |
247 if (desc->stream_id) | |
248 mp_msg(MSGT_OPEN, MSGL_WARN, "libreal: sdpplin_stream: implicit mimetype for stream_id != 0, weird.\n"); | |
249 } | |
250 | |
251 xbuffer_free(buf); | |
252 xbuffer_free(decoded); | |
253 | |
254 return desc; | |
255 } | |
256 | |
257 sdpplin_t *sdpplin_parse(char *data) { | |
258 | |
259 sdpplin_t *desc=calloc(1,sizeof(sdpplin_t)); | |
260 char *buf=xbuffer_init(32); | |
261 char *decoded=xbuffer_init(32); | |
262 int handled; | |
263 int len; | |
264 | |
265 while (data && *data) { | |
266 #ifdef LOG | |
267 { | |
268 int len=strchr(data,'\n')-(data); | |
269 buf = xbuffer_copyin(buf, 0, data, len+1); | |
270 buf[len]=0; | |
271 printf("libreal: sdpplin: '%s'\n", buf); | |
272 } | |
273 #endif | |
274 | |
275 handled=0; | |
276 | |
277 if (filter(data, "m=", &buf)) { | |
278 sdpplin_stream_t *stream=sdpplin_parse_stream(&data); | |
279 #ifdef LOG | |
280 printf("got data for stream id %u\n", stream->stream_id); | |
281 #endif | |
282 if (desc->stream && (stream->stream_id >= 0) && (stream->stream_id < desc->stream_count)) | |
283 desc->stream[stream->stream_id]=stream; | |
284 else if (desc->stream) | |
285 { | |
286 mp_msg(MSGT_OPEN, MSGL_ERR, "sdpplin: bad stream_id %d (must be >= 0, < %d). Broken sdp?\n", | |
287 stream->stream_id, desc->stream_count); | |
288 free(stream); | |
289 } else { | |
290 mp_msg(MSGT_OPEN, MSGL_V, "sdpplin: got 'm=', but 'a=StreamCount' is still unknown.\n"); | |
291 if (stream->stream_id == 0) { | |
292 desc->stream_count=1; | |
293 desc->stream=malloc(sizeof(sdpplin_stream_t*)); | |
294 desc->stream[0]=stream; | |
295 } else { | |
296 mp_msg(MSGT_OPEN, MSGL_ERR, "sdpplin: got 'm=', but 'a=StreamCount' is still unknown and stream_id != 0. Broken sdp?\n"); | |
297 free(stream); | |
298 } | |
299 } | |
300 continue; | |
301 } | |
302 | |
303 if(filter(data,"a=Title:buffer;",&buf)) { | |
304 decoded=b64_decode(buf, decoded, &len); | |
305 desc->title=strdup(decoded); | |
306 handled=1; | |
307 data=nl(data); | |
308 } | |
309 | |
310 if(filter(data,"a=Author:buffer;",&buf)) { | |
311 decoded=b64_decode(buf, decoded, &len); | |
312 desc->author=strdup(decoded); | |
313 handled=1; | |
314 data=nl(data); | |
315 } | |
316 | |
317 if(filter(data,"a=Copyright:buffer;",&buf)) { | |
318 decoded=b64_decode(buf, decoded, &len); | |
319 desc->copyright=strdup(decoded); | |
320 handled=1; | |
321 data=nl(data); | |
322 } | |
323 | |
324 if(filter(data,"a=Abstract:buffer;",&buf)) { | |
325 decoded=b64_decode(buf, decoded, &len); | |
326 desc->abstract=strdup(decoded); | |
327 handled=1; | |
328 data=nl(data); | |
329 } | |
330 | |
331 if(filter(data,"a=StreamCount:integer;",&buf)) { | |
332 desc->stream_count=(unsigned int)atoi(buf); | |
333 desc->stream=malloc(sizeof(sdpplin_stream_t*)*desc->stream_count); | |
334 handled=1; | |
335 data=nl(data); | |
336 } | |
337 | |
338 if(filter(data,"a=Flags:integer;",&buf)) { | |
339 desc->flags=atoi(buf); | |
340 handled=1; | |
341 data=nl(data); | |
342 } | |
343 | |
344 if(!handled) { | |
345 #ifdef LOG | |
346 int len=strchr(data,'\n')-data; | |
347 buf = xbuffer_copyin(buf, 0, data, len+1); | |
348 buf[len]=0; | |
349 printf("libreal: sdpplin: not handled: '%s'\n", buf); | |
350 #endif | |
351 data=nl(data); | |
352 } | |
353 } | |
354 | |
355 xbuffer_free(buf); | |
356 xbuffer_free(decoded); | |
357 | |
358 return desc; | |
359 } | |
360 | |
361 void sdpplin_free(sdpplin_t *description) { | |
362 | |
363 /* TODO: free strings */ | |
364 free(description); | |
365 } | |
366 |