changeset 15585:281d155fb37f

ported all network streams to the new API
author nicodvb
date Sun, 29 May 2005 12:54:00 +0000
parents b5f111039c16
children 34cf1cf85ee3
files libmpdemux/Makefile libmpdemux/asf_streaming.c libmpdemux/demux_rtp.cpp libmpdemux/demux_rtp.h libmpdemux/http.c libmpdemux/network.c libmpdemux/network.h libmpdemux/open.c libmpdemux/pnm.c libmpdemux/pnm.h libmpdemux/realrtsp/rtsp.c libmpdemux/rtp.c libmpdemux/stream.c libmpdemux/stream.h libmpdemux/stream_livedotcom.c
diffstat 15 files changed, 927 insertions(+), 872 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/Makefile	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/Makefile	Sun May 29 12:54:00 2005 +0000
@@ -3,7 +3,7 @@
 
 include ../config.mak
 
-SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c stream_smb.c stream_vstream.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c demux_vqf.c stream_dvd.c
+SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c stream_smb.c stream_vstream.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c demux_vqf.c stream_dvd.c stream_livedotcom.c
 ifeq ($(XMMS_PLUGINS),yes)
 SRCS += demux_xmms.c
 endif 
--- a/libmpdemux/asf_streaming.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/asf_streaming.c	Sun May 29 12:54:00 2005 +0000
@@ -30,15 +30,14 @@
 #endif
 
 extern int verbose;
-
+extern int network_bandwidth;
 
-int asf_http_streaming_start( stream_t *stream, int *demuxer_type );
 int asf_mmst_streaming_start( stream_t *stream );
-
+static int asf_http_streaming_start(stream_t *stream, int *demuxer_type);
 
 // We can try several protocol for asf streaming
 // * first the UDP protcol, if there is a firewall, UDP
-//   packets will not come back, so the mmsu will failed.
+//   packets will not come back, so the mmsu will fail.
 // * Then we can try TCP, but if there is a proxy for
 //   internet connection, the TCP connection will not get
 //   through
@@ -46,21 +45,11 @@
 // 
 // Note: Using 	WMP sequence  MMSU then MMST and then HTTP.
 
-int
-asf_streaming_start( stream_t *stream, int *demuxer_type) {
+static int asf_streaming_start( stream_t *stream, int *demuxer_type) {
     char *proto = stream->streaming_ctrl->url->protocol;
     int fd = -1;
     int port = stream->streaming_ctrl->url->port;
 
-    // Is protocol even valid mms,mmsu,mmst,http,http_proxy?
-    if (!(!strncasecmp(proto, "mmst", 4) || !strncasecmp(proto, "mmsu", 4) ||
-	!strncasecmp(proto, "http_proxy", 10) || !strncasecmp(proto, "mms", 3) ||
-	!strncasecmp(proto, "http", 4)))
-    {
-        mp_msg(MSGT_NETWORK,MSGL_ERR,"Unknown protocol: %s\n", proto );
-        return -1;
-    }
-
     // Is protocol mms or mmsu?
     if (!strncasecmp(proto, "mmsu", 4) || !strncasecmp(proto, "mms", 3))
     {
@@ -84,7 +73,7 @@
 
     //Is protocol http, http_proxy, or mms? 
     if (!strncasecmp(proto, "http_proxy", 10) || !strncasecmp(proto, "http", 4) ||
-	!strncasecmp(proto, "mms", 3))
+	!strncasecmp(proto, "mms", 3) || !strncasecmp(proto, "mmshttp", 7))
     {
 		mp_msg(MSGT_NETWORK,MSGL_V,"Trying ASF/HTTP...\n");
 		fd = asf_http_streaming_start( stream, demuxer_type );
@@ -152,6 +141,11 @@
 extern int audio_id;
 extern int video_id;
 
+static void close_s(stream_t *stream) {
+	close(stream->fd);
+	stream->fd=-1;
+}
+
 static int max_idx(int s_count, int *s_rates, int bound) {
   int i, best = -1, rate = -1;
   for (i = 0; i < s_count; i++) {
@@ -848,8 +842,52 @@
 		stream->streaming_ctrl->buffering = 1;
 	}
 	stream->streaming_ctrl->status = streaming_playing_e;
+	stream->close = close_s;
 
 	http_free( http_hdr );
 	return 0;
 }
 
+static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
+	URL_t *url;
+
+	stream->streaming_ctrl = streaming_ctrl_new();
+	if( stream->streaming_ctrl==NULL ) {
+		return STREAM_ERROR;
+	}
+	stream->streaming_ctrl->bandwidth = network_bandwidth;
+	url = url_new(stream->url);
+	stream->streaming_ctrl->url = check4proxies(url);
+	//url_free(url);
+	
+	mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_ASF, URL: %s\n", stream->url);
+	if((!strncmp(stream->url, "http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN)) {
+		streaming_ctrl_free(stream->streaming_ctrl);
+		stream->streaming_ctrl = NULL;
+		return STREAM_UNSUPORTED;
+	}
+
+	if(asf_streaming_start(stream, file_format) < 0) {
+		mp_msg(MSGT_OPEN, MSGL_ERR, "failed, exiting\n");
+		streaming_ctrl_free(stream->streaming_ctrl);
+		stream->streaming_ctrl = NULL;
+		return STREAM_UNSUPORTED;
+	}
+	
+	*file_format = DEMUXER_TYPE_ASF;
+	stream->type = STREAMTYPE_STREAM;
+	fixup_network_stream_cache(stream);
+	return STREAM_OK;
+}
+
+stream_info_t stream_info_asf = {
+  "mms and mms over http streaming",
+  "null",
+  "Bertrand, Reimar Doeffinger, Albeu",
+  "originally based on work by Majormms (is that code still there?)",
+  open_s,
+  {"mms", "mmsu", "mmst", "http", "http_proxy", "mmshttp", NULL},
+  NULL,
+  0 // Urls are an option string
+};
+
--- a/libmpdemux/demux_rtp.cpp	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/demux_rtp.cpp	Sun May 29 12:54:00 2005 +0000
@@ -16,38 +16,6 @@
 #include "GroupsockHelper.hh"
 #include <unistd.h>
 
-extern "C" stream_t* stream_open_sdp(int fd, off_t fileSize,
-				     int* file_format) {
-  *file_format = DEMUXER_TYPE_RTP;
-  stream_t* newStream = NULL;
-  do {
-    char* sdpDescription = (char*)malloc(fileSize+1);
-    if (sdpDescription == NULL) break;
-
-    ssize_t numBytesRead = read(fd, sdpDescription, fileSize);
-    if (numBytesRead != fileSize) break;
-    sdpDescription[fileSize] = '\0'; // to be safe
-
-    newStream = (stream_t*)calloc(sizeof (stream_t), 1);
-    if (newStream == NULL) break;
-
-    // Store the SDP description in the 'priv' field, for later use:
-    newStream->priv = sdpDescription; 
-  } while (0);
-  return newStream;
-}
-
-extern "C" int _rtsp_streaming_seek(int /*fd*/, off_t /*pos*/,
-				    streaming_ctrl_t* /*streaming_ctrl*/) {
-  return -1; // For now, we don't handle RTSP stream seeking
-}
-
-extern "C" int rtsp_streaming_start(stream_t* stream) {
-  stream->streaming_ctrl->streaming_seek = _rtsp_streaming_seek;
-
-  return 0;
-}
-
 // A data structure representing input data for each stream:
 class ReadBufferQueue {
 public:
--- a/libmpdemux/demux_rtp.h	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/demux_rtp.h	Sun May 29 12:54:00 2005 +0000
@@ -11,12 +11,6 @@
 #include "demuxer.h"
 #endif
 
-// Open a SDP file:
-stream_t* stream_open_sdp(int fd, off_t fileSize, int* file_format);
-
-// Open a RTSP URL:
-int rtsp_streaming_start(stream_t* stream);
-
 // Open a RTP demuxer (which was initiated either from a SDP file,
 // or from a RTSP URL):
 demuxer_t* demux_open_rtp(demuxer_t* demuxer);
--- a/libmpdemux/http.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/http.c	Sun May 29 12:54:00 2005 +0000
@@ -7,11 +7,112 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "http.h"
 #include "url.h"
 #include "mp_msg.h"
 
+#include "stream.h"
+#include "demuxer.h"
+#include "network.h"
+#include "help_mp.h"
+
+#ifndef HAVE_WINSOCK2
+#define closesocket close
+#else
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+
+
+extern mime_struct_t mime_type_table[];
+extern int stream_cache_size;
+extern int network_bandwidth;
+
+extern int http_seek(stream_t *stream, off_t pos);
+
+static int nop_streaming_start( stream_t *stream ) {
+	HTTP_header_t *http_hdr = NULL;
+	char *next_url=NULL;
+	URL_t *rd_url=NULL;
+	int fd,ret;
+	if( stream==NULL ) return -1;
+
+	fd = stream->fd;
+	if( fd<0 ) {
+		fd = http_send_request( stream->streaming_ctrl->url, 0 ); 
+		if( fd<0 ) return -1;
+		http_hdr = http_read_response( fd );
+		if( http_hdr==NULL ) return -1;
+
+		switch( http_hdr->status_code ) {
+			case 200: // OK
+				mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") );
+				mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") );
+				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;
+					}
+				}
+				break;
+			// Redirect
+			case 301: // Permanently
+			case 302: // Temporarily
+				ret=-1;
+				next_url = http_get_field( http_hdr, "Location" );
+
+				if (next_url != NULL)
+					rd_url=url_new(next_url);
+
+				if (next_url != NULL && rd_url != NULL) {
+					mp_msg(MSGT_NETWORK,MSGL_STATUS,"Redirected: Using this url instead %s\n",next_url);
+							stream->streaming_ctrl->url=check4proxies(rd_url);
+					ret=nop_streaming_start(stream); //recursively get streaming started 
+				} else {
+					mp_msg(MSGT_NETWORK,MSGL_ERR,"Redirection failed\n");
+					closesocket( fd );
+					fd = -1;
+				}
+				return ret;
+				break;
+			case 401: //Authorization required
+			case 403: //Forbidden
+			case 404: //Not found
+			case 500: //Server Error
+			default:
+				mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned code %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
+				closesocket( fd );
+				fd = -1;
+				return -1;
+				break;
+		}
+		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 );
+				stream->streaming_ctrl->data = NULL;
+				return -1;
+			}
+		}
+	}
+
+	if( http_hdr ) {
+		http_free( http_hdr );
+		stream->streaming_ctrl->data = NULL;
+	}
+
+	stream->streaming_ctrl->streaming_read = nop_streaming_read;
+	stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
+	stream->streaming_ctrl->prebuffer_size = 64*1024; // 64 KBytes
+	stream->streaming_ctrl->buffering = 1;
+	stream->streaming_ctrl->status = streaming_playing_e;
+	return 0;
+}
+
 HTTP_header_t *
 http_new_header() {
 	HTTP_header_t *http_hdr;
@@ -439,4 +540,236 @@
 	return -1;
 }
 
+static int http_streaming_start(stream_t *stream, int* file_format) {
+	HTTP_header_t *http_hdr;
+	unsigned int i;
+	int fd=-1;
+	int redirect = 0;
+	int auth_retry=0;
+	int seekable=0;
+	char *content_type;
+	char *next_url;
+	URL_t *url = stream->streaming_ctrl->url;
 
+	do
+	{
+		fd = http_send_request( url, 0 );
+		if( fd<0 ) {
+			return -1;
+		}
+
+		http_hdr = http_read_response( fd );
+		if( http_hdr==NULL ) {
+			closesocket( fd );
+			http_free( http_hdr );
+			return -1;
+		}
+
+		stream->fd=fd;
+		if( verbose>0 ) {
+			http_debug_hdr( http_hdr );
+		}
+		
+		stream->streaming_ctrl->data = (void*)http_hdr;
+
+		// Check if we can make partial content requests and thus seek in http-streams
+		if( http_hdr!=NULL && http_hdr->status_code==200 ) {
+		    char *accept_ranges;
+		    if( (accept_ranges = http_get_field(http_hdr,"Accept-Ranges")) != NULL )
+			seekable = strncmp(accept_ranges,"bytes",5)==0;
+		}
+
+		// Check if the response is an ICY status_code reason_phrase
+		if( !strcasecmp(http_hdr->protocol, "ICY") ) {
+			switch( http_hdr->status_code ) {
+				case 200: { // OK
+					char *field_data = NULL;
+					// note: I skip icy-notice1 and 2, as they contain html <BR>
+					// and are IMHO useless info ::atmos
+					if( (field_data = http_get_field(http_hdr, "icy-name")) != NULL )
+						mp_msg(MSGT_NETWORK,MSGL_INFO,"Name   : %s\n", field_data); field_data = NULL;
+					if( (field_data = http_get_field(http_hdr, "icy-genre")) != NULL )
+						mp_msg(MSGT_NETWORK,MSGL_INFO,"Genre  : %s\n", field_data); field_data = NULL;
+					if( (field_data = http_get_field(http_hdr, "icy-url")) != NULL )
+						mp_msg(MSGT_NETWORK,MSGL_INFO,"Website: %s\n", field_data); field_data = NULL;
+					// XXX: does this really mean public server? ::atmos
+					if( (field_data = http_get_field(http_hdr, "icy-pub")) != NULL )
+						mp_msg(MSGT_NETWORK,MSGL_INFO,"Public : %s\n", atoi(field_data)?"yes":"no"); field_data = NULL;
+					if( (field_data = http_get_field(http_hdr, "icy-br")) != NULL )
+						mp_msg(MSGT_NETWORK,MSGL_INFO,"Bitrate: %skbit/s\n", field_data); field_data = NULL;
+					
+					// If content-type == video/nsv we most likely have a winamp video stream 
+					// otherwise it should be mp3. if there are more types consider adding mime type 
+					// handling like later
+					if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "video/nsv") || !strcmp(field_data, "misc/ultravox")))
+						*file_format = DEMUXER_TYPE_NSV;
+					else
+						*file_format = DEMUXER_TYPE_AUDIO;
+					return 0;
+				}
+				case 400: // Server Full
+					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server is full, skipping!\n");
+					return -1;
+				case 401: // Service Unavailable
+					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return service unavailable, skipping!\n");
+					return -1;
+				case 403: // Service Forbidden
+					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return 'Service Forbidden'\n");
+					return -1;
+				case 404: // Resource Not Found
+					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server couldn't find requested stream, skipping!\n");
+					return -1;
+				default:
+					mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: unhandled ICY-Errorcode, contact MPlayer developers!\n");
+					return -1;
+			}
+		}
+
+		// Assume standard http if not ICY			
+		switch( http_hdr->status_code ) {
+			case 200: // OK
+				// Look if we can use the Content-Type
+				content_type = http_get_field( http_hdr, "Content-Type" );
+				if( content_type!=NULL ) {
+					char *content_length = NULL;
+					mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", content_type );
+					if( (content_length = http_get_field(http_hdr, "Content-Length")) != NULL)
+						mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length"));
+					// Check in the mime type table for a demuxer type
+					i = 0;
+					while(mime_type_table[i].mime_type != NULL) {
+						if( !strcasecmp( content_type, mime_type_table[i].mime_type ) ) {
+							*file_format = mime_type_table[i].demuxer_type;
+							return seekable;
+						}
+						i++;
+					}
+				}
+				// Not found in the mime type table, don't fail,
+				// we should try raw HTTP
+				return seekable;
+			// Redirect
+			case 301: // Permanently
+			case 302: // Temporarily
+				// TODO: RFC 2616, recommand to detect infinite redirection loops
+				next_url = http_get_field( http_hdr, "Location" );
+				if( next_url!=NULL ) {
+					closesocket( fd );
+					url_free( url );
+					stream->streaming_ctrl->url = url = url_new( next_url );
+					http_free( http_hdr );
+					redirect = 1;	
+				}
+				break;
+			case 401: // Authentication required
+				if( http_authenticate(http_hdr, url, &auth_retry)<0 ) return STREAM_UNSUPORTED;
+				redirect = 1;
+				break;
+			default:
+				mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
+				return -1;
+		}
+	} while( redirect );
+
+	return -1;
+}
+
+static int fixup_open(stream_t *stream,int seekable) {
+
+	stream->type = STREAMTYPE_STREAM;
+	if(seekable)
+	{
+		stream->flags |= STREAM_SEEK;
+		stream->seek = http_seek;
+	}
+	stream->streaming_ctrl->bandwidth = network_bandwidth;
+	if(nop_streaming_start( stream )) {
+		mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n");
+		streaming_ctrl_free(stream->streaming_ctrl);
+		stream->streaming_ctrl = NULL;
+		return STREAM_UNSUPORTED;
+	}
+	if(stream->streaming_ctrl->buffering) {
+		if(stream_cache_size<0) {
+			// cache option not set, will use our computed value.
+			// buffer in KBytes, *5 because the prefill is 20% of the buffer.
+			stream_cache_size = (stream->streaming_ctrl->prebuffer_size/1024)*5;
+			if( stream_cache_size<64 ) stream_cache_size = 64;	// 16KBytes min buffer
+		}
+		mp_msg(MSGT_NETWORK,MSGL_INFO,"Cache size set to %d KBytes, seekable: %d\n", stream_cache_size, seekable);
+	}
+
+	fixup_network_stream_cache(stream);
+	return STREAM_OK;
+}
+
+static int open_s1(stream_t *stream,int mode, void* opts, int* file_format) {
+	int seekable=0;
+	URL_t *url;
+
+	stream->streaming_ctrl = streaming_ctrl_new();
+	if( stream->streaming_ctrl==NULL ) {
+		return STREAM_ERROR;
+	}
+	stream->streaming_ctrl->bandwidth = network_bandwidth;
+	url = url_new(stream->url);
+	stream->streaming_ctrl->url = check4proxies(url);
+	//url_free(url);
+	
+	mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_HTTP(1), URL: %s\n", stream->url);
+	seekable = http_streaming_start(stream, file_format);
+	if((seekable < 0) || (*file_format == DEMUXER_TYPE_ASF)) {
+		streaming_ctrl_free(stream->streaming_ctrl);
+		stream->streaming_ctrl = NULL;
+		return STREAM_UNSUPORTED;
+	}
+
+	return fixup_open(stream, seekable);
+}
+
+static int open_s2(stream_t *stream,int mode, void* opts, int* file_format) {
+	int seekable=0;
+	URL_t *url;
+
+	stream->streaming_ctrl = streaming_ctrl_new();
+	if( stream->streaming_ctrl==NULL ) {
+		return STREAM_ERROR;
+	}
+	stream->streaming_ctrl->bandwidth = network_bandwidth;
+	url = url_new(stream->url);
+	stream->streaming_ctrl->url = check4proxies(url);
+	//url_free(url);
+	
+	mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_HTTP(2), URL: %s\n", stream->url);
+	seekable = http_streaming_start(stream, file_format);
+	if(seekable < 0) {
+		streaming_ctrl_free(stream->streaming_ctrl);
+		stream->streaming_ctrl = NULL;
+		return STREAM_UNSUPORTED;
+	}
+
+	return fixup_open(stream, seekable);
+}
+
+
+stream_info_t stream_info_http1 = {
+  "http streaming",
+  "null",
+  "Bertrand, Albeau, Reimar Doeffinger, Arpi?",
+  "plain http",
+  open_s1,
+  {"http", "http_proxy", NULL},
+  NULL,
+  0 // Urls are an option string
+};
+
+stream_info_t stream_info_http2 = {
+  "http streaming",
+  "null",
+  "Bertrand, Albeu, Arpi? who?",
+  "plain http, aslo used as falback for many other protocols",
+  open_s2,
+  {"http", "http_proxy", "pnm", "mms", "mmsu", "mmst", "rtsp", NULL},	//all the others as fallback
+  NULL,
+  0 // Urls are an option string
+};
--- a/libmpdemux/network.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/network.c	Sun May 29 12:54:00 2005 +0000
@@ -31,10 +31,6 @@
 #include "http.h"
 #include "cookies.h"
 #include "url.h"
-#include "asf.h"
-#include "rtp.h"
-#include "pnm.h"
-#include "realrtsp/rtsp_session.h"
 
 #include "../version.h"
 
@@ -43,9 +39,6 @@
 
 extern int mp_input_check_interrupt(int time);
 
-int asf_streaming_start( stream_t *stream, int *demuxer_type );
-int rtsp_streaming_start( stream_t *stream );
-
 /* Variables for the command line option -user, -passwd, -bandwidth,
    -user-agent and -nocookies */
 
@@ -60,10 +53,7 @@
 int   network_ipv4_only_proxy = 0;
 
 
-static struct {
-	char *mime_type;
-	int demuxer_type;
-} mime_type_table[] = {
+mime_struct_t mime_type_table[] = {
 	// MP3 streaming, some MP3 streaming server answer with audio/mpeg
 	{ "audio/mpeg", DEMUXER_TYPE_AUDIO },
 	// MPEG streaming
@@ -93,38 +83,10 @@
 	{ "application/x-ogg", DEMUXER_TYPE_OGG },
 	// NullSoft Streaming Video
 	{ "video/nsv", DEMUXER_TYPE_NSV},
-	{ "misc/ultravox", DEMUXER_TYPE_NSV}
-
+	{ "misc/ultravox", DEMUXER_TYPE_NSV},
+	{ NULL, DEMUXER_TYPE_UNKNOWN},
 };
 
-/*
- * An autodetection based on the extension is not a good idea.
- * 
-static struct {
-	char *extension;
-	int demuxer_type;
-} extensions_table[] = {
-	{ "mpeg", DEMUXER_TYPE_MPEG_PS },
-	{ "mpg", DEMUXER_TYPE_MPEG_PS },
-	{ "mpe", DEMUXER_TYPE_MPEG_ES },
-	{ "avi", DEMUXER_TYPE_AVI },
-	{ "mov", DEMUXER_TYPE_MOV },
-	{ "qt", DEMUXER_TYPE_MOV },
-	{ "asx", DEMUXER_TYPE_ASF },
-	{ "asf", DEMUXER_TYPE_ASF },
-	{ "wmv", DEMUXER_TYPE_ASF },
-	{ "wma", DEMUXER_TYPE_ASF },
-	{ "viv", DEMUXER_TYPE_VIVO },
-	{ "rm", DEMUXER_TYPE_REAL },
-	{ "ra", DEMUXER_TYPE_REAL },
-	{ "y4m", DEMUXER_TYPE_Y4M },
-	{ "mp3", DEMUXER_TYPE_AUDIO },
-	{ "ogg", DEMUXER_TYPE_OGG },
-	{ "wav", DEMUXER_TYPE_AUDIO },
-	{ "pls", DEMUXER_TYPE_PLAYLIST },
-	{ "m3u", DEMUXER_TYPE_PLAYLIST }
-};
-*/
 
 streaming_ctrl_t *
 streaming_ctrl_new( ) {
@@ -147,26 +109,6 @@
 	free( streaming_ctrl );
 }
 
-int
-read_rtp_from_server(int fd, char *buffer, int length) {
-	struct rtpheader rh;
-	char *data;
-	int len;
-	static int got_first = 0;
-	static unsigned short sequence;
-
-	if( buffer==NULL || length<0 ) return -1;
-
-	getrtp2(fd, &rh, &data, &len);
-	if( got_first && rh.b.sequence != (unsigned short)(sequence+1) )
-		mp_msg(MSGT_NETWORK,MSGL_ERR,"RTP packet sequence error!  Expected: %d, received: %d\n", 
-			sequence+1, rh.b.sequence);
-	got_first = 1;
-	sequence = rh.b.sequence;
-	memcpy(buffer, data, len);
-	return(len);
-}
-
 
 // Converts an address family constant to a string
 
@@ -624,229 +566,6 @@
 }
 
 
-// By using the protocol, the extension of the file or the content-type
-// we might be able to guess the streaming type.
-int
-autodetectProtocol(streaming_ctrl_t *streaming_ctrl, int *fd_out, int *file_format) {
-	HTTP_header_t *http_hdr;
-	unsigned int i;
-	int fd=-1;
-	int redirect;
-	int auth_retry=0;
-	int seekable=0;
-	char *extension;
-	char *content_type;
-	char *next_url;
-
-	URL_t *url = streaming_ctrl->url;
-	*file_format = DEMUXER_TYPE_UNKNOWN;
-
-	do {
-		*fd_out = -1;
-		next_url = NULL;
-		extension = NULL;
-		content_type = NULL;
-		redirect = 0;
-
-		if( url==NULL ) {
-			return -1;
-		}
-
-		// Checking for PNM://
-		if( !strcasecmp(url->protocol, "pnm") ) {
-			*file_format = DEMUXER_TYPE_REAL;
-			return 0;
-		}
-		
-/* 
- * An autodetection based on the extension is not a good idea.
- * 
-		// Get the extension of the file if present
-		if( url->file!=NULL ) {
-			for( i=strlen(url->file) ; i>0 ; i-- ) {
-				if( url->file[i]=='.' ) {
-					extension=(url->file)+i+1;
-					break;
-				}
-			}
-		}
-extension=NULL;	
-		if( extension!=NULL ) {
-			mp_msg(MSGT_NETWORK,MSGL_DBG2,"Extension: %s\n", extension );
-			// 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) ) {
-					*file_format = extensions_table[i].demuxer_type;
-					return 0;
-				}
-			}
-		}
-*/
-		
-		// Checking for RTSP
-		if( !strcasecmp(url->protocol, "rtsp") ) {
-			// Try Real rtsp:// first (it's always built in)
-			// If it fails, try live.com (if compiled in)
-			*file_format = DEMUXER_TYPE_REAL;
-			return 0;
-		// Checking for SIP
-		} else if( !strcasecmp(url->protocol, "sip") ) {
-#ifdef STREAMING_LIVE_DOT_COM
-			*file_format = DEMUXER_TYPE_RTP;
-			return 0;
-#else
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"SIP support requires the \"LIVE.COM Streaming Media\" libraries!\n");
-			return -1;
-#endif
-		}
-
-		if(!strcasecmp(url->protocol, "udp") ) {
-			*file_format = DEMUXER_TYPE_UNKNOWN;
-			return 0;
-		}
-
-	// Old, hacked RTP support, which works for MPEG Streams
-	//   RTP streams only:
-		// Checking for RTP
-		if( !strcasecmp(url->protocol, "rtp") ) {
-			if( url->port==0 ) {
-				mp_msg(MSGT_NETWORK,MSGL_ERR,"You must enter a port number for RTP streams!\n");
-				return -1;
-			}
-			return 0;
-		}
-
-		// Checking for ASF
-		if( !strncasecmp(url->protocol, "mms", 3) ) {
-			*file_format = DEMUXER_TYPE_ASF;
-			return 0;
-		}
-
-		// HTTP based protocol
-		if( !strcasecmp(url->protocol, "http") || !strcasecmp(url->protocol, "http_proxy") ) {
-			fd = http_send_request( url, 0 );
-			if( fd<0 ) {
-				return -1;
-			}
-
-			http_hdr = http_read_response( fd );
-			if( http_hdr==NULL ) {
-				closesocket( fd );
-				http_free( http_hdr );
-				return -1;
-			}
-
-			*fd_out=fd;
-			if( verbose>0 ) {
-				http_debug_hdr( http_hdr );
-			}
-			
-			streaming_ctrl->data = (void*)http_hdr;
-
-			// Check if we can make partial content requests and thus seek in http-streams
-		        if( http_hdr!=NULL && http_hdr->status_code==200 ) {
-			    char *accept_ranges;
-			    if( (accept_ranges = http_get_field(http_hdr,"Accept-Ranges")) != NULL )
-				seekable = strncmp(accept_ranges,"bytes",5)==0;
-			} 
-
-			// Check if the response is an ICY status_code reason_phrase
-			if( !strcasecmp(http_hdr->protocol, "ICY") ) {
-				switch( http_hdr->status_code ) {
-					case 200: { // OK
-						char *field_data = NULL;
-						// note: I skip icy-notice1 and 2, as they contain html <BR>
-						// and are IMHO useless info ::atmos
-						if( (field_data = http_get_field(http_hdr, "icy-name")) != NULL )
-							mp_msg(MSGT_NETWORK,MSGL_INFO,"Name   : %s\n", field_data); field_data = NULL;
-						if( (field_data = http_get_field(http_hdr, "icy-genre")) != NULL )
-							mp_msg(MSGT_NETWORK,MSGL_INFO,"Genre  : %s\n", field_data); field_data = NULL;
-						if( (field_data = http_get_field(http_hdr, "icy-url")) != NULL )
-							mp_msg(MSGT_NETWORK,MSGL_INFO,"Website: %s\n", field_data); field_data = NULL;
-						// XXX: does this really mean public server? ::atmos
-						if( (field_data = http_get_field(http_hdr, "icy-pub")) != NULL )
-							mp_msg(MSGT_NETWORK,MSGL_INFO,"Public : %s\n", atoi(field_data)?"yes":"no"); field_data = NULL;
-						if( (field_data = http_get_field(http_hdr, "icy-br")) != NULL )
-							mp_msg(MSGT_NETWORK,MSGL_INFO,"Bitrate: %skbit/s\n", field_data); field_data = NULL;
-						
-						// If content-type == video/nsv we most likely have a winamp video stream 
-						// otherwise it should be mp3. if there are more types consider adding mime type 
-						// handling like later
-				                if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "video/nsv") || !strcmp(field_data, "misc/ultravox")))
-							*file_format = DEMUXER_TYPE_NSV;
-						else
-							*file_format = DEMUXER_TYPE_AUDIO;
-						return 0;
-					}
-					case 400: // Server Full
-						mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server is full, skipping!\n");
-						return -1;
-					case 401: // Service Unavailable
-						mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return service unavailable, skipping!\n");
-						return -1;
-					case 403: // Service Forbidden
-						mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server return 'Service Forbidden'\n");
-						return -1;
-					case 404: // Resource Not Found
-						mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: ICY-Server couldn't find requested stream, skipping!\n");
-						return -1;
-					default:
-						mp_msg(MSGT_NETWORK,MSGL_ERR,"Error: unhandled ICY-Errorcode, contact MPlayer developers!\n");
-						return -1;
-				}
-			}
-
-			// Assume standard http if not ICY			
-			switch( http_hdr->status_code ) {
-				case 200: // OK
-					// Look if we can use the Content-Type
-					content_type = http_get_field( http_hdr, "Content-Type" );
-					if( content_type!=NULL ) {
-						char *content_length = NULL;
-						mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", content_type );
-						if( (content_length = http_get_field(http_hdr, "Content-Length")) != NULL)
-							mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length"));
-						// 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 ) ) {
-								*file_format = mime_type_table[i].demuxer_type;
-								return seekable; // for streaming_start
-							}
-						}
-					}
-					// Not found in the mime type table, don't fail,
-					// we should try raw HTTP
-					return seekable; // for streaming_start
-				// Redirect
-				case 301: // Permanently
-				case 302: // Temporarily
-					// TODO: RFC 2616, recommand to detect infinite redirection loops
-					next_url = http_get_field( http_hdr, "Location" );
-					if( next_url!=NULL ) {
-						closesocket( fd );
-						url_free( url );
-						streaming_ctrl->url = url = url_new( next_url );
-						http_free( http_hdr );
-						redirect = 1;	
-					}
-					break;
-				case 401: // Authentication required
-					if( http_authenticate(http_hdr, url, &auth_retry)<0 ) return -1;
-					redirect = 1;
-					break;
-				default:
-					mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
-					return -1;
-			}
-		} else {
-			mp_msg(MSGT_NETWORK,MSGL_V,"Unknown protocol '%s'\n", url->protocol );
-			return -1;
-		}
-	} while( redirect );
-
-	return -1;
-}
-
 int
 streaming_bufferize( streaming_ctrl_t *streaming_ctrl, char *buffer, int size) {
 //printf("streaming_bufferize\n");
@@ -903,469 +622,20 @@
 	stream_ctrl=NULL;
 }
 
-int
-nop_streaming_start( stream_t *stream ) {
-	HTTP_header_t *http_hdr = NULL;
-	char *next_url=NULL;
-	URL_t *rd_url=NULL;
-	int fd,ret;
-	if( stream==NULL ) return -1;
 
-	fd = stream->fd;
-	if( fd<0 ) {
-		fd = http_send_request( stream->streaming_ctrl->url, 0 ); 
-		if( fd<0 ) return -1;
-		http_hdr = http_read_response( fd );
-		if( http_hdr==NULL ) return -1;
-
-		switch( http_hdr->status_code ) {
-			case 200: // OK
-				mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") );
-				mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") );
-				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;
-					}
-				}
-				break;
-			// Redirect
-			case 301: // Permanently
-			case 302: // Temporarily
-				ret=-1;
-				next_url = http_get_field( http_hdr, "Location" );
-
-				if (next_url != NULL)
-					rd_url=url_new(next_url);
-
-				if (next_url != NULL && rd_url != NULL) {
-					mp_msg(MSGT_NETWORK,MSGL_STATUS,"Redirected: Using this url instead %s\n",next_url);
-							stream->streaming_ctrl->url=check4proxies(rd_url);
-					ret=nop_streaming_start(stream); //recursively get streaming started 
-				} else {
-					mp_msg(MSGT_NETWORK,MSGL_ERR,"Redirection failed\n");
-					closesocket( fd );
-					fd = -1;
-				}
-				return ret;
-				break;
-			case 401: //Authorization required
-			case 403: //Forbidden
-			case 404: //Not found
-			case 500: //Server Error
-			default:
-				mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned code %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase );
-				closesocket( fd );
-				fd = -1;
-				return -1;
-				break;
-		}
-		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 );
-				stream->streaming_ctrl->data = NULL;
-				return -1;
-			}
-		}
-	}
-
-	if( http_hdr ) {
-		http_free( http_hdr );
-		stream->streaming_ctrl->data = NULL;
-	}
-
-	stream->streaming_ctrl->streaming_read = nop_streaming_read;
-	stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
-	stream->streaming_ctrl->prebuffer_size = 64*1024; // 64 KBytes
-	stream->streaming_ctrl->buffering = 1;
-	stream->streaming_ctrl->status = streaming_playing_e;
-	return 0;
-}
-
-int
-pnm_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) {
-	return pnm_read(stream_ctrl->data, buffer, size);
-}
-
-
-int
-pnm_streaming_start( stream_t *stream ) {
-	int fd;
-	pnm_t *pnm;
-	if( stream==NULL ) return -1;
-
-	fd = connect2Server( stream->streaming_ctrl->url->hostname,
-	    stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 7070,1 );
-	printf("PNM:// fd=%d\n",fd);
-	if(fd<0) return -1;
-	
-	pnm = pnm_connect(fd,stream->streaming_ctrl->url->file);
-	if(!pnm) return -2;
-
-	stream->fd=fd;
-	stream->streaming_ctrl->data=pnm;
-
-	stream->streaming_ctrl->streaming_read = pnm_streaming_read;
-//	stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
-	stream->streaming_ctrl->prebuffer_size = 8*1024;  // 8 KBytes
-	stream->streaming_ctrl->buffering = 1;
-	stream->streaming_ctrl->status = streaming_playing_e;
-	return 0;
-}
-
-
-int
-realrtsp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) {
-	return rtsp_session_read(stream_ctrl->data, buffer, size);
-}
-
-
-int
-realrtsp_streaming_start( stream_t *stream ) {
-	int fd;
-	rtsp_session_t *rtsp;
-	char *mrl;
-	char *file;
-	int port;
-	int redirected, temp;
-	if( stream==NULL ) return -1;
-	
-	temp = 5; // counter so we don't get caught in infinite redirections (you never know)
-	
-	do {
-	
-		redirected = 0;
-
-		fd = connect2Server( stream->streaming_ctrl->url->hostname,
-			port = (stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 554),1 );
-		if(fd<0 && !stream->streaming_ctrl->url->port)
-			fd = connect2Server( stream->streaming_ctrl->url->hostname,
-				port = 7070, 1 );
-		if(fd<0) return -1;
-		
-		file = stream->streaming_ctrl->url->file;
-		if (file[0] == '/')
-		    file++;
-		mrl = malloc(sizeof(char)*(strlen(stream->streaming_ctrl->url->hostname)+strlen(file)+16));
-		sprintf(mrl,"rtsp://%s:%i/%s",stream->streaming_ctrl->url->hostname,port,file);
-		rtsp = rtsp_session_start(fd,&mrl, file,
-			stream->streaming_ctrl->url->hostname, port, &redirected);
-
-		if ( redirected == 1 ) {
-			url_free(stream->streaming_ctrl->url);
-			stream->streaming_ctrl->url = url_new(mrl);
-			closesocket(fd);
-		}
-
-		free(mrl);
-		temp--;
-
-	} while( (redirected != 0) && (temp > 0) );	
-
-	if(!rtsp) return -1;
-
-	stream->fd=fd;
-	stream->streaming_ctrl->data=rtsp;
-
-	stream->streaming_ctrl->streaming_read = realrtsp_streaming_read;
-//	stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
-	stream->streaming_ctrl->prebuffer_size = 128*1024;  // 8 KBytes
-	stream->streaming_ctrl->buffering = 1;
-	stream->streaming_ctrl->status = streaming_playing_e;
-	return 0;
+int fixup_network_stream_cache(stream_t *stream) {
+  if(stream->streaming_ctrl->buffering) {
+    if(stream_cache_size<0) {
+      // cache option not set, will use our computed value.
+      // buffer in KBytes, *5 because the prefill is 20% of the buffer.
+      stream_cache_size = (stream->streaming_ctrl->prebuffer_size/1024)*5;
+      if( stream_cache_size<64 ) stream_cache_size = 64;	// 16KBytes min buffer
+    }
+    mp_msg(MSGT_NETWORK,MSGL_INFO,"Cache size set to %d KBytes\n", stream_cache_size);
+  }
 }
 
 
-// Start listening on a UDP port. If multicast, join the group.
-static int
-rtp_open_socket( URL_t *url ) {
-	int socket_server_fd, rxsockbufsz;
-	int err, err_len;
-	fd_set set;
-	struct sockaddr_in server_address;
-	struct ip_mreq mcast;
-        struct timeval tv;
-	struct hostent *hp;
-
-	mp_msg(MSGT_NETWORK,MSGL_V,"Listening for traffic on %s:%d ...\n", url->hostname, url->port );
-
-	socket_server_fd = socket(AF_INET, SOCK_DGRAM, 0);
-//	fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK );
-	if( socket_server_fd==-1 ) {
-		mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create socket\n");
-		return -1;
-	}
-
-	if( isalpha(url->hostname[0]) ) {
-#ifndef HAVE_WINSOCK2
-		hp =(struct hostent*)gethostbyname( url->hostname );
-		if( hp==NULL ) {
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname);
-			return -1;
-		}
-		memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length );
-#else
-		server_address.sin_addr.s_addr = htonl(INADDR_ANY);
-#endif
-	} else {
-#ifndef HAVE_WINSOCK2
-#ifdef USE_ATON
-		inet_aton(url->hostname, &server_address.sin_addr);
-#else
-		inet_pton(AF_INET, url->hostname, &server_address.sin_addr);
-#endif
-#else
-		server_address.sin_addr.s_addr = htonl(INADDR_ANY);
-#endif
-	}
-	server_address.sin_family=AF_INET;
-	server_address.sin_port=htons(url->port);
-
-	if( bind( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) {
-#ifndef HAVE_WINSOCK2
-		if( errno!=EINPROGRESS ) {
-#else
-		if( WSAGetLastError() != WSAEINPROGRESS ) {
-#endif
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to connect to server\n");
-			closesocket(socket_server_fd);
-			return -1;
-		}
-	}
-	
-#ifdef HAVE_WINSOCK2
-	if (isalpha(url->hostname[0])) {
-		hp =(struct hostent*)gethostbyname( url->hostname );
-		if( hp==NULL ) {
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname);
-			return -1;
-		}
-		memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length );
-	} else {
-		unsigned int addr = inet_addr(url->hostname);
-		memcpy( (void*)&server_address.sin_addr, (void*)&addr, sizeof(addr) );
-	}
-#endif
-
-	// Increase the socket rx buffer size to maximum -- this is UDP
-	rxsockbufsz = 240 * 1024;
-	if( setsockopt( socket_server_fd, SOL_SOCKET, SO_RCVBUF, &rxsockbufsz, sizeof(rxsockbufsz))) {
-		mp_msg(MSGT_NETWORK,MSGL_ERR,"Couldn't set receive socket buffer size\n");
-	}
-
-	if((ntohl(server_address.sin_addr.s_addr) >> 28) == 0xe) {
-		mcast.imr_multiaddr.s_addr = server_address.sin_addr.s_addr;
-		//mcast.imr_interface.s_addr = inet_addr("10.1.1.2");
-		mcast.imr_interface.s_addr = 0;
-		if( setsockopt( socket_server_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))) {
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)\n");
-			return -1;
-		}
-	}
-
-	tv.tv_sec = 0;
-	tv.tv_usec = (1 * 1000000);	// 1 second timeout
-	FD_ZERO( &set );
-	FD_SET( socket_server_fd, &set );
-	if( select(socket_server_fd+1, &set, NULL, NULL, &tv)>0 ) {
-        //if( select(socket_server_fd+1, &set, NULL, NULL, NULL)>0 ) {
-		err_len = sizeof( err );
-		getsockopt( socket_server_fd, SOL_SOCKET, SO_ERROR, &err, &err_len );
-		if( err ) {
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"Timeout! No data from host %s\n", url->hostname );
-			mp_msg(MSGT_NETWORK,MSGL_DBG2,"Socket error: %d\n", err );
-			closesocket(socket_server_fd);
-			return -1;
-		}
-	}
-	return socket_server_fd;
-}
-
-static int
-rtp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl ) {
-    return read_rtp_from_server( fd, buffer, size );
-}
-
-static int
-rtp_streaming_start( stream_t *stream, int raw_udp ) {
-	streaming_ctrl_t *streaming_ctrl;
-	int fd;
-
-	if( stream==NULL ) return -1;
-	streaming_ctrl = stream->streaming_ctrl;
-	fd = stream->fd;
-	
-	if( fd<0 ) {
-		fd = rtp_open_socket( (streaming_ctrl->url) ); 
-		if( fd<0 ) return -1;
-		stream->fd = fd;
-	}
-
-	if(raw_udp)
-		streaming_ctrl->streaming_read = nop_streaming_read;
-	else
-		streaming_ctrl->streaming_read = rtp_streaming_read;
-	streaming_ctrl->streaming_seek = nop_streaming_seek;
-	streaming_ctrl->prebuffer_size = 64*1024;	// 64 KBytes	
-	streaming_ctrl->buffering = 0;
-	streaming_ctrl->status = streaming_playing_e;
-	return 0;
-}
-
-int
-streaming_start(stream_t *stream, int *demuxer_type, URL_t *url) {
-	int ret;
-	if( stream==NULL ) return -1;
-
-	stream->streaming_ctrl = streaming_ctrl_new();
-	if( stream->streaming_ctrl==NULL ) {
-		return -1;
-	}
-	stream->streaming_ctrl->url = check4proxies( url );
-
-        if (*demuxer_type != DEMUXER_TYPE_PLAYLIST){ 
-	ret = autodetectProtocol( stream->streaming_ctrl, &stream->fd, demuxer_type );
-        } else {
-	  ret=0;
-	}
-
-	if( ret<0 ) {
-		return -1;
-	}
-	if( ret==1 ) {
-		stream->flags |= STREAM_SEEK;
-		stream->seek = http_seek;
-	}
-
-	ret = -1;
-	
-	// Get the bandwidth available
-	stream->streaming_ctrl->bandwidth = network_bandwidth;
-	
-	// For RTP streams, we usually don't know the stream type until we open it.
-	if( !strcasecmp( stream->streaming_ctrl->url->protocol, "rtp")) {
-		if(stream->fd >= 0) {
-			if(closesocket(stream->fd) < 0)
-				mp_msg(MSGT_NETWORK,MSGL_ERR,"streaming_start : Closing socket %d failed %s\n",stream->fd,strerror(errno));
-		}
-		stream->fd = -1;
-		ret = rtp_streaming_start( stream, 0);
-	} else
-
-	if( !strcasecmp( stream->streaming_ctrl->url->protocol, "pnm")) {
-		stream->fd = -1;
-		ret = pnm_streaming_start( stream );
-		if (ret == -1) {
-		    mp_msg(MSGT_NETWORK,MSGL_INFO,"Can't connect with pnm, retrying with http.\n");
-		    goto stream_switch;
-		}
-	} else
-	
-	if( (!strcasecmp( stream->streaming_ctrl->url->protocol, "rtsp")) &&
-			(*demuxer_type == DEMUXER_TYPE_REAL)) {
-		stream->fd = -1;
-		if ((ret = realrtsp_streaming_start( stream )) < 0) {
-		    mp_msg(MSGT_NETWORK,MSGL_INFO,"Not a Realmedia rtsp url. Trying standard rtsp protocol.\n");
-#ifdef STREAMING_LIVE_DOT_COM
-		    *demuxer_type =  DEMUXER_TYPE_RTP;
-		    goto stream_switch;
-#else
-		    mp_msg(MSGT_NETWORK,MSGL_ERR,"RTSP support requires the \"LIVE.COM Streaming Media\" libraries!\n");
-		    return -1;
-#endif
-		}
-	} else if(!strcasecmp( stream->streaming_ctrl->url->protocol, "udp")) {
-		stream->fd = -1;
-		ret = rtp_streaming_start(stream, 1);
-		if(ret<0) {
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"rtp_streaming_start(udp) failed\n");
-			return -1;
-		}
-		*demuxer_type =  DEMUXER_TYPE_UNKNOWN;
-	} else
-
-	// For connection-oriented streams, we can usually determine the streaming type.
-stream_switch:
-	switch( *demuxer_type ) {
-		case DEMUXER_TYPE_ASF:
-			// Send the appropriate HTTP request
-			// Need to filter the network stream.
-			// ASF raw stream is encapsulated.
-			// It can also be a playlist (redirector)
-			// so we need to pass demuxer_type too
-			ret = asf_streaming_start( stream, demuxer_type );
-			if( ret<0 ) {
-                                //sometimes a file is just on a webserver and it is not streamed.
-				//try loading them default method as last resort for http protocol
-                                if ( !strcasecmp(stream->streaming_ctrl->url->protocol, "http") ) {
-                                mp_msg(MSGT_NETWORK,MSGL_STATUS,"Trying default streaming for http protocol\n ");
-                                //reset stream
-                                close(stream->fd);
-		                stream->fd=-1;
-                                ret=nop_streaming_start(stream);
-                                }
-
-                         if (ret<0) {
-				mp_msg(MSGT_NETWORK,MSGL_ERR,"asf_streaming_start failed\n");
-                                mp_msg(MSGT_NETWORK,MSGL_STATUS,"Check if this is a playlist which requires -playlist option\nExample: mplayer -playlist <url>\n");
-                               }
-			}
-			break;
-#ifdef STREAMING_LIVE_DOT_COM
-		case DEMUXER_TYPE_RTP:
-			// RTSP/RTP streaming is handled separately:
-			ret = rtsp_streaming_start( stream );
-			if( ret<0 ) {
-				mp_msg(MSGT_NETWORK,MSGL_ERR,"rtsp_streaming_start failed\n");
-			}
-			break;
-#endif
-		case DEMUXER_TYPE_MPEG_ES:
-		case DEMUXER_TYPE_MPEG_PS:
-		case DEMUXER_TYPE_AVI:
-		case DEMUXER_TYPE_MOV:
-		case DEMUXER_TYPE_VIVO:
-		case DEMUXER_TYPE_FLI:
-		case DEMUXER_TYPE_REAL:
-		case DEMUXER_TYPE_Y4M:
-		case DEMUXER_TYPE_FILM:
-		case DEMUXER_TYPE_ROQ:
-		case DEMUXER_TYPE_AUDIO:
-		case DEMUXER_TYPE_OGG:
-		case DEMUXER_TYPE_PLAYLIST:
-		case DEMUXER_TYPE_UNKNOWN:
-		case DEMUXER_TYPE_NSV: 
-			// Generic start, doesn't need to filter
-			// the network stream, it's a raw stream
-			ret = nop_streaming_start( stream );
-			if( ret<0 ) {
-				mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n");
-			}
-			break;
-		default:
-			mp_msg(MSGT_NETWORK,MSGL_ERR,"Unable to detect the streaming type\n");
-			ret = -1;
-	}
-
-	if( ret<0 ) {
-		streaming_ctrl_free( stream->streaming_ctrl );
-		stream->streaming_ctrl = NULL;
-	} else if( stream->streaming_ctrl->buffering ) {
-		if(stream_cache_size<0) {
-			// cache option not set, will use our computed value.
-			// buffer in KBytes, *5 because the prefill is 20% of the buffer.
-			stream_cache_size = (stream->streaming_ctrl->prebuffer_size/1024)*5;
-			if( stream_cache_size<64 ) stream_cache_size = 64;	// 16KBytes min buffer
-		}
-		mp_msg(MSGT_NETWORK,MSGL_INFO,"Cache size set to %d KBytes\n", stream_cache_size);
-	}
-
-	return ret;
-}
-
 int
 streaming_stop( stream_t *stream ) {
 	stream->streaming_ctrl->status = streaming_stopped_e;
--- a/libmpdemux/network.h	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/network.h	Sun May 29 12:54:00 2005 +0000
@@ -25,6 +25,11 @@
 
 #define BUFFER_SIZE		2048
 
+typedef struct {
+	char *mime_type;
+	int demuxer_type;
+} mime_struct_t;
+
 typedef enum {
 	streaming_stopped_e,
 	streaming_playing_e
@@ -45,11 +50,12 @@
 } streaming_ctrl_t;
 
 //int streaming_start( stream_t *stream, int *demuxer_type, URL_t *url );
-
+streaming_ctrl_t *streaming_ctrl_new();
 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 );
 int nop_streaming_seek( int fd, off_t pos, streaming_ctrl_t *stream_ctrl );
+void streaming_ctrl_free( streaming_ctrl_t *streaming_ctrl );
 
 int connect2Server(char *host, int port,int verb);
 
@@ -57,5 +63,6 @@
 HTTP_header_t *http_read_response(int fd);
 
 int http_authenticate(HTTP_header_t *http_hdr, URL_t *url, int *auth_retry);
+URL_t* check4proxies(URL_t *url);
 
 #endif
--- a/libmpdemux/open.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/open.c	Sun May 29 12:54:00 2005 +0000
@@ -20,15 +20,6 @@
 #include "demuxer.h"
 #include "mf.h"
 
-#ifdef MPLAYER_NETWORK
-#include "url.h"
-#include "network.h"
-extern int streaming_start( stream_t *stream, int *demuxer_type, URL_t *url);
-#ifdef STREAMING_LIVE_DOT_COM
-#include "demux_rtp.h"
-#endif
-static URL_t* url;
-#endif
 
 /// We keep these 2 for the gui atm, but they will be removed.
 int vcd_track=0;
@@ -37,10 +28,6 @@
 // Open a new stream  (stdin/file/vcd/url)
 
 stream_t* open_stream(char* filename,char** options, int* file_format){
-stream_t* stream=NULL;
-int f=-1;
-off_t len;
-
   // Check if playlist or unknown 
   if (*file_format != DEMUXER_TYPE_PLAYLIST){
     *file_format=DEMUXER_TYPE_UNKNOWN;
@@ -51,59 +38,6 @@
    return NULL;
 }
 
-
-#ifdef MPLAYER_NETWORK
-#ifdef STREAMING_LIVE_DOT_COM
-  // Check for a SDP file:
-  if (strncmp("sdp://",filename,6) == 0) {
-       filename += 6;
-#if defined(__CYGWIN__) || defined(__MINGW32__)
-       f=open(filename,O_RDONLY|O_BINARY);
-#else
-       f=open(filename,O_RDONLY);
-#endif
-       if(f<0){ mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_FileNotFound,filename);return NULL; }
-
-       len=lseek(f,0,SEEK_END); lseek(f,0,SEEK_SET);
-       if (len == -1)
-           return NULL;
-
-#ifdef _LARGEFILE_SOURCE
-	 mp_msg(MSGT_OPEN,MSGL_V,"File size is %lld bytes\n", (long long)len);
-#else
-	 mp_msg(MSGT_OPEN,MSGL_V,"File size is %u bytes\n", (unsigned int)len);
-#endif
-	 return stream_open_sdp(f, len, file_format);
-  }
-#endif
-
-  // FIXME: to avoid nonsense error messages...
-  if (strncmp("tv://", filename, 5) && strncmp("mf://", filename, 5) &&
-    strncmp("vcd://", filename, 6) && strncmp("dvb://", filename, 6) &&
-    strncmp("cdda://", filename, 7) && strncmp("cddb://", filename, 7) &&
-    strncmp("mpst://", filename, 7) && strncmp("tivo://", filename, 7) &&
-    strncmp("file://", filename, 7) && strncmp("cue://", filename, 6) &&
-    strncmp("ftp://", filename, 6) && strncmp("smb://", filename, 6) && 
-    strncmp("dvd://", filename, 6) && strncmp("dvdnav://", filename, 9) &&
-    strstr(filename, "://")) {
-     url = url_new(filename);
-    }
-  if(url) {
-        stream=new_stream(f,STREAMTYPE_STREAM);
-	if( streaming_start( stream, file_format, url )<0){
-          mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_UnableOpenURL, filename);
-	  url_free(url);
-	  url = NULL;
-	  return NULL;
-	} else {
-        mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_ConnToServer, url->hostname );
-	url_free(url);
-	url = NULL;
-	return stream;
-	}
-  }
-#endif
-
 //============ Open STDIN or plain FILE ============
 
   return open_stream_full(filename,STREAM_READ,options,file_format);
--- a/libmpdemux/pnm.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/pnm.c	Sun May 29 12:54:00 2005 +0000
@@ -33,6 +33,10 @@
 #include <stdlib.h>
 #include <sys/time.h>
 #include <inttypes.h>
+#include "stream.h"
+#include "demuxer.h"
+#include "help_mp.h"
+
 
 #include "config.h"
 #ifndef HAVE_WINSOCK2
@@ -47,6 +51,8 @@
 #include "pnm.h"
 //#include "libreal/rmff.h"
 
+extern int network_bandwidth;
+
 #define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
         (((long)(unsigned char)(ch3)       ) | \
         ( (long)(unsigned char)(ch2) << 8  ) | \
@@ -836,22 +842,79 @@
   this->recv_read += to_copy;
 
 #ifdef LOG
-  printf ("input_pnm: %d bytes provided\n", len);
+  mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: %d bytes provided\n", len);
 #endif
 
   return len;
 }
 
-int pnm_peek_header (pnm_t *this, char *data) {
+static int pnm_peek_header (pnm_t *this, char *data) {
 
   memcpy (data, this->header, this->header_len);
   return this->header_len;
 }
 
-void pnm_close(pnm_t *p) {
+static void pnm_close(pnm_t *p) {
 
   if (p->s >= 0) closesocket(p->s);
   free(p->path);
   free(p);
 }
 
+static int pnm_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) {
+	return pnm_read(stream_ctrl->data, buffer, size);
+}
+
+static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
+  int fd;
+  pnm_t *pnm;
+  URL_t *url;
+
+  mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_PNM, URL: %s\n", stream->url);
+  stream->streaming_ctrl = streaming_ctrl_new();
+  if(stream->streaming_ctrl==NULL) {
+    return STREAM_ERROR;
+  }
+  stream->streaming_ctrl->bandwidth = network_bandwidth;
+  url = url_new(stream->url);
+  stream->streaming_ctrl->url = check4proxies(url);
+  //url_free(url);
+
+  fd = connect2Server( stream->streaming_ctrl->url->hostname,
+    stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 7070,1 );
+  
+  if(fd<0)
+    goto fail;
+
+  pnm = pnm_connect(fd,stream->streaming_ctrl->url->file);
+  if(!pnm) 
+    goto fail;
+  stream->type = STREAMTYPE_STREAM;
+  stream->fd=fd;
+  stream->streaming_ctrl->data=pnm;
+  stream->streaming_ctrl->streaming_read = pnm_streaming_read;
+  //stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
+  stream->streaming_ctrl->prebuffer_size = 8*1024;  // 8 KBytes
+  stream->streaming_ctrl->buffering = 1;
+  stream->streaming_ctrl->status = streaming_playing_e;
+  *file_format = DEMUXER_TYPE_REAL;
+  fixup_network_stream_cache(stream);
+  return STREAM_OK;
+
+fail:
+  streaming_ctrl_free(stream->streaming_ctrl);
+  stream->streaming_ctrl = NULL;
+  return STREAM_UNSUPORTED;
+}
+
+
+stream_info_t stream_info_pnm = {
+  "RealNetworks pnm",
+  "pnm",
+  "Arpi, xine team",
+  "ported from xine",
+  open_s,
+  {"pnm", NULL},	//pnm as fallback
+  NULL,
+  0 // Urls are an option string
+};
--- a/libmpdemux/pnm.h	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/pnm.h	Sun May 29 12:54:00 2005 +0000
@@ -32,12 +32,12 @@
 
 typedef struct pnm_s pnm_t;
 
-pnm_t*   pnm_connect (int fd,char *url);
+//pnm_t*   pnm_connect (int fd,char *url);
 
-int      pnm_read (pnm_t *this, char *data, int len);
-void     pnm_close (pnm_t *this);
+//int      pnm_read (pnm_t *this, char *data, int len);
+//void     pnm_close (pnm_t *this);
 
-int      pnm_peek_header (pnm_t *this, char *data);
+//int      pnm_peek_header (pnm_t *this, char *data);
 
 #endif
 
--- a/libmpdemux/realrtsp/rtsp.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/realrtsp/rtsp.c	Sun May 29 12:54:00 2005 +0000
@@ -49,6 +49,9 @@
 #include <inttypes.h>
 
 #include "rtsp.h"
+#include "../stream.h"
+#include "../demuxer.h"
+#include "rtsp_session.h"
 
 /*
 #define LOG
@@ -58,6 +61,7 @@
 #define HEADER_SIZE 1024
 #define MAX_FIELDS 256
 
+extern int network_bandwidth;
 struct rtsp_s {
 
   int           s;
@@ -839,3 +843,96 @@
     answer++;
   }
 }
+
+static int realrtsp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) {
+  return rtsp_session_read(stream_ctrl->data, buffer, size);
+}
+
+
+static int realrtsp_streaming_start( stream_t *stream ) {
+  int fd;
+  rtsp_session_t *rtsp;
+  char *mrl;
+  char *file;
+  int port;
+  int redirected, temp;
+  if( stream==NULL ) return -1;
+
+  temp = 5; // counter so we don't get caught in infinite redirections (you never know)
+
+  do {
+    redirected = 0;
+
+    fd = connect2Server( stream->streaming_ctrl->url->hostname,
+         port = (stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 554),1 );
+    if(fd<0 && !stream->streaming_ctrl->url->port)
+      fd = connect2Server(stream->streaming_ctrl->url->hostname, port = 7070, 1);
+    if(fd<0) return -1;
+
+    file = stream->streaming_ctrl->url->file;
+    if (file[0] == '/')
+      file++;
+    mrl = malloc(sizeof(char)*(strlen(stream->streaming_ctrl->url->hostname)+strlen(file)+16));
+    sprintf(mrl,"rtsp://%s:%i/%s",stream->streaming_ctrl->url->hostname,port,file);
+    rtsp = rtsp_session_start(fd,&mrl, file, stream->streaming_ctrl->url->hostname, port, &redirected);
+
+    if( redirected == 1) {
+      url_free(stream->streaming_ctrl->url);
+      stream->streaming_ctrl->url = url_new(mrl);
+      closesocket(fd);
+    }
+
+    free(mrl);
+    temp--;
+  } while( (redirected != 0) && (temp > 0) );	
+
+  if(!rtsp) return -1;
+
+  stream->fd=fd;
+  stream->streaming_ctrl->data=rtsp;
+
+  stream->streaming_ctrl->streaming_read = realrtsp_streaming_read;
+  //stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
+  stream->streaming_ctrl->prebuffer_size = 128*1024;  // 8 KBytes
+  stream->streaming_ctrl->buffering = 1;
+  stream->streaming_ctrl->status = streaming_playing_e;
+  return 0;
+}
+
+
+static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
+  URL_t *url;
+
+  mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_RTSP, URL: %s\n", stream->url);
+  stream->streaming_ctrl = streaming_ctrl_new();
+  if( stream->streaming_ctrl==NULL )
+    return STREAM_ERROR;
+
+  stream->streaming_ctrl->bandwidth = network_bandwidth;
+  url = url_new(stream->url);
+  stream->streaming_ctrl->url = check4proxies(url);
+  //url_free(url);
+
+  stream->fd = -1;
+  if(realrtsp_streaming_start( stream ) < 0) {
+    streaming_ctrl_free(stream->streaming_ctrl);
+    stream->streaming_ctrl = NULL;
+    return STREAM_UNSUPORTED;
+  }
+
+  fixup_network_stream_cache(stream);
+  stream->type = STREAMTYPE_STREAM;
+  return STREAM_OK;
+}
+
+
+stream_info_t stream_info_rtsp = {
+  "RealNetworks rtsp streaming",
+  "realrtsp",
+  "Roberto Togni, xine team",
+  "ported from xine",
+  open_s,
+  {"rtsp", NULL},
+  NULL,
+  0 // Urls are an option string
+};
--- a/libmpdemux/rtp.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/rtp.c	Sun May 29 12:54:00 2005 +0000
@@ -11,21 +11,180 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#include <ctype.h>
 #include "config.h"
 #ifndef HAVE_WINSOCK2
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
+#define closesocket close
 #else
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #endif
+#include <errno.h>
+#include "stream.h"
 
 /* MPEG-2 TS RTP stack */
 
 #define DEBUG        1
 #include "rtp.h"
 
+extern int network_bandwidth;
+
+int read_rtp_from_server(int fd, char *buffer, int length) {
+	struct rtpheader rh;
+	char *data;
+	int len;
+	static int got_first = 0;
+	static unsigned short sequence;
+
+	if( buffer==NULL || length<0 ) return -1;
+
+	getrtp2(fd, &rh, &data, &len);
+	if( got_first && rh.b.sequence != (unsigned short)(sequence+1) )
+		mp_msg(MSGT_NETWORK,MSGL_ERR,"RTP packet sequence error!  Expected: %d, received: %d\n", 
+			sequence+1, rh.b.sequence);
+	got_first = 1;
+	sequence = rh.b.sequence;
+	memcpy(buffer, data, len);
+	return(len);
+}
+
+
+// Start listening on a UDP port. If multicast, join the group.
+static int rtp_open_socket( URL_t *url ) {
+	int socket_server_fd, rxsockbufsz;
+	int err, err_len;
+	fd_set set;
+	struct sockaddr_in server_address;
+	struct ip_mreq mcast;
+        struct timeval tv;
+	struct hostent *hp;
+
+	mp_msg(MSGT_NETWORK,MSGL_V,"Listening for traffic on %s:%d ...\n", url->hostname, url->port );
+
+	socket_server_fd = socket(AF_INET, SOCK_DGRAM, 0);
+//	fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK );
+	if( socket_server_fd==-1 ) {
+		mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create socket\n");
+		return -1;
+	}
+
+	if( isalpha(url->hostname[0]) ) {
+#ifndef HAVE_WINSOCK2
+		hp =(struct hostent*)gethostbyname( url->hostname );
+		if( hp==NULL ) {
+			mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname);
+			return -1;
+		}
+		memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length );
+#else
+		server_address.sin_addr.s_addr = htonl(INADDR_ANY);
+#endif
+	} else {
+#ifndef HAVE_WINSOCK2
+#ifdef USE_ATON
+		inet_aton(url->hostname, &server_address.sin_addr);
+#else
+		inet_pton(AF_INET, url->hostname, &server_address.sin_addr);
+#endif
+#else
+		server_address.sin_addr.s_addr = htonl(INADDR_ANY);
+#endif
+	}
+	server_address.sin_family=AF_INET;
+	server_address.sin_port=htons(url->port);
+
+	if( bind( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) {
+#ifndef HAVE_WINSOCK2
+		if( errno!=EINPROGRESS ) {
+#else
+		if( WSAGetLastError() != WSAEINPROGRESS ) {
+#endif
+			mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to connect to server\n");
+			closesocket(socket_server_fd);
+			return -1;
+		}
+	}
+	
+#ifdef HAVE_WINSOCK2
+	if (isalpha(url->hostname[0])) {
+		hp =(struct hostent*)gethostbyname( url->hostname );
+		if( hp==NULL ) {
+			mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname);
+			return -1;
+		}
+		memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length );
+	} else {
+		unsigned int addr = inet_addr(url->hostname);
+		memcpy( (void*)&server_address.sin_addr, (void*)&addr, sizeof(addr) );
+	}
+#endif
+
+	// Increase the socket rx buffer size to maximum -- this is UDP
+	rxsockbufsz = 240 * 1024;
+	if( setsockopt( socket_server_fd, SOL_SOCKET, SO_RCVBUF, &rxsockbufsz, sizeof(rxsockbufsz))) {
+		mp_msg(MSGT_NETWORK,MSGL_ERR,"Couldn't set receive socket buffer size\n");
+	}
+
+	if((ntohl(server_address.sin_addr.s_addr) >> 28) == 0xe) {
+		mcast.imr_multiaddr.s_addr = server_address.sin_addr.s_addr;
+		//mcast.imr_interface.s_addr = inet_addr("10.1.1.2");
+		mcast.imr_interface.s_addr = 0;
+		if( setsockopt( socket_server_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))) {
+			mp_msg(MSGT_NETWORK,MSGL_ERR,"IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)\n");
+			return -1;
+		}
+	}
+
+	tv.tv_sec = 0;
+	tv.tv_usec = (1 * 1000000);	// 1 second timeout
+	FD_ZERO( &set );
+	FD_SET( socket_server_fd, &set );
+	if( select(socket_server_fd+1, &set, NULL, NULL, &tv)>0 ) {
+        //if( select(socket_server_fd+1, &set, NULL, NULL, NULL)>0 ) {
+		err_len = sizeof( err );
+		getsockopt( socket_server_fd, SOL_SOCKET, SO_ERROR, &err, &err_len );
+		if( err ) {
+			mp_msg(MSGT_NETWORK,MSGL_ERR,"Timeout! No data from host %s\n", url->hostname );
+			mp_msg(MSGT_NETWORK,MSGL_DBG2,"Socket error: %d\n", err );
+			closesocket(socket_server_fd);
+			return -1;
+		}
+	}
+	return socket_server_fd;
+}
+
+static int rtp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl ) {
+	return read_rtp_from_server( fd, buffer, size );
+}
+
+static int rtp_streaming_start( stream_t *stream, int raw_udp ) {
+	streaming_ctrl_t *streaming_ctrl;
+	int fd;
+
+	if( stream==NULL ) return -1;
+	streaming_ctrl = stream->streaming_ctrl;
+	fd = stream->fd;
+	
+	if( fd<0 ) {
+		fd = rtp_open_socket( (streaming_ctrl->url) ); 
+		if( fd<0 ) return -1;
+		stream->fd = fd;
+	}
+
+	if(raw_udp)
+		streaming_ctrl->streaming_read = nop_streaming_read;
+	else
+		streaming_ctrl->streaming_read = rtp_streaming_read;
+	streaming_ctrl->streaming_seek = nop_streaming_seek;
+	streaming_ctrl->prebuffer_size = 64*1024;	// 64 KBytes	
+	streaming_ctrl->buffering = 0;
+	streaming_ctrl->status = streaming_playing_e;
+	return 0;
+}
+
 
 int getrtp2(int fd, struct rtpheader *rh, char** data, int* lengthData) {
   static char buf[1600];
@@ -68,3 +227,51 @@
 }
 
 
+static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
+  URL_t *url;
+  int udp = 0;
+
+  mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_RTP, URL: %s\n", stream->url);
+  stream->streaming_ctrl = streaming_ctrl_new();
+  if( stream->streaming_ctrl==NULL ) {
+    return STREAM_ERROR;
+  }
+  stream->streaming_ctrl->bandwidth = network_bandwidth;
+  url = url_new(stream->url);
+  stream->streaming_ctrl->url = check4proxies(url);
+
+  if( url->port==0 ) {
+    mp_msg(MSGT_NETWORK,MSGL_ERR,"You must enter a port number for RTP and UDP streams!\n");
+    goto fail;
+  }
+  if(!strncmp(stream->url, "udp", 3))
+    udp = 1;
+
+  if(rtp_streaming_start(stream, udp) < 0) {
+    mp_msg(MSGT_NETWORK,MSGL_ERR,"rtp_streaming_start(rtp) failed\n");
+    goto fail;
+  }
+
+  stream->type = STREAMTYPE_STREAM;
+  fixup_network_stream_cache(stream);
+  return STREAM_OK;
+
+fail:
+  streaming_ctrl_free( stream->streaming_ctrl );
+  stream->streaming_ctrl = NULL;
+  return STREAM_UNSUPORTED;
+}
+
+
+stream_info_t stream_info_rtp_udp = {
+  "mpeg rtp and upd streaming",
+  "rtp and udp",
+  "Dave Chapman",
+  "native rtp support",
+  open_s,
+  {"rtp", "udp", NULL},
+  NULL,
+  0 // Urls are an option string
+};
+
+
--- a/libmpdemux/stream.c	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/stream.c	Sun May 29 12:54:00 2005 +0000
@@ -45,6 +45,12 @@
 #endif
 #ifdef MPLAYER_NETWORK
 extern stream_info_t stream_info_netstream;
+extern stream_info_t stream_info_pnm;
+extern stream_info_t stream_info_asf;
+extern stream_info_t stream_info_rtsp;
+extern stream_info_t stream_info_rtp_udp;
+extern stream_info_t stream_info_http1;
+extern stream_info_t stream_info_http2;
 #endif
 #ifdef HAS_DVBIN_SUPPORT
 extern stream_info_t stream_info_dvb;
@@ -61,6 +67,10 @@
 #ifdef LIBSMBCLIENT
 extern stream_info_t stream_info_smb;
 #endif
+#ifdef STREAMING_LIVE_DOT_COM
+extern stream_info_t stream_info_sdp;
+extern stream_info_t stream_info_rtsp_sip;
+#endif;
 
 extern stream_info_t stream_info_cue;
 extern stream_info_t stream_info_null;
@@ -76,6 +86,16 @@
 #endif
 #ifdef MPLAYER_NETWORK
   &stream_info_netstream,
+  &stream_info_http1,
+  &stream_info_asf,
+  &stream_info_pnm,
+  &stream_info_rtsp,
+#ifdef STREAMING_LIVE_DOT_COM
+  &stream_info_sdp,
+  &stream_info_rtsp_sip,
+#endif
+  &stream_info_rtp_udp,
+  &stream_info_http2,
 #endif
 #ifdef HAS_DVBIN_SUPPORT
   &stream_info_dvb,
--- a/libmpdemux/stream.h	Sat May 28 21:28:40 2005 +0000
+++ b/libmpdemux/stream.h	Sun May 29 12:54:00 2005 +0000
@@ -20,6 +20,7 @@
 #define STREAMTYPE_VCDBINCUE 12      // vcd directly from bin/cue files
 #define STREAMTYPE_DVB 13
 #define STREAMTYPE_VSTREAM 14
+#define STREAMTYPE_SDP 15
 
 #define STREAM_BUFFER_SIZE 2048
 
@@ -110,6 +111,7 @@
 #define cache_stream_seek_long(x,y) stream_seek_long(x,y)
 #define stream_enable_cache(x,y,z,w) 1
 #endif
+int fixup_network_stream_cache(stream_t *stream);
 
 inline static int stream_read_char(stream_t *s){
   return (s->buf_pos<s->buf_len)?s->buffer[s->buf_pos++]:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpdemux/stream_livedotcom.c	Sun May 29 12:54:00 2005 +0000
@@ -0,0 +1,122 @@
+
+#include "config.h"
+
+#ifdef MPLAYER_NETWORK
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "stream.h"
+#include "network.h"
+#include "demuxer.h"
+#include "help_mp.h"
+
+#ifdef STREAMING_LIVE_DOT_COM
+
+extern int network_bandwidth;
+
+static int _rtsp_streaming_seek(int fd, off_t pos, streaming_ctrl_t* streaming_ctrl) {
+  return -1; // For now, we don't handle RTSP stream seeking
+}
+
+static int rtsp_streaming_start(stream_t* stream) {
+  stream->streaming_ctrl->streaming_seek = _rtsp_streaming_seek;
+  return 0;
+}
+
+
+static int open_live_rtsp_sip(stream_t *stream,int mode, void* opts, int* file_format) {
+  URL_t *url;
+
+  stream->streaming_ctrl = streaming_ctrl_new();
+  if( stream->streaming_ctrl==NULL ) {
+    return STREAM_ERROR;
+  }
+  stream->streaming_ctrl->bandwidth = network_bandwidth;
+  url = url_new(stream->url);
+  stream->streaming_ctrl->url = check4proxies(url);
+  //url_free(url);
+
+  mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_LIVEDOTCOM, URL: %s\n", stream->url);
+
+  if(rtsp_streaming_start(stream) < 0) {
+    mp_msg(MSGT_NETWORK,MSGL_ERR,"rtsp_streaming_start failed\n");
+    goto fail;
+  }
+
+  *file_format = DEMUXER_TYPE_RTP;
+  stream->type = STREAMTYPE_STREAM;
+  return STREAM_OK;
+
+fail:
+  streaming_ctrl_free( stream->streaming_ctrl );
+  stream->streaming_ctrl = NULL;
+  return STREAM_ERROR;
+}
+
+static int open_live_sdp(stream_t *stream,int mode, void* opts, int* file_format) {
+  FILE *f;
+  char *filename = stream->url;
+  off_t len;
+  char* sdpDescription;
+  ssize_t numBytesRead;
+
+  if(strncmp("sdp://",filename,6) == 0) {
+    filename += 6;
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+    f = open(filename,O_RDONLY|O_BINARY);
+#else
+    f = open(filename,O_RDONLY);
+#endif
+    if(f < 0) {
+      mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_FileNotFound,filename);
+      return STREAM_ERROR;
+    }
+
+    len=lseek(f,0,SEEK_END); 
+    lseek(f,0,SEEK_SET);
+    if(len == -1)
+      return STREAM_ERROR;
+
+    sdpDescription = (char*)malloc(len+1);
+    if(sdpDescription == NULL) return STREAM_ERROR;
+    numBytesRead = read(f, sdpDescription, len);
+    if(numBytesRead != len) {
+      free(sdpDescription);
+      return STREAM_ERROR;
+    }
+    sdpDescription[len] = '\0'; // to be safe
+    stream->priv = sdpDescription;
+
+    stream->type = STREAMTYPE_SDP;
+    *file_format = DEMUXER_TYPE_RTP;
+    return STREAM_OK;
+  }
+}
+
+
+stream_info_t stream_info_rtsp_sip = {
+  "Standard rtsp and sip",
+  "rtsp and sip",
+  "Ross Finlayson",
+  "uses lve.com streaming library",
+  open_live_rtsp_sip,
+  {"rtsp", "sip", NULL },
+  NULL,
+  0 // Urls are an option string
+};
+
+stream_info_t stream_info_sdp = {
+  "Sdp stream descriptor",
+  "sdp",
+  "Ross Finlayson",
+  "uses live.com streaming library",
+  open_live_sdp,
+  {"sdp", NULL },
+  NULL,
+  0 // Urls are an option string
+};
+
+#endif
+#endif