summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-10-20 18:49:08 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-10-20 18:49:08 +0000
commit881e5d0783d66de0d3efe4b633aa413a277c5b18 (patch)
tree998f3cdd340f82a73f54b1cdc4e22c19dabff4ad /libmpdemux
parentdaab5f2480c62bbe684e09e0ae979958b447124b (diff)
downloadmpv-881e5d0783d66de0d3efe4b633aa413a277c5b18.tar.bz2
mpv-881e5d0783d66de0d3efe4b633aa413a277c5b18.tar.xz
libdemuxer...
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2311 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/asf.h200
-rw-r--r--libmpdemux/asf_streaming.c353
-rw-r--r--libmpdemux/asfheader.c279
-rw-r--r--libmpdemux/aviheader.c241
-rw-r--r--libmpdemux/aviheader.h106
-rw-r--r--libmpdemux/aviprint.c102
-rw-r--r--libmpdemux/aviwrite.c172
-rw-r--r--libmpdemux/bswap.h2
-rw-r--r--libmpdemux/codec-cfg.h0
-rw-r--r--libmpdemux/config.h2
-rw-r--r--libmpdemux/demux_asf.c367
-rw-r--r--libmpdemux/demux_avi.c673
-rw-r--r--libmpdemux/demux_mov.c613
-rw-r--r--libmpdemux/demux_mpg.c403
-rw-r--r--libmpdemux/demuxer.c580
-rw-r--r--libmpdemux/demuxer.h155
-rw-r--r--libmpdemux/dvdauth.c229
-rw-r--r--libmpdemux/dvdauth.h16
-rw-r--r--libmpdemux/help_mp.h1
-rw-r--r--libmpdemux/http.c296
-rw-r--r--libmpdemux/http.h44
-rw-r--r--libmpdemux/mp_msg.h2
-rw-r--r--libmpdemux/network.c592
-rw-r--r--libmpdemux/network.h49
-rw-r--r--libmpdemux/open.c437
-rw-r--r--libmpdemux/parse_es.c117
-rw-r--r--libmpdemux/parse_es.h18
-rw-r--r--libmpdemux/stheader.h94
-rw-r--r--libmpdemux/stream.c188
-rw-r--r--libmpdemux/stream.h141
-rw-r--r--libmpdemux/test.c66
-rw-r--r--libmpdemux/url.c117
-rw-r--r--libmpdemux/url.h23
-rw-r--r--libmpdemux/vcd_read.h280
-rw-r--r--libmpdemux/vcd_read_fbsd.h143
35 files changed, 7101 insertions, 0 deletions
diff --git a/libmpdemux/asf.h b/libmpdemux/asf.h
new file mode 100644
index 0000000000..8d35563cda
--- /dev/null
+++ b/libmpdemux/asf.h
@@ -0,0 +1,200 @@
+#ifndef __ASF_H
+#define __ASF_H
+
+#include "config.h" /* for WORDS_BIGENDIAN */
+#include <inttypes.h>
+#include "bswap.h"
+#ifdef STREAMING
+#include "network.h"
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a<b)?a:b)
+#endif
+
+///////////////////////
+// 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 size;
+ uint32_t sequence_number;
+ uint16_t unknown;
+ uint16_t size_confirm;
+} 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;
+
+
+/*
+ * Some macros to swap little endian structures read from an ASF file
+ * into machine endian format
+ */
+#ifdef WORDS_BIGENDIAN
+#define le2me_ASF_obj_header_t(h) { \
+ (h)->size = le2me_64((h)->size); \
+}
+#define le2me_ASF_header_t(h) { \
+ le2me_ASF_obj_header_t(&(h)->objh); \
+ (h)->cno = le2me_32((h)->cno); \
+}
+#define le2me_ASF_stream_header_t(h) { \
+ (h)->unk1 = le2me_64((h)->unk1); \
+ (h)->type_size = le2me_32((h)->type_size); \
+ (h)->stream_size = le2me_32((h)->stream_size); \
+ (h)->stream_no = le2me_16((h)->stream_no); \
+ (h)->unk2 = le2me_32((h)->unk2); \
+}
+#define le2me_ASF_file_header_t(h) { \
+ (h)->file_size = le2me_64((h)->file_size); \
+ (h)->creat_time = le2me_64((h)->creat_time); \
+ (h)->packets = le2me_64((h)->packets); \
+ (h)->end_timestamp = le2me_64((h)->end_timestamp); \
+ (h)->duration = le2me_64((h)->duration); \
+ (h)->start_timestamp = le2me_32((h)->start_timestamp); \
+ (h)->unk1 = le2me_32((h)->unk1); \
+ (h)->flags = le2me_32((h)->flags); \
+ (h)->packetsize = le2me_32((h)->packetsize); \
+ (h)->packetsize2 = le2me_32((h)->packetsize2); \
+ (h)->frame_size = le2me_32((h)->frame_size); \
+}
+#define le2me_ASF_content_description_t(h) { \
+ (h)->title_size = le2me_16((h)->title_size); \
+ (h)->author_size = le2me_16((h)->author_size); \
+ (h)->copyright_size = le2me_16((h)->copyright_size); \
+ (h)->comment_size = le2me_16((h)->comment_size); \
+ (h)->rating_size = le2me_16((h)->rating_size); \
+}
+#define le2me_BITMAPINFOHEADER(h) { \
+ (h)->biSize = le2me_32((h)->biSize); \
+ (h)->biWidth = le2me_32((h)->biWidth); \
+ (h)->biHeight = le2me_32((h)->biHeight); \
+ (h)->biPlanes = le2me_16((h)->biPlanes); \
+ (h)->biBitCount = le2me_16((h)->biBitCount); \
+ (h)->biCompression = le2me_32((h)->biCompression); \
+ (h)->biSizeImage = le2me_32((h)->biSizeImage); \
+ (h)->biXPelsPerMeter = le2me_32((h)->biXPelsPerMeter); \
+ (h)->biYPelsPerMeter = le2me_32((h)->biYPelsPerMeter); \
+ (h)->biClrUsed = le2me_32((h)->biClrUsed); \
+ (h)->biClrImportant = le2me_32((h)->biClrImportant); \
+}
+#define le2me_WAVEFORMATEX(h) { \
+ (h)->wFormatTag = le2me_16((h)->wFormatTag); \
+ (h)->nChannels = le2me_16((h)->nChannels); \
+ (h)->nSamplesPerSec = le2me_32((h)->nSamplesPerSec); \
+ (h)->nAvgBytesPerSec = le2me_32((h)->nAvgBytesPerSec); \
+ (h)->nBlockAlign = le2me_16((h)->nBlockAlign); \
+ (h)->wBitsPerSample = le2me_16((h)->wBitsPerSample); \
+ (h)->cbSize = le2me_16((h)->cbSize); \
+}
+#else
+#define le2me_ASF_obj_header_t(h) /**/
+#define le2me_ASF_header_t(h) /**/
+#define le2me_ASF_stream_header_t(h) /**/
+#define le2me_ASF_file_header_t(h) /**/
+#define le2me_ASF_content_description_t(h) /**/
+#define le2me_BITMAPINFOHEADER(h) /**/
+#define le2me_WAVEFORMATEX(h) /**/
+#endif
+
+
+#ifdef STREAMING
+int asf_http_streaming_type(char *content_type, char *features);
+int asf_http_streaming_start( streaming_ctrl_t *streaming_ctrl );
+int asf_http_streaming_read( streaming_ctrl_t *streaming_ctrl );
+
+int asf_streaming(char *data, int length, int *drop_packet );
+#endif
+
+#endif
diff --git a/libmpdemux/asf_streaming.c b/libmpdemux/asf_streaming.c
new file mode 100644
index 0000000000..5205a143b6
--- /dev/null
+++ b/libmpdemux/asf_streaming.c
@@ -0,0 +1,353 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "url.h"
+#include "http.h"
+#include "asf.h"
+#include "network.h"
+
+#include "stream.h"
+//#include "demuxer.h"
+
+//extern demuxer_t *demuxer;
+
+static ASF_StreamType_e streaming_type = ASF_Unknown_e;
+
+int
+asf_http_streaming_read( streaming_ctrl_t *streaming_ctrl ) {
+ char *buffer;
+ int drop_packet;
+ int ret;
+printf("asf_streaming_read\n");
+ ret = asf_streaming( streaming_ctrl->buffer->buffer, streaming_ctrl->buffer->length, &drop_packet );
+printf("ret: %d\n", ret);
+ if( ret<0 ) return -1;
+ if( ret>streaming_ctrl->buffer->length ) return 0;
+ buffer = (char*)malloc(ret);
+ if( buffer==NULL ) {
+ printf("Memory allocation failed\n");
+ return -1;
+ }
+printf("buffer length: %d\n", streaming_ctrl->buffer->length );
+ net_fifo_pop( streaming_ctrl->buffer, buffer, ret );
+printf(" pop: 0x%02X\n", *((unsigned int*)buffer) );
+printf("buffer length: %d\n", streaming_ctrl->buffer->length );
+printf("0x%02X\n", *((unsigned int*)(buffer+sizeof(ASF_stream_chunck_t))) );
+ if( !drop_packet ) {
+ write( streaming_ctrl->fd_pipe_in, buffer+sizeof(ASF_stream_chunck_t), ret-sizeof(ASF_stream_chunck_t) );
+ }
+ free( buffer );
+ return ret;
+}
+
+int
+asf_streaming(char *data, int length, int *drop_packet ) {
+ ASF_stream_chunck_t *stream_chunck=(ASF_stream_chunck_t*)data;
+ printf("ASF stream chunck size=%d\n", stream_chunck->size);
+printf("length: %d\n", length );
+printf("0x%02X\n", stream_chunck->type );
+
+ if( drop_packet!=NULL ) *drop_packet = 0;
+ if( data==NULL || length<=0 ) return -1;
+
+ if( stream_chunck->size<8 ) {
+ printf("Ahhhh, stream_chunck size is too small: %d\n", stream_chunck->size);
+ return -1;
+ }
+ if( stream_chunck->size!=stream_chunck->size_confirm ) {
+ printf("size_confirm mismatch!: %d %d\n", stream_chunck->size, stream_chunck->size_confirm);
+ return -1;
+ }
+
+ printf(" type: 0x%02X\n", stream_chunck->type );
+ printf(" size: %d (0x%02X)\n", stream_chunck->size, stream_chunck->size );
+ printf(" sequence_number: 0x%04X\n", stream_chunck->sequence_number );
+ printf(" unknown: 0x%02X\n", stream_chunck->unknown );
+ printf(" size_confirm: 0x%02X\n", stream_chunck->size_confirm );
+
+
+ switch(stream_chunck->type) {
+ case 0x4324: // Clear ASF configuration
+ printf("=====> Clearing ASF stream configuration!\n");
+ if( drop_packet!=NULL ) *drop_packet = 1;
+ return stream_chunck->size;
+ break;
+ case 0x4424: // Data follows
+ printf("=====> Data follows\n");
+ break;
+ case 0x4524: // Transfer complete
+ printf("=====> Transfer complete\n");
+ if( drop_packet!=NULL ) *drop_packet = 1;
+ return stream_chunck->size;
+ break;
+ case 0x4824: // ASF header chunk follows
+ printf("=====> ASF header chunk follows\n");
+ break;
+ default:
+ printf("=====> Unknown stream type 0x%x\n", stream_chunck->type );
+ }
+ return stream_chunck->size+4;
+}
+
+int
+asf_http_streaming_type(char *content_type, char *features) {
+ if( content_type==NULL ) return ASF_Unknown_e;
+ if( !strcasecmp(content_type, "application/octet-stream") ) {
+ if( features==NULL ) {
+ printf("=====> ASF Prerecorded\n");
+ return ASF_Prerecorded_e;
+ } else if( strstr(features, "broadcast")) {
+ printf("=====> ASF Live stream\n");
+ return ASF_Live_e;
+ } else {
+ printf("=====> ASF Prerecorded\n");
+ return 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("=====> ASF Redirector\n");
+ return ASF_Redirector_e;
+ } else {
+ printf("=====> ASF unknown content-type: %s\n", content_type );
+ return ASF_Unknown_e;
+ }
+ }
+ return ASF_Unknown_e;
+}
+
+HTTP_header_t *
+asf_http_request(URL_t *url) {
+ HTTP_header_t *http_hdr;
+ char str[250];
+ char *ptr;
+ char *request;
+ int i;
+
+ int offset_hi=0, offset_lo=0, req_nb=1, length=0;
+ int asf_nb_stream;
+
+ // Common header for all requests.
+ http_hdr = http_new_header();
+ http_set_uri( http_hdr, url->file );
+ http_set_field( http_hdr, "Accept: */*" );
+ http_set_field( http_hdr, "User-Agent: NSPlayer/4.1.0.3856" );
+ sprintf( str, "Host: %s:%d", url->hostname, url->port );
+ http_set_field( http_hdr, str );
+ http_set_field( http_hdr, "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}" );
+ sprintf(str,
+ "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=%u:%u,request-context=%d,max-duration=%u",
+ offset_hi, offset_lo, req_nb, length );
+ http_set_field( http_hdr, str );
+
+ switch( streaming_type ) {
+ case ASF_Live_e:
+ case ASF_Prerecorded_e:
+ http_set_field( http_hdr, "Pragma: xPlayStrm=1" );
+ ptr = str;
+ ptr += sprintf( ptr, "Pragma: stream-switch-entry=");
+
+// FIXME: why do you need demuxer here? if you really need it, pass it as
+// parameter. -- A'rpi
+
+#if 0
+ for( i=0, asf_nb_stream=0 ; i<256 ; i++ ) {
+ // FIXME START
+ if( demuxer==NULL ) {
+ ptr += sprintf( ptr, " ffff:1:0" );
+ asf_nb_stream = 1;
+ break;
+ }
+ // FIXME END
+ if( demuxer->a_streams[i] ) {
+ ptr += sprintf( ptr, " ffff:%d:0", i );
+ asf_nb_stream++;
+ }
+ if( demuxer->v_streams[i] ) {
+ ptr += sprintf( ptr, " ffff:%d:0", i );
+ asf_nb_stream++;
+ }
+ }
+#endif
+ http_set_field( http_hdr, str );
+ sprintf( str, "Pragma: stream-switch-count=%d", asf_nb_stream );
+ http_set_field( http_hdr, str );
+ break;
+ case ASF_Redirector_e:
+ break;
+ case ASF_Unknown_e:
+ // First request goes here.
+ break;
+ default:
+ printf("Unknown asf stream type\n");
+ }
+
+ http_set_field( http_hdr, "Connection: Close" );
+ http_build_request( http_hdr );
+
+ return http_hdr;
+}
+
+int
+asf_http_parse_response( HTTP_header_t *http_hdr ) {
+ char *content_type, *pragma;
+ char features[64] = "\0";
+ int len;
+ if( http_response_parse(http_hdr)<0 ) {
+ printf("Failed to parse HTTP response\n");
+ return -1;
+ }
+ if( http_hdr->status_code!=200 ) {
+ printf("Server return %d:%s\n", http_hdr->status_code, http_hdr->reason_phrase);
+ return -1;
+ }
+
+ content_type = http_get_field( http_hdr, "Content-Type");
+
+ pragma = http_get_field( http_hdr, "Pragma");
+ while( pragma!=NULL ) {
+ char *comma_ptr=NULL;
+ char *end;
+ // The pragma line can get severals attributes
+ // separeted with a comma ','.
+ do {
+ if( !strncasecmp( pragma, "features=", 9) ) {
+ pragma += 9;
+ end = strstr( pragma, "," );
+ if( end==NULL ) {
+ len = strlen(pragma);
+ }
+ len = MIN(end-pragma,sizeof(features));
+ strncpy( features, pragma, len );
+ features[len]='\0';
+ break;
+ }
+ comma_ptr = strstr( pragma, "," );
+ if( comma_ptr!=NULL ) {
+ pragma = comma_ptr+1;
+ if( pragma[0]==' ' ) pragma++;
+ }
+ } while( comma_ptr!=NULL );
+ pragma = http_get_next_field( http_hdr );
+ }
+
+ streaming_type = asf_http_streaming_type( content_type, features );
+
+ if( http_hdr->body_size>0 ) {
+ asf_streaming( http_hdr->body, http_hdr->body_size, NULL);
+ }
+
+ return 0;
+}
+
+URL_t *
+asf_http_ASX_redirect( HTTP_header_t *http_hdr ) {
+ URL_t *url_redirect=NULL;
+ printf("=========>> ASX parser not yet implemented <<==========\n");
+
+ printf("ASX=[%s]\n", http_hdr->body );
+
+ return url_redirect;
+}
+
+int
+asf_http_streaming_start( streaming_ctrl_t *streaming_ctrl ) {
+ HTTP_header_t *http_hdr=NULL;
+ URL_t *url_next=NULL;
+ URL_t *url = *(streaming_ctrl->url);
+ char buffer[BUFFER_SIZE];
+ int i;
+ int fd = streaming_ctrl->fd_net;
+ int done=1;
+
+streaming_type = ASF_Live_e;
+ do {
+ if( fd>0 ) close( fd );
+
+ fd = connect2Server( url->hostname, url->port );
+ if( fd<0 ) return -1;
+
+ http_hdr = asf_http_request( url );
+printf("[%s]\n", http_hdr->buffer );
+ write( fd, http_hdr->buffer, http_hdr->buffer_size );
+// http_free( http_hdr );
+
+ http_hdr = http_new_header();
+ do {
+ i = readFromServer( fd, buffer, BUFFER_SIZE );
+printf("read: %d\n", i );
+ if( i<0 ) {
+ perror("read");
+ http_free( http_hdr );
+ return -1;
+ }
+ http_response_append( http_hdr, buffer, i );
+ } while( !http_is_header_entired( http_hdr ) );
+//http_hdr->buffer[http_hdr->buffer_len]='\0';
+//printf("[%s]\n", http_hdr->buffer );
+ if( asf_http_parse_response(http_hdr)<0 ) {
+ printf("Failed to parse header\n");
+ http_free( http_hdr );
+ return -1;
+ }
+ switch( streaming_type ) {
+ case ASF_Live_e:
+ case ASF_Prerecorded_e:
+ if( http_hdr->body_size>0 ) {
+printf("--- 0x%02X\n", streaming_ctrl->buffer );
+ net_fifo_push( streaming_ctrl->buffer, http_hdr->body, http_hdr->body_size );
+ } else {
+ ASF_stream_chunck_t *ptr;
+ int ret;
+ i = readFromServer( fd, buffer, sizeof(ASF_stream_chunck_t) );
+printf("read: %d\n", i );
+ ret = asf_streaming( buffer, i, NULL );
+ net_fifo_push( streaming_ctrl->buffer, buffer, i );
+ ptr = (ASF_stream_chunck_t*)buffer;
+ if( ret==ptr->size ) {
+ }
+ }
+// done = 0;
+ break;
+ case ASF_Redirector_e:
+ url_next = asf_http_ASX_redirect( http_hdr );
+ if( url_next==NULL ) {
+ printf("Failed to parse ASX file\n");
+ close(fd);
+ http_free( http_hdr );
+ return -1;
+ }
+ if( url_next->port==0 ) url_next->port=80;
+ url_free( url );
+ url = url_next;
+ *(streaming_ctrl->url) = url_next;
+ url_next = NULL;
+ break;
+ case ASF_Unknown_e:
+ default:
+ printf("Unknown ASF streaming type\n");
+ close(fd);
+ http_free( http_hdr );
+ return -1;
+ }
+
+ // Check if we got a redirect.
+ } while(!done);
+
+ streaming_ctrl->fd_net = fd;
+ streaming_ctrl->streaming_read = asf_http_streaming_read;
+ streaming_ctrl->prebuffer_size = 10000;
+ streaming_ctrl->buffering = 1;
+ streaming_ctrl->status = streaming_playing_e;
+
+ http_free( http_hdr );
+ return fd;
+}
+
diff --git a/libmpdemux/asfheader.c b/libmpdemux/asfheader.c
new file mode 100644
index 0000000000..d8349c6499
--- /dev/null
+++ b/libmpdemux/asfheader.c
@@ -0,0 +1,279 @@
+// .asf fileformat docs from http://divx.euro.ru
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern int verbose; // defined in mplayer.c
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "stream.h"
+#include "demuxer.h"
+
+#include "wine/mmreg.h"
+#include "wine/avifmt.h"
+#include "wine/vfw.h"
+
+#include "codec-cfg.h"
+#include "stheader.h"
+//#include "aviheader.h"
+#include "asf.h"
+
+#ifdef ARCH_X86
+#define ASF_LOAD_GUID_PREFIX(guid) (*(uint32_t *)(guid))
+#else
+#define ASF_LOAD_GUID_PREFIX(guid) \
+ ((guid)[3] << 24 | (guid)[2] << 16 | (guid)[1] << 8 | (guid)[0])
+#endif
+
+#define ASF_GUID_PREFIX_audio_stream 0xF8699E40
+#define ASF_GUID_PREFIX_video_stream 0xBC19EFC0
+#define ASF_GUID_PREFIX_audio_conceal_none 0x49f1a440
+#define ASF_GUID_PREFIX_audio_conceal_interleave 0xbfc3cd50
+#define ASF_GUID_PREFIX_header 0x75B22630
+#define ASF_GUID_PREFIX_data_chunk 0x75b22636
+#define ASF_GUID_PREFIX_index_chunk 0x33000890
+#define ASF_GUID_PREFIX_stream_header 0xB7DC0791
+#define ASF_GUID_PREFIX_header_2_0 0xD6E229D1
+#define ASF_GUID_PREFIX_file_header 0x8CABDCA1
+#define ASF_GUID_PREFIX_content_desc 0x75b22633
+
+
+static ASF_header_t asfh;
+static ASF_obj_header_t objh;
+static ASF_file_header_t fileh;
+static ASF_stream_header_t streamh;
+static ASF_content_description_t contenth;
+
+unsigned char* asf_packet=NULL;
+int asf_scrambling_h=1;
+int asf_scrambling_w=1;
+int asf_scrambling_b=1;
+int asf_packetsize=0;
+
+//int i;
+
+// the variable string is modify in this function
+void pack_asf_string(char* string, int length) {
+ int i,j;
+ if( string==NULL ) return;
+ for( i=0, j=0; i<length && string[i]!='\0'; i+=2, j++) {
+ string[j]=string[i];
+ }
+ 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);
+ mp_msg(MSGT_HEADER,MSGL_V,"%s%s\n", name, string);
+}
+
+static char* asf_chunk_type(unsigned char* guid) {
+ static char tmp[60];
+ char *p;
+ int i;
+
+ switch(ASF_LOAD_GUID_PREFIX(guid)){
+ case ASF_GUID_PREFIX_audio_stream:
+ return "guid_audio_stream";
+ case ASF_GUID_PREFIX_video_stream:
+ return "guid_video_stream";
+ case ASF_GUID_PREFIX_audio_conceal_none:
+ return "guid_audio_conceal_none";
+ case ASF_GUID_PREFIX_audio_conceal_interleave:
+ return "guid_audio_conceal_interleave";
+ case ASF_GUID_PREFIX_header:
+ return "guid_header";
+ case ASF_GUID_PREFIX_data_chunk:
+ return "guid_data_chunk";
+ case ASF_GUID_PREFIX_index_chunk:
+ return "guid_index_chunk";
+ case ASF_GUID_PREFIX_stream_header:
+ return "guid_stream_header";
+ case ASF_GUID_PREFIX_header_2_0:
+ return "guid_header_2_0";
+ case ASF_GUID_PREFIX_file_header:
+ return "guid_file_header";
+ case ASF_GUID_PREFIX_content_desc:
+ return "guid_content_desc";
+ default:
+ strcpy(tmp, "unknown guid ");
+ p = tmp + strlen(tmp);
+ for (i = 0; i < 16; i++) {
+ if ((1 << i) & ((1<<4) | (1<<6) | (1<<8))) *p++ = '-';
+ sprintf(p, "%02x", guid[i]);
+ p += 2;
+ }
+ return tmp;
+ }
+}
+
+int asf_check_header(demuxer_t *demuxer){
+ unsigned char asfhdrguid[16]={0x30,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C};
+ stream_read(demuxer->stream,(char*) &asfh,sizeof(asfh)); // header obj
+ le2me_ASF_header_t(&asfh); // swap to machine endian
+// for(i=0;i<16;i++) printf(" %02X",temp[i]);printf("\n");
+// for(i=0;i<16;i++) printf(" %02X",asfhdrguid[i]);printf("\n");
+ if(memcmp(asfhdrguid,asfh.objh.guid,16)){
+ mp_msg(MSGT_HEADER,MSGL_V,"ASF_check: not ASF guid!\n");
+ return 0; // not ASF guid
+ }
+ if(asfh.cno>256){
+ mp_msg(MSGT_HEADER,MSGL_V,"ASF_check: invalid subchunks_no %d\n",(int) asfh.cno);
+ return 0; // invalid header???
+ }
+ return 1;
+}
+
+extern void print_wave_header(WAVEFORMATEX *h);
+extern void print_video_header(BITMAPINFOHEADER *h);
+
+int read_asf_header(demuxer_t *demuxer){
+ static unsigned char buffer[1024];
+
+#if 1
+ //printf("ASF file! (subchunks: %d)\n",asfh.cno);
+while(!stream_eof(demuxer->stream)){
+ int pos,endpos;
+ pos=stream_tell(demuxer->stream);
+ stream_read(demuxer->stream,(char*) &objh,sizeof(objh));
+ le2me_ASF_obj_header_t(&objh);
+ if(stream_eof(demuxer->stream)) break; // EOF
+ endpos=pos+objh.size;
+// for(i=0;i<16;i++) printf("%02X ",objh.guid[i]);
+ //printf("0x%08X [%s] %d\n",pos, asf_chunk_type(objh.guid),(int) objh.size);
+ switch(ASF_LOAD_GUID_PREFIX(objh.guid)){
+ case ASF_GUID_PREFIX_stream_header:
+ stream_read(demuxer->stream,(char*) &streamh,sizeof(streamh));
+ le2me_ASF_stream_header_t(&streamh);
+ if(verbose){
+ mp_msg(MSGT_HEADER,MSGL_V,"stream type: %s\n",asf_chunk_type(streamh.type));
+ mp_msg(MSGT_HEADER,MSGL_V,"stream concealment: %s\n",asf_chunk_type(streamh.concealment));
+ mp_msg(MSGT_HEADER,MSGL_V,"type: %d bytes, stream: %d bytes ID: %d\n",(int)streamh.type_size,(int)streamh.stream_size,(int)streamh.stream_no);
+ mp_msg(MSGT_HEADER,MSGL_V,"unk1: %lX unk2: %X\n",(unsigned long)streamh.unk1,(unsigned int)streamh.unk2);
+ mp_msg(MSGT_HEADER,MSGL_V,"FILEPOS=0x%X\n",stream_tell(demuxer->stream));
+ }
+ if(streamh.type_size>1024 || streamh.stream_size>1024){
+ mp_msg(MSGT_HEADER,MSGL_FATAL,"FATAL: header size bigger than 1024 bytes!\n"
+ "Please contact mplayer authors, and upload/send this file.\n");
+ return 0;
+ }
+ // type-specific data:
+ stream_read(demuxer->stream,(char*) buffer,streamh.type_size);
+ switch(ASF_LOAD_GUID_PREFIX(streamh.type)){
+ case ASF_GUID_PREFIX_audio_stream: {
+ sh_audio_t* sh_audio=new_sh_audio(demuxer,streamh.stream_no & 0x7F);
+ sh_audio->wf=calloc((streamh.type_size<sizeof(WAVEFORMATEX))?sizeof(WAVEFORMATEX):streamh.type_size,1);
+ memcpy(sh_audio->wf,buffer,streamh.type_size);
+ le2me_WAVEFORMATEX(sh_audio->wf);
+ if(verbose>=1) print_wave_header(sh_audio->wf);
+ if(ASF_LOAD_GUID_PREFIX(streamh.concealment)==ASF_GUID_PREFIX_audio_conceal_interleave){
+ stream_read(demuxer->stream,(char*) buffer,streamh.stream_size);
+ asf_scrambling_h=buffer[0];
+ asf_scrambling_w=(buffer[2]<<8)|buffer[1];
+ asf_scrambling_b=(buffer[4]<<8)|buffer[3];
+ asf_scrambling_w/=asf_scrambling_b;
+ } else {
+ asf_scrambling_b=asf_scrambling_h=asf_scrambling_w=1;
+ }
+ mp_msg(MSGT_HEADER,MSGL_V,"ASF: audio scrambling: %d x %d x %d\n",asf_scrambling_h,asf_scrambling_w,asf_scrambling_b);
+ //if(demuxer->audio->id==-1) demuxer->audio->id=streamh.stream_no & 0x7F;
+ break;
+ }
+ case ASF_GUID_PREFIX_video_stream: {
+ sh_video_t* sh_video=new_sh_video(demuxer,streamh.stream_no & 0x7F);
+ int len=streamh.type_size-(4+4+1+2);
+// sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
+ sh_video->bih=calloc((len<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):len,1);
+ memcpy(sh_video->bih,&buffer[4+4+1+2],len);
+ le2me_BITMAPINFOHEADER(sh_video->bih);
+ //sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
+ //sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
+ if(verbose>=1) print_video_header(sh_video->bih);
+ //asf_video_id=streamh.stream_no & 0x7F;
+ //if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F;
+ break;
+ }
+ }
+ // stream-specific data:
+ // stream_read(demuxer->stream,(char*) buffer,streamh.stream_size);
+ break;
+// case ASF_GUID_PREFIX_header_2_0: return "guid_header_2_0";
+ case ASF_GUID_PREFIX_file_header: // guid_file_header
+ stream_read(demuxer->stream,(char*) &fileh,sizeof(fileh));
+ le2me_ASF_file_header_t(&fileh);
+ mp_msg(MSGT_HEADER,MSGL_V,"ASF: packets: %d flags: %d pack_size: %d frame_size: %d\n",(int)fileh.packets,(int)fileh.flags,(int)fileh.packetsize,(int)fileh.frame_size);
+ asf_packetsize=fileh.packetsize;
+ asf_packet=malloc(asf_packetsize); // !!!
+ bre