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.