changeset 833:b8cecdc0c67f

Starting implementation of ASF network streaming.
author bertrand
date Fri, 18 May 2001 16:14:06 +0000
parents 369697a87773
children 06cd7efc94d7
files Makefile asf.h asf_streaming.c asfheader.c demux_asf.c network.c url.c url.h
diffstat 8 files changed, 338 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu May 17 23:35:51 2001 +0000
+++ b/Makefile	Fri May 18 16:14:06 2001 +0000
@@ -20,8 +20,10 @@
 prefix = /usr/local
 BINDIR = ${prefix}/bin
 # BINDIR = /usr/local/bin
-SRCS = find_sub.c aviprint.c dll_init.c dec_audio.c aviwrite.c aviheader.c asfheader.c demux_avi.c demux_asf.c demux_mpg.c demuxer.c stream.c codec-cfg.c subreader.c linux/getch2.c linux/timer-lx.c linux/shmem.c xa/xa_gsm.c lirc_mp.c cfgparser.c mixer.c dvdauth.c spudec.c
-OBJS = find_sub.o aviprint.o dll_init.o dec_audio.o aviwrite.o aviheader.o asfheader.o demux_avi.o demux_asf.o demux_mpg.o demuxer.o stream.o codec-cfg.o subreader.o linux/getch2.o linux/timer-lx.o linux/shmem.o xa/xa_gsm.o lirc_mp.o cfgparser.o mixer.o dvdauth.o spudec.o
+SRCS = asf_streaming.c find_sub.c aviprint.c dll_init.c dec_audio.c aviwrite.c aviheader.c asfheader.c demux_avi.c demux_asf.c demux_mpg.c demuxer.c stream.c codec-cfg.c subreader.c linux/getch2.c linux/timer-lx.c linux/shmem.c xa/xa_gsm.c lirc_mp.c cfgparser.c mixer.c dvdauth.c spudec.c
+#BB: IMHO It's simplier to use the following rule:
+#OBJS = $(SRCS:.c=.o)
+OBJS = asf_streaming.o find_sub.o aviprint.o dll_init.o dec_audio.o aviwrite.o aviheader.o asfheader.o demux_avi.o demux_asf.o demux_mpg.o demuxer.o stream.o codec-cfg.o subreader.o linux/getch2.o linux/timer-lx.o linux/shmem.o xa/xa_gsm.o lirc_mp.o cfgparser.o mixer.o dvdauth.o spudec.o
 CFLAGS = $(OPTFLAGS) -Iloader -Ilibvo $(CSS_INC) # -Wall
 A_LIBS = -Lmp3lib -lMP3 -Llibac3 -lac3
 VO_LIBS = -Llibvo -lvo $(X_LIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asf.h	Fri May 18 16:14:06 2001 +0000
@@ -0,0 +1,110 @@
+#ifndef ASF_H
+#define ASF_H
+
+#include <inttypes.h>
+
+///////////////////////
+// MS GUID definition
+///////////////////////
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+// Size of GUID is 16 bytes!
+typedef struct __attribute__((packed)) {
+	uint32_t	Data1;		// 4 bytes
+	uint16_t	Data2;		// 2 bytes
+	uint16_t	Data3;		// 2 bytes
+	uint8_t		Data4[8];	// 8 bytes
+} GUID_t;
+#endif
+
+///////////////////////
+// ASF Object Header 
+///////////////////////
+typedef struct __attribute__((packed)) {
+  uint8_t guid[16];
+  uint64_t size;
+} ASF_obj_header_t;
+
+////////////////
+// ASF Header 
+////////////////
+typedef struct __attribute__((packed)) {
+  ASF_obj_header_t objh;
+  uint32_t cno; // number of subchunks
+  uint8_t v1; // unknown (0x01)
+  uint8_t v2; // unknown (0x02)
+} ASF_header_t;
+
+/////////////////////
+// ASF File Header 
+/////////////////////
+typedef struct __attribute__((packed)) {
+  uint8_t client[16]; // Client GUID
+  uint64_t file_size;
+  uint64_t creat_time; //File creation time FILETIME 8
+  uint64_t packets;    //Number of packets UINT64 8
+  uint64_t end_timestamp; //Timestamp of the end position UINT64 8
+  uint64_t duration;  //Duration of the playback UINT64 8
+  uint32_t start_timestamp; //Timestamp of the start position UINT32 4
+  uint32_t unk1; //Unknown, maybe reserved ( usually contains 0 ) UINT32 4
+  uint32_t flags; //Unknown, maybe flags ( usually contains 2 ) UINT32 4
+  uint32_t packetsize; //Size of packet, in bytes UINT32 4
+  uint32_t packetsize2; //Size of packet ( confirm ) UINT32 4
+  uint32_t frame_size; //Size of uncompressed video frame UINT32 4
+} ASF_file_header_t;
+
+///////////////////////
+// ASF Stream Header
+///////////////////////
+typedef struct __attribute__((packed)) {
+  uint8_t type[16]; // Stream type (audio/video) GUID 16
+  uint8_t concealment[16]; // Audio error concealment type GUID 16
+  uint64_t unk1; // Unknown, maybe reserved ( usually contains 0 ) UINT64 8
+  uint32_t type_size; //Total size of type-specific data UINT32 4
+  uint32_t stream_size; //Size of stream-specific data UINT32 4
+  uint16_t stream_no; //Stream number UINT16 2
+  uint32_t unk2; //Unknown UINT32 4
+} ASF_stream_header_t;
+
+///////////////////////////
+// ASF Content Description
+///////////////////////////
+typedef struct  __attribute__((packed)) {
+  uint16_t title_size;
+  uint16_t author_size;
+  uint16_t copyright_size;
+  uint16_t comment_size;
+  uint16_t rating_size;
+} ASF_content_description_t;
+
+////////////////////////
+// ASF Segment Header 
+////////////////////////
+typedef struct __attribute__((packed)) {
+  uint8_t streamno;
+  uint8_t seq;
+  uint32_t x;
+  uint8_t flag;
+} ASF_segmhdr_t;
+
+//////////////////////
+// ASF Stream Chunck
+//////////////////////
+typedef struct __attribute__((packed)) {
+	uint16_t	type;
+	uint16_t	length;
+	uint32_t	sequence_number;
+	uint16_t	unknown;
+	uint16_t	length2;
+} ASF_stream_chunck_t;
+
+
+// Definition of the differents type of ASF streaming
+typedef enum {
+	ASF_Unknown_e,
+	ASF_Live_e,
+	ASF_Prerecorded_e,
+	ASF_Redirector_e
+} ASF_StreamType_e;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asf_streaming.c	Fri May 18 16:14:06 2001 +0000
@@ -0,0 +1,54 @@
+#include "asf.h"
+
+#include <string.h>
+
+static ASF_StreamType_e stream_type;
+
+void asf_streaming(char *data, int length) {
+	ASF_stream_chunck_t *stream_chunck=(ASF_stream_chunck_t*)data;
+	printf("ASF stream chunck size=%d\n", stream_chunck->length);
+
+	switch(stream_chunck->type) {
+		case 0x4324:	// Clear ASF configuration
+			printf("    --> Clearing ASF stream configuration!\n");
+			break;
+		case 0x4424:    // Data follows
+			printf("    --> Data follows\n");
+			break;
+		case 0x4524:    // Transfer complete
+			printf("    --> Transfer complete\n");
+			break;
+		case 0x4824:    // ASF header chunk follows
+			printf("    --> ASF header chunk follows\n");
+			break;
+		default:
+			printf("======> Unknown stream type %d\n", stream_chunck->type );
+	}
+}
+
+void asf_steam_type(char *content_type, char *features) {
+	stream_type = ASF_Unknown_e;
+	if( !strcasecmp(content_type, "application/octet-stream") ) {
+		if( strstr(features, "broadcast")) {
+			printf("-----> Live stream <-------\n");
+			stream_type = ASF_Live_e;
+		} else {
+			printf("-----> Prerecorded <-------\n");
+			stream_type = ASF_Prerecorded_e;
+		}
+	} else {
+		if(     (!strcasecmp(content_type, "audio/x-ms-wax")) ||
+			(!strcasecmp(content_type, "audio/x-ms-wma")) ||
+			(!strcasecmp(content_type, "video/x-ms-asf")) ||
+			(!strcasecmp(content_type, "video/x-ms-afs")) ||
+			(!strcasecmp(content_type, "video/x-ms-wvx")) ||
+			(!strcasecmp(content_type, "video/x-ms-wmv")) ||
+			(!strcasecmp(content_type, "video/x-ms-wma")) ) {
+			printf("-----> Redirector <-------\n");
+			stream_type = ASF_Redirector_e;
+		} else {
+			printf("-----> unknown content-type: %s\n", content_type );
+			stream_type = ASF_Unknown_e;
+		}
+	}
+}
--- a/asfheader.c	Thu May 17 23:35:51 2001 +0000
+++ b/asfheader.c	Fri May 18 16:14:06 2001 +0000
@@ -16,6 +16,10 @@
 #include "codec-cfg.h"
 #include "stheader.h"
 
+#include "asf.h"
+
+// BB: Moved to asf.h  --------------------- FROM HERE -------------------
+#ifdef 0
 typedef struct __attribute__((packed)) {
   unsigned char guid[16];
   unsigned long long size;
@@ -60,6 +64,8 @@
   unsigned short comment_size;
   unsigned short rating_size;
 } ASF_content_description_t;
+#endif
+// BB: Moved to asf.h  --------------------- TO HERE -------------------
 
 static ASF_header_t asfh;
 static ASF_obj_header_t objh;
@@ -75,13 +81,19 @@
 
 //int i;
 
-void print_asf_string(const char* name, char* string, int length){
-  int i;
-  printf("%s", name);
-  for(i=0;i<length && string[i]!='\0';i+=2){
-    printf("%c", string[i]);
+// the variable string is modify in this function
+void pack_asf_string(char* string, int length) {
+  int i,j;
+  for( i=0, j=0; i<length && string[i]!='\0'; i+=2, j++) {
+    string[j]=string[i];
   }
-  printf("\n");
+  string[j]='\0';
+}
+
+// the variable string is modify in this function
+void print_asf_string(const char* name, char* string, int length) {
+  pack_asf_string(string, length);
+  printf("%s%s\n", name, string);
 }
 
 static char* asf_chunk_type(unsigned char* guid){
--- a/demux_asf.c	Thu May 17 23:35:51 2001 +0000
+++ b/demux_asf.c	Fri May 18 16:14:06 2001 +0000
@@ -8,6 +8,8 @@
 #include "stream.h"
 #include "demuxer.h"
 
+#include "asf.h"
+
 // defined at asfheader.c:
 extern unsigned char* asf_packet;
 extern int asf_scrambling_h;
@@ -24,12 +26,16 @@
 
 //static int skip_video_frames=0;
 
+//BB: Moved to asf.h --------- FROM HERE --------
+#ifdef 0
 typedef struct __attribute__((packed)) {
   unsigned char streamno;
   unsigned char seq;
   unsigned long x;
   unsigned char flag;
 } ASF_segmhdr_t;
+#endif
+//BB: Moved to asf.h --------- TO HERE --------
 
 static void asf_descrambling(unsigned char *src,int len){
   unsigned char *dst=malloc(len);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network.c	Fri May 18 16:14:06 2001 +0000
@@ -0,0 +1,38 @@
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+
+int
+connect2Server(char *host, int port) {
+	int socket_server_fd;
+	struct sockaddr_in server_address;
+	printf(">>>> connect2Server [%s@%d]\n", host, port );
+	socket_server_fd = socket(AF_INET, SOCK_STREAM, 0);
+	if( socket_server_fd==-1 ) {
+		perror("Failed to create socket");
+		exit(1);
+	}
+
+	if( isalpha(host[0]) ) {
+		struct hostent *hp;
+		if( (hp=gethostbyname( host ))==NULL ) {
+			printf("Unknown host: %s\n", host);
+			exit(1);
+		}
+		memcpy( &server_address.sin_addr.s_addr, hp->h_addr, hp->h_length );
+	} else {
+		inet_pton(AF_INET, host, &server_address.sin_addr);
+	}
+	server_address.sin_family=AF_INET;
+	server_address.sin_port=htons(port);
+
+	if( connect( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) {
+		perror("Failed to connect to server");
+		close(socket_Stream_fd);
+		exit(1);
+	}
+	return socket_server_fd;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/url.c	Fri May 18 16:14:06 2001 +0000
@@ -0,0 +1,93 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "url.h"
+
+URL_t*
+set_url(char* url) {
+	int pos1, pos2;
+	URL_t* Curl;
+	char *ptr1, *ptr2;
+
+	// Create the URL container
+	Curl = (URL_t*)malloc(sizeof(URL_t));
+	if( Curl==NULL ) {
+		printf("Memory allocation failed!\n");
+		exit(1);
+	}
+	// Copy the url in the URL container
+	Curl->url = (char*)malloc(strlen(url)+1);
+	if( Curl->url==NULL ) {
+		printf("Memory allocation failed!\n");
+		exit(1);
+	}
+	strcpy(Curl->url, url);
+
+	// extract the protocol
+	ptr1 = strstr(url, "://");
+	if( ptr1==NULL ) {
+		printf("Malformed URL!\n");
+		return NULL;
+	}
+	pos1 = ptr1-url;
+	Curl->protocol = (char*)malloc(pos1+1);
+	strncpy(Curl->protocol, url, pos1);
+	Curl->protocol[pos1] = '\0';
+
+	// look if the port is given
+	ptr2 = strstr(ptr1+3, ":");
+	if( ptr2==NULL ) {
+		// No port is given
+		// Look if a path is given
+		ptr2 = strstr(ptr1+3, "/");
+		if( ptr2==NULL ) {
+			// No path/filename
+			// So we have an URL like http://www.hostname.com
+			pos2 = strlen(url);
+		} else {
+			// We have an URL like http://www.hostname.com/file.txt
+			pos2 = ptr2-url;
+		}
+	} else {
+		// We have an URL beginning like http://www.hostname.com:1212
+		// Get the port number
+		Curl->port = atoi(ptr2+1);
+		pos2 = ptr2-url;
+	}
+	// copy the hostname in the URL container
+	Curl->hostname = (char*)malloc(strlen(url)+1);
+	if( Curl->hostname==NULL ) {
+		printf("Memory allocation failed!\n");
+		exit(1);
+	}
+	strncpy(Curl->hostname, ptr1+3, pos2-pos1-3);
+
+	// Look if a path is given
+	ptr2 = strstr(ptr1+3, "/");
+	if( ptr2!=NULL ) {
+		// A path/filename is given
+		// check if it's not a trailing '/'
+		if( strlen(ptr2)>1 ) {
+			// copy the path/filename in the URL container
+			Curl->path = (char*)malloc(strlen(ptr2));
+			if( Curl->path==NULL ) {
+				printf("Memory allocation failed!\n");
+				exit(1);
+			}
+			strcpy(Curl->path, ptr2+1);
+		}
+	}
+	
+	return Curl;
+}
+
+void
+free_url(URL_t* url) {
+	if(url) return;
+	if(url->url) free(url->url);
+	if(url->protocol) free(url->protocol);
+	if(url->hostname) free(url->hostname);
+	if(url->path) free(url->path);
+	free(url);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/url.h	Fri May 18 16:14:06 2001 +0000
@@ -0,0 +1,15 @@
+#ifndef URL_H
+#define URL_H
+
+typedef struct {
+	char *url;
+	char *protocol;
+	char *hostname;
+	char *path;
+	unsigned int port;
+} URL_t;
+
+URL_t* set_url(char* url);
+void   free_url(URL_t* url);
+
+#endif