mirror of
https://github.com/mpv-player/mpv
synced 2025-02-17 04:58:06 +00:00
Starting implementation of ASF network streaming.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@834 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
8a0a08e97f
commit
4a83e5f2bd
6
Makefile
6
Makefile
@ -20,8 +20,10 @@ PRG_CFG = codec-cfg
|
||||
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)
|
||||
|
110
asf.h
Normal file
110
asf.h
Normal file
@ -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
|
54
asf_streaming.c
Normal file
54
asf_streaming.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
24
asfheader.c
24
asfheader.c
@ -16,6 +16,10 @@ extern int verbose; // defined in mplayer.c
|
||||
#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 @@ typedef struct __attribute__((packed)) {
|
||||
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 asf_packetsize=0;
|
||||
|
||||
//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){
|
||||
|
@ -8,6 +8,8 @@ extern int verbose; // defined in mplayer.c
|
||||
#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 @@ extern int asf_packetsize;
|
||||
|
||||
//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);
|
||||
|
38
network.c
Normal file
38
network.c
Normal file
@ -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;
|
||||
}
|
||||
|
93
url.c
Normal file
93
url.c
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user