# HG changeset patch # User bertrand # Date 1010475089 0 # Node ID f732854e3d1692c8b5fb273b35895367110e3ca7 # Parent 898caa690c0b9033dc49720437561d26727e6ebb Kept the HTTP connection open after autodetect, so we don't need to reopen and request a second time. diff -r 898caa690c0b -r f732854e3d16 libmpdemux/asf_streaming.c --- a/libmpdemux/asf_streaming.c Tue Jan 08 02:01:04 2002 +0000 +++ b/libmpdemux/asf_streaming.c Tue Jan 08 07:31:29 2002 +0000 @@ -72,6 +72,53 @@ return -1; } +int +asf_streaming(ASF_stream_chunck_t *stream_chunck, int *drop_packet ) { +/* +printf("ASF stream chunck size=%d\n", stream_chunck->size); +printf("length: %d\n", length ); +printf("0x%02X\n", stream_chunck->type ); +*/ + if( drop_packet!=NULL ) *drop_packet = 0; + + if( stream_chunck->size<8 ) { + printf("Ahhhh, stream_chunck size is too small: %d\n", stream_chunck->size); + return -1; + } + if( stream_chunck->size!=stream_chunck->size_confirm ) { + printf("size_confirm mismatch!: %d %d\n", stream_chunck->size, stream_chunck->size_confirm); + return -1; + } +/* + printf(" type: 0x%02X\n", stream_chunck->type ); + printf(" size: %d (0x%02X)\n", stream_chunck->size, stream_chunck->size ); + printf(" sequence_number: 0x%04X\n", stream_chunck->sequence_number ); + printf(" unknown: 0x%02X\n", stream_chunck->unknown ); + printf(" size_confirm: 0x%02X\n", stream_chunck->size_confirm ); +*/ + switch(stream_chunck->type) { + case 0x4324: // $C Clear ASF configuration + printf("=====> Clearing ASF stream configuration!\n"); + if( drop_packet!=NULL ) *drop_packet = 1; + return stream_chunck->size; + break; + case 0x4424: // $D Data follows +// printf("=====> Data follows\n"); + break; + case 0x4524: // $E Transfer complete + printf("=====> Transfer complete\n"); + if( drop_packet!=NULL ) *drop_packet = 1; + return stream_chunck->size; + break; + case 0x4824: // $H ASF header chunk follows + printf("=====> ASF header chunk follows\n"); + break; + default: + printf("=====> Unknown stream type 0x%x\n", stream_chunck->type ); + } + return stream_chunck->size+4; +} + static int asf_streaming_parse_header(int fd, streaming_ctrl_t* streaming_ctrl) { ASF_header_t asfh; @@ -283,53 +330,6 @@ return read; } -int -asf_streaming(ASF_stream_chunck_t *stream_chunck, int *drop_packet ) { -/* -printf("ASF stream chunck size=%d\n", stream_chunck->size); -printf("length: %d\n", length ); -printf("0x%02X\n", stream_chunck->type ); -*/ - if( drop_packet!=NULL ) *drop_packet = 0; - - if( stream_chunck->size<8 ) { - printf("Ahhhh, stream_chunck size is too small: %d\n", stream_chunck->size); - return -1; - } - if( stream_chunck->size!=stream_chunck->size_confirm ) { - printf("size_confirm mismatch!: %d %d\n", stream_chunck->size, stream_chunck->size_confirm); - return -1; - } -/* - printf(" type: 0x%02X\n", stream_chunck->type ); - printf(" size: %d (0x%02X)\n", stream_chunck->size, stream_chunck->size ); - printf(" sequence_number: 0x%04X\n", stream_chunck->sequence_number ); - printf(" unknown: 0x%02X\n", stream_chunck->unknown ); - printf(" size_confirm: 0x%02X\n", stream_chunck->size_confirm ); -*/ - switch(stream_chunck->type) { - case 0x4324: // $C Clear ASF configuration - printf("=====> Clearing ASF stream configuration!\n"); - if( drop_packet!=NULL ) *drop_packet = 1; - return stream_chunck->size; - break; - case 0x4424: // $D Data follows -// printf("=====> Data follows\n"); - break; - case 0x4524: // $E Transfer complete - printf("=====> Transfer complete\n"); - if( drop_packet!=NULL ) *drop_packet = 1; - return stream_chunck->size; - break; - case 0x4824: // $H ASF header chunk follows - printf("=====> ASF header chunk follows\n"); - break; - default: - printf("=====> Unknown stream type 0x%x\n", stream_chunck->type ); - } - return stream_chunck->size+4; -} - int asf_http_streaming_seek( int fd, off_t pos, streaming_ctrl_t *streaming_ctrl ) { return -1; @@ -377,7 +377,6 @@ asf_http_streaming_ctrl_t *asf_http_ctrl = (asf_http_streaming_ctrl_t*)streaming_ctrl->data; char str[250]; char *ptr; - char *request; int i,as = -1,vs = -1; int offset_hi=0, offset_lo=0, length=0; @@ -528,7 +527,6 @@ asf_http_streaming_ctrl_t *asf_http_ctrl; ASF_StreamType_e streaming_type; char buffer[BUFFER_SIZE]; - unsigned int port; int i, ret; int fd = stream->fd; int done; diff -r 898caa690c0b -r f732854e3d16 libmpdemux/network.c --- a/libmpdemux/network.c Tue Jan 08 02:01:04 2002 +0000 +++ b/libmpdemux/network.c Tue Jan 08 07:31:29 2002 +0000 @@ -84,10 +84,6 @@ int read_rtp_from_server(int fd, char *buffer, int length) { - int ret; - int done=0; - fd_set set; - struct timeval tv; struct rtpheader rh; char *data; int len; @@ -233,7 +229,7 @@ // By using the protocol, the extension of the file or the content-type // we might be able to guess the streaming type. int -autodetectProtocol(URL_t *url, int *fd_out) { +autodetectProtocol(streaming_ctrl_t *streaming_ctrl, int *fd_out, int *file_format) { HTTP_header_t *http_hdr; int fd=-1; int i; @@ -243,14 +239,19 @@ char *next_url; char response[1024]; + URL_t *url = streaming_ctrl->url; + *file_format = DEMUXER_TYPE_UNKNOWN; + do { - *fd_out=-1; + *fd_out = -1; next_url = NULL; extension = NULL; content_type = NULL; redirect = 0; - if( url==NULL ) return DEMUXER_TYPE_UNKNOWN; + if( url==NULL ) { + return -1; + } // Get the extension of the file if present if( url->file!=NULL ) { @@ -267,8 +268,8 @@ // Look for the extension in the extensions table for( i=0 ; i<(sizeof(extensions_table)/sizeof(extensions_table[0])) ; i++ ) { if( !strcasecmp(extension, extensions_table[i].extension) ) { - //if( url->port==0 ) url->port = 80; - return extensions_table[i].demuxer_type; + *file_format = extensions_table[i].demuxer_type; + return 0; } } } @@ -276,24 +277,22 @@ // Checking for RTSP if( !strcasecmp(url->protocol, "rtsp") ) { printf("RTSP protocol not yet implemented!\n"); - return DEMUXER_TYPE_UNKNOWN; + return -1; } // Checking for RTP if( !strcasecmp(url->protocol, "rtp") ) { - if( url->port==0 ) - { + if( url->port==0 ) { printf("You must enter a port number for RTP streams!\n"); - exit(1); //fixme + return -1; } - *fd_out=-1; - return DEMUXER_TYPE_UNKNOWN; + return -1; } // Checking for ASF if( !strncasecmp(url->protocol, "mms", 3) ) { - //if( url->port==0 ) url->port = 80; - return DEMUXER_TYPE_ASF; + *file_format = DEMUXER_TYPE_ASF; + return 0; } // HTTP based protocol @@ -302,26 +301,26 @@ fd = http_send_request( url ); if( fd<0 ) { - *fd_out=-1; - return DEMUXER_TYPE_UNKNOWN; + return -1; } http_hdr = http_read_response( fd ); if( http_hdr==NULL ) { close( fd ); - *fd_out=-1; http_free( http_hdr ); - return DEMUXER_TYPE_UNKNOWN; + return -1; } *fd_out=fd; http_debug_hdr( http_hdr ); + streaming_ctrl->data = (void*)http_hdr; + // Check if the response is an ICY status_code reason_phrase if( !strcasecmp(http_hdr->protocol, "ICY") ) { // Ok, we have detected an mp3 streaming - http_free( http_hdr ); - return DEMUXER_TYPE_MPEG_PS; + *file_format = DEMUXER_TYPE_MPEG_PS; + return 0; } switch( http_hdr->status_code ) { @@ -334,10 +333,13 @@ // Check in the mime type table for a demuxer type for( i=0 ; i<(sizeof(mime_type_table)/sizeof(mime_type_table[0])) ; i++ ) { if( !strcasecmp( content_type, mime_type_table[i].mime_type ) ) { - http_free( http_hdr ); - return mime_type_table[i].demuxer_type; + *file_format = mime_type_table[i].demuxer_type; + return 0; } } + // Not found in the mime type table, don't fail, + // we should try raw HTTP + return 0; } break; // Redirect @@ -349,24 +351,21 @@ close( fd ); url_free( url ); url = url_new( next_url ); + http_free( http_hdr ); redirect = 1; } break; default: printf("Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); - close( fd ); - *fd_out=-1; - http_free( http_hdr ); - return DEMUXER_TYPE_UNKNOWN; + return -1; } } else { printf("Unknown protocol '%s'\n", url->protocol ); - return DEMUXER_TYPE_UNKNOWN; + return -1; } } while( redirect ); - http_free( http_hdr ); - return DEMUXER_TYPE_UNKNOWN; + return -1; } int @@ -423,7 +422,7 @@ int nop_streaming_start( stream_t *stream ) { - HTTP_header_t *http_hdr; + HTTP_header_t *http_hdr = NULL; int fd; if( stream==NULL ) return -1; @@ -451,7 +450,19 @@ fd = -1; } stream->fd = fd; + } else { + http_hdr = (HTTP_header_t*)stream->streaming_ctrl->data; + if( http_hdr->body_size>0 ) { + if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { + http_free( http_hdr ); + return -1; + } + } + } + + if( http_hdr ) { http_free( http_hdr ); + stream->streaming_ctrl->data = NULL; } stream->streaming_ctrl->streaming_read = nop_streaming_read; @@ -467,11 +478,9 @@ // Start listening on a UDP port. If multicast, join the group. int rtp_open_socket( URL_t *url ) { - int fd; int socket_server_fd; int err, err_len; fd_set set; - struct timeval tv; struct sockaddr_in server_address; struct ip_mreq mcast; @@ -559,31 +568,21 @@ } int -streaming_start(stream_t *stream, URL_t *url, int demuxer_type) { +//streaming_start(stream_t *stream, URL_t *url, int demuxer_type) { +streaming_start(stream_t *stream, int demuxer_type) { int ret=-1; if( stream==NULL ) return -1; - stream->streaming_ctrl = streaming_ctrl_new( ); - if( stream->streaming_ctrl==NULL ) { - return -1; - } - - stream->streaming_ctrl->url = url_copy(url); -// stream->streaming_ctrl->demuxer_type = demuxer_type; - // For RTP streams, we usually don't know the stream type until we open it. - if( !strcmp( url->protocol, "rtp")) - { - if(stream->fd >= 0) - { + if( !strcmp( stream->streaming_ctrl->url->protocol, "rtp")) { + if(stream->fd >= 0) { if(close(stream->fd) < 0) printf("streaming_start : Closing socket %d failed %s\n",stream->fd,strerror(errno)); } stream->fd = -1; stream->fd = rtp_streaming_start( stream ); - } + } else // For connection-oriented streams, we can usually determine the streaming type. - else switch( demuxer_type ) { case DEMUXER_TYPE_ASF: // Send the appropriate HTTP request diff -r 898caa690c0b -r f732854e3d16 libmpdemux/network.h --- a/libmpdemux/network.h Tue Jan 08 02:01:04 2002 +0000 +++ b/libmpdemux/network.h Tue Jan 08 07:31:29 2002 +0000 @@ -16,6 +16,7 @@ #include #include "url.h" +#include "stream.h" #define BUFFER_SIZE 2048 @@ -37,6 +38,13 @@ void *data; } streaming_ctrl_t; +streaming_ctrl_t *streaming_ctrl_new(); +void streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl ); + +int autodetectProtocol( streaming_ctrl_t *streaming_ctrl, int *fd_out, int *file_format ); + +//int streaming_start( stream_t *stream, int demuxer_type ); + int streaming_bufferize( streaming_ctrl_t *streaming_ctrl, char *buffer, int size); int nop_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ); diff -r 898caa690c0b -r f732854e3d16 libmpdemux/open.c --- a/libmpdemux/open.c Tue Jan 08 02:01:04 2002 +0000 +++ b/libmpdemux/open.c Tue Jan 08 07:31:29 2002 +0000 @@ -372,10 +372,19 @@ #ifdef STREAMING url = url_new(filename); if(url) { - (*file_format)=autodetectProtocol( url, &f ); + streaming_ctrl_t *streaming_ctrl; + streaming_ctrl = streaming_ctrl_new(); + if( streaming_ctrl==NULL ) return NULL; + streaming_ctrl->url = url_copy( url ); + if( autodetectProtocol( streaming_ctrl, &f, file_format )<0 ) { + mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_UnableOpenURL, filename ); + return NULL; + } mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_ConnToServer, url->hostname ); stream=new_stream(f,STREAMTYPE_STREAM); - if( streaming_start( stream , url, *file_format )<0){ + stream->streaming_ctrl = streaming_ctrl; + //if( streaming_start( stream , url, *file_format )<0){ + if( streaming_start( stream, *file_format )<0){ mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_UnableOpenURL, filename); url_free(url); return NULL;