[MPlayer-cvslog] CVS: main/libmpdemux stream_livedotcom.c, NONE, 1.1 Makefile, 1.90, 1.91 asf_streaming.c, 1.53, 1.54 demux_rtp.cpp, 1.26, 1.27 demux_rtp.h, 1.3, 1.4 http.c, 1.20, 1.21 network.c, 1.111, 1.112 network.h, 1.19, 1.20 open.c, 1.108, 1.109 pnm.c, 1.12, 1.13 pnm.h, 1.1, 1.2 rtp.c, 1.8, 1.9 stream.c, 1.77, 1.78 stream.h, 1.70, 1.71

Nico Sabbi CVS syncmail at mplayerhq.hu
Sun May 29 14:54:02 CEST 2005


CVS change done by Nico Sabbi CVS

Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var2/tmp/cvs-serv192

Modified Files:
	Makefile asf_streaming.c demux_rtp.cpp demux_rtp.h http.c 
	network.c network.h open.c pnm.c pnm.h rtp.c stream.c stream.h 
Added Files:
	stream_livedotcom.c 
Log Message:
ported all network streams to the new API

--- NEW FILE ---

#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

Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/Makefile,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -r1.90 -r1.91
--- Makefile	19 May 2005 20:58:11 -0000	1.90
+++ Makefile	29 May 2005 12:53:59 -0000	1.91
@@ -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 

Index: asf_streaming.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/asf_streaming.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- asf_streaming.c	3 Feb 2005 20:13:44 -0000	1.53
+++ asf_streaming.c	29 May 2005 12:53:59 -0000	1.54
@@ -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
+};
+

Index: demux_rtp.cpp
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_rtp.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- demux_rtp.cpp	20 Jul 2004 02:12:08 -0000	1.26
+++ demux_rtp.cpp	29 May 2005 12:53:59 -0000	1.27
@@ -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:

Index: demux_rtp.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_rtp.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- demux_rtp.h	22 Feb 2004 06:19:24 -0000	1.3
+++ demux_rtp.h	29 May 2005 12:53:59 -0000	1.4
@@ -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);

Index: http.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/http.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- http.c	11 Jan 2005 17:49:59 -0000	1.20
+++ http.c	29 May 2005 12:53:59 -0000	1.21
@@ -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
+};

Index: network.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/network.c,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -r1.111 -r1.112
--- network.c	17 Apr 2005 20:33:25 -0000	1.111
+++ network.c	29 May 2005 12:53:59 -0000	1.112
@@ -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,468 +622,19 @@
 	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 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);
+  }
 }
 
-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;
-}
-
-
-// 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 ) {

Index: network.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/network.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- network.h	17 Feb 2004 12:30:45 -0000	1.19
+++ network.h	29 May 2005 12:53:59 -0000	1.20
@@ -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

Index: open.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/open.c,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -r1.108 -r1.109
--- open.c	19 May 2005 20:58:11 -0000	1.108
+++ open.c	29 May 2005 12:53:59 -0000	1.109
@@ -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);

Index: pnm.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/pnm.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- pnm.c	9 Apr 2005 14:50:36 -0000	1.12
+++ pnm.c	29 May 2005 12:53:59 -0000	1.13
@@ -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
+};

Index: pnm.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/pnm.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- pnm.h	26 Dec 2002 17:25:22 -0000	1.1
+++ pnm.h	29 May 2005 12:53:59 -0000	1.2
@@ -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
 

Index: rtp.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/rtp.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- rtp.c	16 Apr 2005 12:51:09 -0000	1.8
+++ rtp.c	29 May 2005 12:53:59 -0000	1.9
@@ -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
+};
+
+

Index: stream.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/stream.c,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -r1.77 -r1.78
--- stream.c	19 May 2005 20:58:11 -0000	1.77
+++ stream.c	29 May 2005 12:53:59 -0000	1.78
@@ -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,

Index: stream.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/stream.h,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- stream.h	27 Feb 2005 04:25:12 -0000	1.70
+++ stream.h	29 May 2005 12:53:59 -0000	1.71
@@ -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++]:




More information about the MPlayer-cvslog mailing list