[MPlayer-dev-eng] MMS support in mplayer begun

Derek J Witt djw at flinthills.com
Sat Dec 8 11:54:15 CET 2001


Bertrand Baudet wrote:
> 
> On Friday 07 December 2001 12:44 pm, you wrote:
> > Ok, That does make sense.  I have wiped out my changes and redownloaded
> > the cvs tree.  I will modify asf_streaming_start function accordingly
> > below.   I can make an enumerated type for mmsu, mmst, and then http in
> > that order to make a switch statement work.  I don't know enough about
> > UDP to do anything worthwhile there.  So, I will just make a stub for
> > UDP for the time being, or simply return -1.
> 
> Ok, do you want to it, or do you want me to do it, so you can grab
> it from CVS. In this way you will not have to patch mplayer. Then just
> send me your new files and I will have a look and test them.
> 

I've had a quite a few distractions in the last few days. I may not be
able to email any new files next week (jobhunting; just lost my job). 
This weekend is pretty much shot. I am probably going to stay away from
the computer to help myself relax. I will keep try to do something on my
end. I've almost managed to parse the server version number. I'm trying
to get used to multibyte characters. (such as the version number).  I
will send new files as they're done.
> 
> I don't quite understand. Do you mean that depending on the player version
> number, the wms will return a list of codec to download if no present
> localy, right?

Yeah, I found out that using NSPlayer/6.4.0.1112 for the player version,
pretty much all streams should work fine.  


I have included what I've done, thus far. This time, i didn't touch
asf_http_streaming_start(). In order to return the local hostname and
port, I had to include the standard networking headers in
asf_streaming.c. I think I should place those #include lines in asf.h
instead.
-- 
**  Derek J Witt                                              **
*   Email: mailto:djw at flinthills.com                           *
*   Home Page: http://www.flinthills.com/~djw/                 *
*** "...and on the eighth day, God met Bill Gates." - Unknown **
-------------- next part --------------
? libmpdemux/mmst.h
Index: libmpdemux/asf.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/asf.h,v
retrieving revision 1.9
diff -u -r1.9 asf.h
--- libmpdemux/asf.h	20 Nov 2001 22:17:16 -0000	1.9
+++ libmpdemux/asf.h	8 Dec 2001 11:00:59 -0000
@@ -197,6 +197,88 @@
 int asf_http_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl );
 
 int asf_streaming(char *data, int length, int *drop_packet );
+
+/* START - MMST support. */
+int asf_mmst_streaming_start( stream_t *stream );
+int asf_mmst_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl );
+int my_sprintf(unsigned char *pos, unsigned char *CWord, int number);
+int my_swprintf(unsigned char *pos, unsigned char *CWord, int number);
+void hex_printf(unsigned char *buffer, int size);
+
+typedef enum {        
+	init_connect=0x01,
+	send_local_ip=0x02,
+	send_file_path=0x05,
+	start_play_at_packet=0x07,
+	request_file=0x08,
+	stop_play=0x09,
+	request_connection_port=0x0B,
+	cancel_protocol=0x0D,
+	/* This is sent when the player is stopped during
+	   protocol negotiations (i.e. when the initial header
+	   is sent. */
+	
+	request_init=0x14,
+	header_chunk_request=0x15,
+	data_request=0x18,  
+	/* This one seems to be requesting codecs. This will not be used. */
+
+	ping_reply=0x1B,
+	/* This is the Ping reply. The server sends out this
+	   same command about once a minute to keep the 
+	   connection open. */
+	
+	seek_request=0x28,  
+	/* Sent when FF or Rewind are pressed or selected. */
+	
+	ack=0x30, 
+	/* This command is mostly unknown. We will ignore this for now. */
+	
+	send_local_details=0x32, 
+	/* This one has gotten Microsoft into alot of 
+	   of hot water. This one sends out your computer's
+	   IP address, your logon username, which codecs
+	   you have, and the OS you're running. I really 
+	   doubt this is needed for mplayer. */
+	
+	stream_element_switcher=0x33
+	
+	/* This allows us to switch streams if the
+	   current URL actually refers to multiple
+	   streams. This one will be ignored for now.
+	   Once we have one MMS stream working, then
+	   perhaps this will be implemented. */
+} mms_client_command_type;
+
+typedef enum {
+	server_version_response = 0x01,
+
+	data_length_value = 0x02,
+
+	funnel_error = 0x03,
+
+	sending_data_file = 0x05,
+
+	file_info_received = 0x06,
+
+	sending_mms_header = 0x11,
+
+	sending_general_data = 0x15,  
+	/* This one may be a codec download. This one will definitely 
+	   be ignored. */
+
+	end_of_stream = 0x1E,
+	ack_stream_selection = 0x21
+} mms_server_command_type;
+
+/* put 32 bit integer (Little endian) */
+void put_long(unsigned char *pos, unsigned int val);
+
+/* get 32bit integer (Little endian) */
+void get_long(unsigned char *pos, unsigned int *val);
+
+/* END - MMST Support */
+
 #endif
 
 #endif
Index: libmpdemux/asf_streaming.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/asf_streaming.c,v
retrieving revision 1.9
diff -u -r1.9 asf_streaming.c
--- libmpdemux/asf_streaming.c	20 Nov 2001 22:20:20 -0000	1.9
+++ libmpdemux/asf_streaming.c	8 Dec 2001 11:01:00 -0000
@@ -3,6 +3,12 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
 #include "config.h"
 
 #include "url.h"
@@ -11,6 +17,7 @@
 #include "network.h"
 
 #include "stream.h"
+#include "mmst.h"
 
 static ASF_StreamType_e streaming_type = ASF_Unknown_e;
 
@@ -20,7 +27,20 @@
 // So for now, we use the HTTP protocol.
 int
 asf_streaming_start( stream_t *stream ) {
-	return asf_http_streaming_start( stream );	
+	char protocol[10];
+
+	strcpy(protocol, stream -> streaming_ctrl -> url -> protocol);
+
+	if ((strcasecmp(protocol, "mms") == 0) || (strcasecmp(protocol, "mmst") == 0))
+		return asf_mmst_streaming_start( stream );
+
+	if (strcasecmp(protocol, "mmsu") == 0) {
+
+		printf("UDP support for MMS streams not yet supported. Sorry!\n");
+		return -1;
+	}
+	else
+		return asf_http_streaming_start( stream );	
 }
 
 
@@ -352,3 +372,126 @@
 	return fd;
 }
 
+int
+asf_mmst_streaming_start( stream_t *stream ) {
+	mms_client_command_type mms_command;
+	URL_t *url_next=NULL;
+	URL_t *url = stream->streaming_ctrl->url;
+	char buffer[BUFFER_SIZE], 
+		command_packet[50],
+		*BufPtr;
+	unsigned int MMSCSize;
+	unsigned int MMSCSeq = 0;
+	const unsigned int MMSC_POS_SEQ = 0x14,
+		MMSC_POS_SIZE        = 0x08,
+		MMSC_POS_FLAG        = 0x24,
+		MMSC_POS_SUBFLAG1    = 0x26,
+		MMSC_POS_SUBFLAG2    = 0x28,
+		MMSC_POS_REQCHUNKSEQ = 0x3c,
+		MMSC_POS_CHUNKLENGTH = 0x5c;
+
+	unsigned int DataSize, connection_failed = 1;
+	unsigned char MMSCFlag, MMSCSubFlag1, MMSCSubFlag2;
+
+	typedef struct sockaddr_in sockaddr_in;
+
+	//	unsigned char command_filler[] = {0x00, 0x00, 0x00,
+	int i;
+	int fd = stream->fd;
+	int done=1;
+
+	printf("Inside asf_mmst_streaming_start...");
+	
+	if( fd>0 ) close( fd );
+
+	url->port=1755;
+	
+	printf("Attempting to (re)connect to %s://%s/%s...\n",
+	       url->protocol,
+	       url->hostname,
+	       url->file);
+	
+	fd = connect2Server( url->hostname, url->port );
+	if( fd<0 ) return -1;
+	
+	connection_failed = 0;
+	
+	BufPtr = buffer; /* Send Initial Request */
+	
+	BufPtr += my_sprintf(BufPtr, MMSC_HEADER, sizeof(MMSC_HEADER));
+	BufPtr += my_sprintf(BufPtr, MMSC_REQUEST_INIT, sizeof(MMSC_REQUEST_INIT));
+	BufPtr += my_swprintf(BufPtr, "NSPlayer/6.4.07.1112; ", 0);
+	BufPtr += my_swprintf(BufPtr, "{c77e7400-738a-11d2-9add-0020af0a3278}", 0);
+	BufPtr += my_swprintf(BufPtr, "\0", 1);
+	MMSCSize=(int)BufPtr-(int)buffer; if(MMSCSize%8) MMSCSize+=8-MMSCSize%8; put_long(buffer+MMSC_POS_SIZE, MMSCSize-0x10);
+	put_long(buffer+MMSC_POS_SEQ, MMSCSeq++);
+	
+	if (send(fd, buffer, MMSCSize, 0) == -1) 
+		return -1;
+	
+	if (read( fd, buffer, 128) != 128) {
+		connection_failed = 1;
+		//	usleep(10000);
+		printf("Read failed #1\n");
+		//		continue;
+	} 
+	//hex_printf(buffer, 128);
+
+	read( fd, buffer, 16);
+	hex_printf(buffer, 16);
+}
+
+int 
+my_swprintf(unsigned char *pos, unsigned char *CWord, int number) {
+        int i, count;
+        unsigned short *SWord;
+        if(number==0) number = strlen(CWord);
+        SWord = malloc(number*2);
+        for(i=0, count=0 ; i<number ; i++) {
+                if((CWord[i] > 0x7f) && (CWord[i+1] > 0x7f)) {
+                        SWord[count++] = CWord[i+1]*256 + CWord[i];
+                        i++;
+                } else {
+                        SWord[count++] = CWord[i];
+                }
+        }
+        memcpy(pos, SWord, count*2);
+        free(SWord);
+	return number;
+}
+
+int my_sprintf(unsigned char *pos, unsigned char *CWord, int number)
+{
+        if(number==0) number = strlen(CWord);
+        memcpy(pos, CWord, number);
+        return number;
+}
+
+void hex_printf(unsigned char *buffer, int size) {
+	int i;
+
+	for (i=0; i < size; i++) {
+		printf("%2x ", buffer[i]);
+		if (((i+1) % 8 == 0) && ((i+1) % 32 != 0))
+			printf("\t");
+		if ((i+1) % 32 == 0)
+			printf("\n");
+	}
+
+	for (i=0; i < size; i++) {
+		printf("%c", (buffer[i] >= 32) ? buffer[i] : ' ');
+	}
+
+}
+
+/* put 32 bit integer (Little endian) */
+void put_long(unsigned char *pos, unsigned int val) {
+        *pos++ = (val & 0xff);
+        *pos++ = ((val>>8) & 0xff), *pos++ = ((val>>16) & 0xff), *pos++ = ((val>>24) & 0xff);
+}
+
+/* get 32bit integer (Little endian) */
+void get_long(unsigned char *pos, unsigned int *val) {
+        unsigned char c1 = *pos++, c2 = *pos++, c3 = *pos++, c4 = *pos++;
+        (*val) = (c4<<24) + (c3<<16) + (c2<<8) + c1;
+}
Index: libmpdemux/asfheader.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/asfheader.c,v
retrieving revision 1.25
diff -u -r1.25 asfheader.c
--- libmpdemux/asfheader.c	22 Nov 2001 15:30:54 -0000	1.25
+++ libmpdemux/asfheader.c	8 Dec 2001 11:01:01 -0000
@@ -48,6 +48,8 @@
 int asf_scrambling_b=1;
 int asf_packetsize=0;
 
+
+
 //int i;
 
 // the variable string is modify in this function
Index: libmpdemux/tvi_dummy.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tvi_dummy.c,v
retrieving revision 1.6
diff -u -r1.6 tvi_dummy.c
--- libmpdemux/tvi_dummy.c	8 Dec 2001 01:22:03 -0000	1.6
+++ libmpdemux/tvi_dummy.c	8 Dec 2001 11:01:21 -0000
@@ -35,8 +35,6 @@
 /* initialisation */
 static int init(priv_t *priv, tvi_param_t *params)
 {
-    priv->width = 320;
-    priv->height = 200;
     return(1);
 }
 
@@ -69,14 +67,8 @@
 	case TVI_CONTROL_VID_SET_WIDTH:
 	    priv->width = (int)*(void **)arg;
 	    return(TVI_CONTROL_TRUE);
-	case TVI_CONTROL_VID_GET_WIDTH:
-	    (int)*(void **)arg = priv->width;
-	    return(TVI_CONTROL_TRUE);
 	case TVI_CONTROL_VID_SET_HEIGHT:
 	    priv->height = (int)*(void **)arg;
-	    return(TVI_CONTROL_TRUE);	    
-	case TVI_CONTROL_VID_GET_HEIGHT:
-	    (int)*(void **)arg = priv->height;
 	    return(TVI_CONTROL_TRUE);	    
 	case TVI_CONTROL_VID_CHK_WIDTH:
 	case TVI_CONTROL_VID_CHK_HEIGHT:
Index: libmpdemux/video.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/video.c,v
retrieving revision 1.3
diff -u -r1.3 video.c
--- libmpdemux/video.c	8 Dec 2001 03:21:59 -0000	1.3
+++ libmpdemux/video.c	8 Dec 2001 11:01:24 -0000
@@ -83,7 +83,6 @@
    // fill aspect info:
    switch(picture.aspect_ratio_information){
      case 2:  // PAL/NTSC SVCD/DVD 4:3
-     case 4:  // SECAM 4:3? - XXX check with more files! 
      case 8:  // PAL VCD 4:3
      case 12: // NTSC VCD 4:3
        sh_video->aspect=4.0/3.0;


More information about the MPlayer-dev-eng mailing list