Mercurial > mplayer.hg
comparison libmpdemux/network.c @ 3686:bed6226ffb46
RTP support patch by Brian Kuschak <bkuschak@yahoo.com>
author | arpi |
---|---|
date | Sun, 23 Dec 2001 22:09:02 +0000 |
parents | 6bd312199a75 |
children | 837ed2f1ed5e |
comparison
equal
deleted
inserted
replaced
3685:3062f68d3fa2 | 3686:bed6226ffb46 |
---|---|
21 | 21 |
22 #include "network.h" | 22 #include "network.h" |
23 #include "http.h" | 23 #include "http.h" |
24 #include "url.h" | 24 #include "url.h" |
25 #include "asf.h" | 25 #include "asf.h" |
26 #include "rtp.h" | |
26 | 27 |
27 static struct { | 28 static struct { |
28 char *mime_type; | 29 char *mime_type; |
29 int demuxer_type; | 30 int demuxer_type; |
30 } mime_type_table[] = { | 31 } mime_type_table[] = { |
79 streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl ) { | 80 streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl ) { |
80 if( streaming_ctrl==NULL ) return; | 81 if( streaming_ctrl==NULL ) return; |
81 free( streaming_ctrl ); | 82 free( streaming_ctrl ); |
82 } | 83 } |
83 | 84 |
85 int | |
86 read_rtp_from_server(int fd, char *buffer, int length) { | |
87 int ret; | |
88 int done=0; | |
89 fd_set set; | |
90 struct timeval tv; | |
91 struct rtpheader rh; | |
92 char *data; | |
93 int len; | |
94 static int got_first = 0; | |
95 static int sequence; | |
96 | |
97 if( buffer==NULL || length<0 ) return -1; | |
98 | |
99 getrtp2(fd, &rh, &data, &len); | |
100 if( got_first && rh.b.sequence != sequence+1 ) | |
101 printf("RTP packet sequence error! Expected: %d, received: %d\n", | |
102 sequence+1, rh.b.sequence); | |
103 got_first = 1; | |
104 sequence = rh.b.sequence; | |
105 memcpy(buffer, data, len); | |
106 return(len); | |
107 } | |
108 | |
84 // Connect to a server using a TCP connection | 109 // Connect to a server using a TCP connection |
85 int | 110 int |
86 connect2Server(char *host, int port) { | 111 connect2Server(char *host, int port) { |
87 int socket_server_fd; | 112 int socket_server_fd; |
88 int err, err_len; | 113 int err, err_len; |
249 } | 274 } |
250 | 275 |
251 // Checking for RTSP | 276 // Checking for RTSP |
252 if( !strcasecmp(url->protocol, "rtsp") ) { | 277 if( !strcasecmp(url->protocol, "rtsp") ) { |
253 printf("RTSP protocol not yet implemented!\n"); | 278 printf("RTSP protocol not yet implemented!\n"); |
279 return DEMUXER_TYPE_UNKNOWN; | |
280 } | |
281 | |
282 // Checking for RTP | |
283 if( !strcasecmp(url->protocol, "rtp") ) { | |
284 if( url->port==0 ) | |
285 { | |
286 printf("You must enter a port number for RTP streams!\n"); | |
287 exit(1); //fixme | |
288 } | |
289 *fd_out=-1; | |
254 return DEMUXER_TYPE_UNKNOWN; | 290 return DEMUXER_TYPE_UNKNOWN; |
255 } | 291 } |
256 | 292 |
257 // Checking for ASF | 293 // Checking for ASF |
258 if( !strncasecmp(url->protocol, "mms", 3) ) { | 294 if( !strncasecmp(url->protocol, "mms", 3) ) { |
427 // stream->streaming_ctrl->buffering = 0; | 463 // stream->streaming_ctrl->buffering = 0; |
428 stream->streaming_ctrl->status = streaming_playing_e; | 464 stream->streaming_ctrl->status = streaming_playing_e; |
429 return fd; | 465 return fd; |
430 } | 466 } |
431 | 467 |
468 // Start listening on a UDP port. If multicast, join the group. | |
469 int | |
470 rtp_open_socket( URL_t *url ) { | |
471 int fd; | |
472 int socket_server_fd; | |
473 int err, err_len; | |
474 fd_set set; | |
475 struct timeval tv; | |
476 struct sockaddr_in server_address; | |
477 struct ip_mreq mcast; | |
478 | |
479 printf("Listening for traffic on %s:%d ...\n", url->hostname, url->port ); | |
480 | |
481 socket_server_fd = socket(AF_INET, SOCK_DGRAM, 0); | |
482 // fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK ); | |
483 if( socket_server_fd==-1 ) { | |
484 perror("Failed to create socket"); | |
485 return -1; | |
486 } | |
487 | |
488 if( isalpha(url->hostname[0]) ) { | |
489 struct hostent *hp =(struct hostent*)gethostbyname( url->hostname ); | |
490 if( hp==NULL ) { | |
491 printf("Counldn't resolve name: %s\n", url->hostname); | |
492 return -1; | |
493 } | |
494 memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length ); | |
495 } else { | |
496 inet_pton(AF_INET, url->hostname, &server_address.sin_addr); | |
497 } | |
498 server_address.sin_family=AF_INET; | |
499 server_address.sin_port=htons(url->port); | |
500 | |
501 if( bind( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) { | |
502 if( errno!=EINPROGRESS ) { | |
503 perror("Failed to connect to server"); | |
504 close(socket_server_fd); | |
505 return -1; | |
506 } | |
507 } | |
508 if((ntohl(server_address.sin_addr.s_addr) >> 28) == 0xe) { | |
509 mcast.imr_multiaddr.s_addr = server_address.sin_addr.s_addr; | |
510 //mcast.imr_interface.s_addr = inet_addr("10.1.1.2"); | |
511 mcast.imr_interface.s_addr = 0; | |
512 if( setsockopt( socket_server_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))) { | |
513 perror("IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)"); | |
514 return -1; | |
515 } | |
516 } | |
517 | |
518 //tv.tv_sec = 0; | |
519 //tv.tv_usec = (10 * 1000000); // 10 seconds timeout | |
520 FD_ZERO( &set ); | |
521 FD_SET( socket_server_fd, &set ); | |
522 //if( select(socket_server_fd+1, &set, NULL, NULL, &tv)>0 ) { | |
523 if( select(socket_server_fd+1, &set, NULL, NULL, NULL)>0 ) { | |
524 err_len = sizeof( err ); | |
525 getsockopt( socket_server_fd, SOL_SOCKET, SO_ERROR, &err, &err_len ); | |
526 if( err ) { | |
527 printf("Timeout! No data from host %s\n", url->hostname ); | |
528 printf("Socket error: %d\n", err ); | |
529 close(socket_server_fd); | |
530 return -1; | |
531 } | |
532 } | |
533 return socket_server_fd; | |
534 } | |
535 | |
536 int | |
537 rtp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl ) { | |
538 return read_rtp_from_server( fd, buffer, size ); | |
539 } | |
540 | |
541 int | |
542 rtp_streaming_start( stream_t *stream ) { | |
543 streaming_ctrl_t *streaming_ctrl; | |
544 int fd; | |
545 | |
546 if( streaming_ctrl==NULL ) return -1; | |
547 streaming_ctrl = stream->streaming_ctrl; | |
548 fd = stream->fd; | |
549 | |
550 if( fd<0 ) { | |
551 fd = rtp_open_socket( (streaming_ctrl->url) ); | |
552 if( fd<0 ) return -1; | |
553 } | |
554 | |
555 streaming_ctrl->streaming_read = rtp_streaming_read; | |
556 streaming_ctrl->prebuffer_size = 180000; | |
557 streaming_ctrl->buffering = 0; //1; | |
558 streaming_ctrl->status = streaming_playing_e; | |
559 return fd; | |
560 } | |
561 | |
432 int | 562 int |
433 streaming_start(stream_t *stream, URL_t *url, int demuxer_type) { | 563 streaming_start(stream_t *stream, URL_t *url, int demuxer_type) { |
434 int ret=-1; | 564 int ret=-1; |
435 if( stream==NULL ) return -1; | 565 if( stream==NULL ) return -1; |
436 | 566 |
441 | 571 |
442 stream->streaming_ctrl->url = url_copy(url); | 572 stream->streaming_ctrl->url = url_copy(url); |
443 // stream->streaming_ctrl->demuxer_type = demuxer_type; | 573 // stream->streaming_ctrl->demuxer_type = demuxer_type; |
444 stream->fd = -1; | 574 stream->fd = -1; |
445 | 575 |
576 // For RTP streams, we usually don't know the stream type until we open it. | |
577 if( !strcmp( url->protocol, "rtp")) | |
578 { | |
579 stream->fd = rtp_streaming_start( stream ); | |
580 } | |
581 // For connection-oriented streams, we can usually determine the streaming type. | |
582 else | |
446 switch( demuxer_type ) { | 583 switch( demuxer_type ) { |
447 case DEMUXER_TYPE_ASF: | 584 case DEMUXER_TYPE_ASF: |
448 // Send the appropriate HTTP request | 585 // Send the appropriate HTTP request |
449 // Need to filter the network stream. | 586 // Need to filter the network stream. |
450 // ASF raw stream is encapsulated. | 587 // ASF raw stream is encapsulated. |