Mercurial > mplayer.hg
comparison stream/librtsp/rtsp.c @ 29263:0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
author | diego |
---|---|
date | Wed, 13 May 2009 02:58:57 +0000 |
parents | c884d17bd005 |
children | b01f807eb183 |
comparison
equal
deleted
inserted
replaced
29262:7d545a6b8aff | 29263:0f1b5b68af32 |
---|---|
57 */ | 57 */ |
58 | 58 |
59 /* | 59 /* |
60 * network utilities | 60 * network utilities |
61 */ | 61 */ |
62 | 62 |
63 static int write_stream(int s, const char *buf, int len) { | 63 static int write_stream(int s, const char *buf, int len) { |
64 int total, timeout; | 64 int total, timeout; |
65 | 65 |
66 total = 0; timeout = 30; | 66 total = 0; timeout = 30; |
67 while (total < len){ | 67 while (total < len){ |
68 int n; | 68 int n; |
69 | 69 |
70 n = send (s, &buf[total], len - total, 0); | 70 n = send (s, &buf[total], len - total, 0); |
71 | 71 |
72 if (n > 0) | 72 if (n > 0) |
85 | 85 |
86 return total; | 86 return total; |
87 } | 87 } |
88 | 88 |
89 static ssize_t read_stream(int fd, void *buf, size_t count) { | 89 static ssize_t read_stream(int fd, void *buf, size_t count) { |
90 | 90 |
91 ssize_t ret, total; | 91 ssize_t ret, total; |
92 | 92 |
93 total = 0; | 93 total = 0; |
94 | 94 |
95 while (total < count) { | 95 while (total < count) { |
96 | 96 |
97 ret=recv (fd, ((uint8_t*)buf)+total, count-total, 0); | 97 ret=recv (fd, ((uint8_t*)buf)+total, count-total, 0); |
98 | 98 |
99 if (ret<0) { | 99 if (ret<0) { |
100 if(errno == EAGAIN) { | 100 if(errno == EAGAIN) { |
101 fd_set rset; | 101 fd_set rset; |
102 struct timeval timeout; | 102 struct timeval timeout; |
103 | 103 |
104 FD_ZERO (&rset); | 104 FD_ZERO (&rset); |
105 FD_SET (fd, &rset); | 105 FD_SET (fd, &rset); |
106 | 106 |
107 timeout.tv_sec = 30; | 107 timeout.tv_sec = 30; |
108 timeout.tv_usec = 0; | 108 timeout.tv_usec = 0; |
109 | 109 |
110 if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) { | 110 if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) { |
111 return -1; | 111 return -1; |
112 } | 112 } |
113 continue; | 113 continue; |
114 } | 114 } |
115 | 115 |
116 mp_msg(MSGT_OPEN, MSGL_ERR, "rtsp: read error.\n"); | 116 mp_msg(MSGT_OPEN, MSGL_ERR, "rtsp: read error.\n"); |
117 return ret; | 117 return ret; |
118 } else | 118 } else |
119 total += ret; | 119 total += ret; |
120 | 120 |
121 /* end of stream */ | 121 /* end of stream */ |
122 if (!ret) break; | 122 if (!ret) break; |
123 } | 123 } |
124 | 124 |
125 return total; | 125 return total; |
127 | 127 |
128 /* | 128 /* |
129 * rtsp_get gets a line from stream | 129 * rtsp_get gets a line from stream |
130 * and returns a null terminated string. | 130 * and returns a null terminated string. |
131 */ | 131 */ |
132 | 132 |
133 static char *rtsp_get(rtsp_t *s) { | 133 static char *rtsp_get(rtsp_t *s) { |
134 | 134 |
135 int n=1; | 135 int n=1; |
136 char *buffer = malloc(BUF_SIZE); | 136 char *buffer = malloc(BUF_SIZE); |
137 char *string = NULL; | 137 char *string = NULL; |
152 string[n-1]=0; | 152 string[n-1]=0; |
153 | 153 |
154 #ifdef LOG | 154 #ifdef LOG |
155 mp_msg(MSGT_OPEN, MSGL_INFO, "librtsp: << '%s'\n", string); | 155 mp_msg(MSGT_OPEN, MSGL_INFO, "librtsp: << '%s'\n", string); |
156 #endif | 156 #endif |
157 | 157 |
158 | 158 |
159 free(buffer); | 159 free(buffer); |
160 return string; | 160 return string; |
161 } | 161 } |
162 | 162 |
163 /* | 163 /* |
164 * rtsp_put puts a line on stream | 164 * rtsp_put puts a line on stream |
165 */ | 165 */ |
166 | 166 |
167 static void rtsp_put(rtsp_t *s, const char *string) { | 167 static void rtsp_put(rtsp_t *s, const char *string) { |
168 | 168 |
169 int len=strlen(string); | 169 int len=strlen(string); |
170 char *buf=malloc(len+2); | 170 char *buf=malloc(len+2); |
171 | 171 |
176 memcpy(buf,string,len); | 176 memcpy(buf,string,len); |
177 buf[len]=0x0d; | 177 buf[len]=0x0d; |
178 buf[len+1]=0x0a; | 178 buf[len+1]=0x0a; |
179 | 179 |
180 write_stream(s->s, buf, len+2); | 180 write_stream(s->s, buf, len+2); |
181 | 181 |
182 #ifdef LOG | 182 #ifdef LOG |
183 mp_msg(MSGT_OPEN, MSGL_INFO, " done.\n"); | 183 mp_msg(MSGT_OPEN, MSGL_INFO, " done.\n"); |
184 #endif | 184 #endif |
185 | 185 |
186 free(buf); | 186 free(buf); |
192 | 192 |
193 static int rtsp_get_code(const char *string) { | 193 static int rtsp_get_code(const char *string) { |
194 | 194 |
195 char buf[4]; | 195 char buf[4]; |
196 int code=0; | 196 int code=0; |
197 | 197 |
198 if (!strncmp(string, RTSP_PROTOCOL_VERSION, strlen(RTSP_PROTOCOL_VERSION))) | 198 if (!strncmp(string, RTSP_PROTOCOL_VERSION, strlen(RTSP_PROTOCOL_VERSION))) |
199 { | 199 { |
200 memcpy(buf, string+strlen(RTSP_PROTOCOL_VERSION)+1, 3); | 200 memcpy(buf, string+strlen(RTSP_PROTOCOL_VERSION)+1, 3); |
201 buf[3]=0; | 201 buf[3]=0; |
202 code=atoi(buf); | 202 code=atoi(buf); |
216 | 216 |
217 static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) { | 217 static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) { |
218 | 218 |
219 char **payload=s->scheduled; | 219 char **payload=s->scheduled; |
220 char *buf; | 220 char *buf; |
221 | 221 |
222 buf = malloc(strlen(type)+strlen(what)+strlen(RTSP_PROTOCOL_VERSION)+3); | 222 buf = malloc(strlen(type)+strlen(what)+strlen(RTSP_PROTOCOL_VERSION)+3); |
223 | 223 |
224 sprintf(buf,"%s %s %s",type, what, RTSP_PROTOCOL_VERSION); | 224 sprintf(buf,"%s %s %s",type, what, RTSP_PROTOCOL_VERSION); |
225 rtsp_put(s,buf); | 225 rtsp_put(s,buf); |
226 free(buf); | 226 free(buf); |
227 if (payload) | 227 if (payload) |
228 while (*payload) { | 228 while (*payload) { |
238 */ | 238 */ |
239 | 239 |
240 static void rtsp_schedule_standard(rtsp_t *s) { | 240 static void rtsp_schedule_standard(rtsp_t *s) { |
241 | 241 |
242 char tmp[17]; | 242 char tmp[17]; |
243 | 243 |
244 snprintf(tmp, 17, "CSeq: %u", s->cseq); | 244 snprintf(tmp, 17, "CSeq: %u", s->cseq); |
245 rtsp_schedule_field(s, tmp); | 245 rtsp_schedule_field(s, tmp); |
246 | 246 |
247 if (s->session) { | 247 if (s->session) { |
248 char *buf; | 248 char *buf; |
249 buf = malloc(strlen(s->session)+15); | 249 buf = malloc(strlen(s->session)+15); |
250 sprintf(buf, "Session: %s", s->session); | 250 sprintf(buf, "Session: %s", s->session); |
251 rtsp_schedule_field(s, buf); | 251 rtsp_schedule_field(s, buf); |
253 } | 253 } |
254 } | 254 } |
255 /* | 255 /* |
256 * get the answers, if server responses with something != 200, return NULL | 256 * get the answers, if server responses with something != 200, return NULL |
257 */ | 257 */ |
258 | 258 |
259 static int rtsp_get_answers(rtsp_t *s) { | 259 static int rtsp_get_answers(rtsp_t *s) { |
260 | 260 |
261 char *answer=NULL; | 261 char *answer=NULL; |
262 unsigned int answer_seq; | 262 unsigned int answer_seq; |
263 char **answer_ptr=s->answers; | 263 char **answer_ptr=s->answers; |
264 int code; | 264 int code; |
265 int ans_count = 0; | 265 int ans_count = 0; |
266 | 266 |
267 answer=rtsp_get(s); | 267 answer=rtsp_get(s); |
268 if (!answer) | 268 if (!answer) |
269 return 0; | 269 return 0; |
270 code=rtsp_get_code(answer); | 270 code=rtsp_get_code(answer); |
271 free(answer); | 271 free(answer); |
272 | 272 |
273 rtsp_free_answers(s); | 273 rtsp_free_answers(s); |
274 | 274 |
275 do { /* while we get answer lines */ | 275 do { /* while we get answer lines */ |
276 | 276 |
277 answer=rtsp_get(s); | 277 answer=rtsp_get(s); |
278 if (!answer) | 278 if (!answer) |
279 return 0; | 279 return 0; |
280 | 280 |
281 if (!strncasecmp(answer,"CSeq:",5)) { | 281 if (!strncasecmp(answer,"CSeq:",5)) { |
282 sscanf(answer,"%*s %u",&answer_seq); | 282 sscanf(answer,"%*s %u",&answer_seq); |
283 if (s->cseq != answer_seq) { | 283 if (s->cseq != answer_seq) { |
284 #ifdef LOG | 284 #ifdef LOG |
285 mp_msg(MSGT_OPEN, MSGL_WARN, "librtsp: warning: CSeq mismatch. got %u, assumed %u", answer_seq, s->cseq); | 285 mp_msg(MSGT_OPEN, MSGL_WARN, "librtsp: warning: CSeq mismatch. got %u, assumed %u", answer_seq, s->cseq); |
313 free(buf); | 313 free(buf); |
314 } | 314 } |
315 *answer_ptr=answer; | 315 *answer_ptr=answer; |
316 answer_ptr++; | 316 answer_ptr++; |
317 } while ((strlen(answer)!=0) && (++ans_count < MAX_FIELDS)); | 317 } while ((strlen(answer)!=0) && (++ans_count < MAX_FIELDS)); |
318 | 318 |
319 s->cseq++; | 319 s->cseq++; |
320 | 320 |
321 *answer_ptr=NULL; | 321 *answer_ptr=NULL; |
322 rtsp_schedule_standard(s); | 322 rtsp_schedule_standard(s); |
323 | 323 |
324 return code; | 324 return code; |
325 } | 325 } |
326 | 326 |
327 /* | 327 /* |
328 * send an ok message | 328 * send an ok message |
329 */ | 329 */ |
330 | 330 |
331 int rtsp_send_ok(rtsp_t *s) { | 331 int rtsp_send_ok(rtsp_t *s) { |
332 char cseq[16]; | 332 char cseq[16]; |
333 | 333 |
334 rtsp_put(s, "RTSP/1.0 200 OK"); | 334 rtsp_put(s, "RTSP/1.0 200 OK"); |
335 sprintf(cseq,"CSeq: %u", s->cseq); | 335 sprintf(cseq,"CSeq: %u", s->cseq); |
336 rtsp_put(s, cseq); | 336 rtsp_put(s, cseq); |
337 rtsp_put(s, ""); | 337 rtsp_put(s, ""); |
338 return 0; | 338 return 0; |
371 buf=malloc(strlen(s->host)+strlen(s->path)+16); | 371 buf=malloc(strlen(s->host)+strlen(s->path)+16); |
372 sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); | 372 sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); |
373 } | 373 } |
374 rtsp_send_request(s,RTSP_METHOD_DESCRIBE,buf); | 374 rtsp_send_request(s,RTSP_METHOD_DESCRIBE,buf); |
375 free(buf); | 375 free(buf); |
376 | 376 |
377 return rtsp_get_answers(s); | 377 return rtsp_get_answers(s); |
378 } | 378 } |
379 | 379 |
380 int rtsp_request_setup(rtsp_t *s, const char *what, char *control) { | 380 int rtsp_request_setup(rtsp_t *s, const char *what, char *control) { |
381 | 381 |
386 else | 386 else |
387 { | 387 { |
388 int len = strlen (s->host) + strlen (s->path) + 16; | 388 int len = strlen (s->host) + strlen (s->path) + 16; |
389 if (control) | 389 if (control) |
390 len += strlen (control) + 1; | 390 len += strlen (control) + 1; |
391 | 391 |
392 buf = malloc (len); | 392 buf = malloc (len); |
393 sprintf (buf, "rtsp://%s:%i/%s%s%s", s->host, s->port, s->path, | 393 sprintf (buf, "rtsp://%s:%i/%s%s%s", s->host, s->port, s->path, |
394 control ? "/" : "", control ? control : ""); | 394 control ? "/" : "", control ? control : ""); |
395 } | 395 } |
396 | 396 |
397 rtsp_send_request (s, RTSP_METHOD_SETUP, buf); | 397 rtsp_send_request (s, RTSP_METHOD_SETUP, buf); |
398 free (buf); | 398 free (buf); |
399 return rtsp_get_answers (s); | 399 return rtsp_get_answers (s); |
400 } | 400 } |
401 | 401 |
410 buf=malloc(strlen(s->host)+strlen(s->path)+16); | 410 buf=malloc(strlen(s->host)+strlen(s->path)+16); |
411 sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); | 411 sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); |
412 } | 412 } |
413 rtsp_send_request(s,RTSP_METHOD_SET_PARAMETER,buf); | 413 rtsp_send_request(s,RTSP_METHOD_SET_PARAMETER,buf); |
414 free(buf); | 414 free(buf); |
415 | 415 |
416 return rtsp_get_answers(s); | 416 return rtsp_get_answers(s); |
417 } | 417 } |
418 | 418 |
419 int rtsp_request_play(rtsp_t *s, const char *what) { | 419 int rtsp_request_play(rtsp_t *s, const char *what) { |
420 | 420 |
421 char *buf; | 421 char *buf; |
422 int ret; | 422 int ret; |
423 | 423 |
424 if (what) { | 424 if (what) { |
425 buf=strdup(what); | 425 buf=strdup(what); |
426 } else | 426 } else |
427 { | 427 { |
428 buf=malloc(strlen(s->host)+strlen(s->path)+16); | 428 buf=malloc(strlen(s->host)+strlen(s->path)+16); |
429 sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); | 429 sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); |
430 } | 430 } |
431 rtsp_send_request(s,RTSP_METHOD_PLAY,buf); | 431 rtsp_send_request(s,RTSP_METHOD_PLAY,buf); |
432 free(buf); | 432 free(buf); |
433 | 433 |
434 ret = rtsp_get_answers (s); | 434 ret = rtsp_get_answers (s); |
435 if (ret == RTSP_STATUS_OK) | 435 if (ret == RTSP_STATUS_OK) |
436 s->server_state = RTSP_PLAYING; | 436 s->server_state = RTSP_PLAYING; |
437 | 437 |
438 return ret; | 438 return ret; |
439 } | 439 } |
440 | 440 |
441 int rtsp_request_teardown(rtsp_t *s, const char *what) { | 441 int rtsp_request_teardown(rtsp_t *s, const char *what) { |
442 | 442 |
443 char *buf; | 443 char *buf; |
444 | 444 |
445 if (what) | 445 if (what) |
446 buf = strdup (what); | 446 buf = strdup (what); |
447 else | 447 else |
448 { | 448 { |
449 buf = | 449 buf = |
472 if (((buffer[0]=='S')&&(buffer[1]=='E')&&(buffer[2]=='T')&&(buffer[3]=='_')) || | 472 if (((buffer[0]=='S')&&(buffer[1]=='E')&&(buffer[2]=='T')&&(buffer[3]=='_')) || |
473 ((buffer[0]=='O')&&(buffer[1]=='P')&&(buffer[2]=='T')&&(buffer[3]=='I'))) // OPTIONS | 473 ((buffer[0]=='O')&&(buffer[1]=='P')&&(buffer[2]=='T')&&(buffer[3]=='I'))) // OPTIONS |
474 { | 474 { |
475 char *rest=rtsp_get(s); | 475 char *rest=rtsp_get(s); |
476 if (!rest) | 476 if (!rest) |
477 return -1; | 477 return -1; |
478 | 478 |
479 seq=-1; | 479 seq=-1; |
480 do { | 480 do { |
481 free(rest); | 481 free(rest); |
482 rest=rtsp_get(s); | 482 rest=rtsp_get(s); |
538 | 538 |
539 s->s = fd; | 539 s->s = fd; |
540 s->server=NULL; | 540 s->server=NULL; |
541 s->server_state=0; | 541 s->server_state=0; |
542 s->server_caps=0; | 542 s->server_caps=0; |
543 | 543 |
544 s->cseq=0; | 544 s->cseq=0; |
545 s->session=NULL; | 545 s->session=NULL; |
546 | 546 |
547 if (user_agent) | 547 if (user_agent) |
548 s->user_agent=strdup(user_agent); | 548 s->user_agent=strdup(user_agent); |
549 else | 549 else |
550 s->user_agent=strdup("User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)"); | 550 s->user_agent=strdup("User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)"); |
551 | 551 |
585 | 585 |
586 char *rtsp_search_answers(rtsp_t *s, const char *tag) { | 586 char *rtsp_search_answers(rtsp_t *s, const char *tag) { |
587 | 587 |
588 char **answer; | 588 char **answer; |
589 char *ptr; | 589 char *ptr; |
590 | 590 |
591 if (!s->answers) return NULL; | 591 if (!s->answers) return NULL; |
592 answer=s->answers; | 592 answer=s->answers; |
593 | 593 |
594 while (*answer) { | 594 while (*answer) { |
595 if (!strncasecmp(*answer,tag,strlen(tag))) { | 595 if (!strncasecmp(*answer,tag,strlen(tag))) { |
650 } | 650 } |
651 param = nparam ? nparam + 1 : NULL; | 651 param = nparam ? nparam + 1 : NULL; |
652 } | 652 } |
653 return NULL; | 653 return NULL; |
654 } | 654 } |
655 | 655 |
656 /* | 656 /* |
657 * schedules a field for transmission | 657 * schedules a field for transmission |
658 */ | 658 */ |
659 | 659 |
660 void rtsp_schedule_field(rtsp_t *s, const char *string) { | 660 void rtsp_schedule_field(rtsp_t *s, const char *string) { |
661 | 661 |
662 int i=0; | 662 int i=0; |
663 | 663 |
664 if (!string) return; | 664 if (!string) return; |
665 | 665 |
666 while(s->scheduled[i]) { | 666 while(s->scheduled[i]) { |
667 i++; | 667 i++; |
668 } | 668 } |
669 s->scheduled[i]=strdup(string); | 669 s->scheduled[i]=strdup(string); |
670 } | 670 } |
671 | 671 |
672 /* | 672 /* |
673 * removes the first scheduled field which prefix matches string. | 673 * removes the first scheduled field which prefix matches string. |
674 */ | 674 */ |
675 | 675 |
676 void rtsp_unschedule_field(rtsp_t *s, const char *string) { | 676 void rtsp_unschedule_field(rtsp_t *s, const char *string) { |
677 | 677 |
678 char **ptr=s->scheduled; | 678 char **ptr=s->scheduled; |
679 | 679 |
680 if (!string) return; | 680 if (!string) return; |
681 | 681 |
682 while(*ptr) { | 682 while(*ptr) { |
683 if (!strncmp(*ptr, string, strlen(string))) | 683 if (!strncmp(*ptr, string, strlen(string))) |
684 break; | 684 break; |
697 */ | 697 */ |
698 | 698 |
699 void rtsp_unschedule_all(rtsp_t *s) { | 699 void rtsp_unschedule_all(rtsp_t *s) { |
700 | 700 |
701 char **ptr; | 701 char **ptr; |
702 | 702 |
703 if (!s->scheduled) return; | 703 if (!s->scheduled) return; |
704 ptr=s->scheduled; | 704 ptr=s->scheduled; |
705 | 705 |
706 while (*ptr) { | 706 while (*ptr) { |
707 free(*ptr); | 707 free(*ptr); |
714 */ | 714 */ |
715 | 715 |
716 void rtsp_free_answers(rtsp_t *s) { | 716 void rtsp_free_answers(rtsp_t *s) { |
717 | 717 |
718 char **answer; | 718 char **answer; |
719 | 719 |
720 if (!s->answers) return; | 720 if (!s->answers) return; |
721 answer=s->answers; | 721 answer=s->answers; |
722 | 722 |
723 while (*answer) { | 723 while (*answer) { |
724 free(*answer); | 724 free(*answer); |