Mercurial > mplayer.hg
changeset 1342:baf646413408
ASF support for non-x86 cpus
author | jkeil |
---|---|
date | Thu, 19 Jul 2001 15:15:21 +0000 |
parents | 5628c341f4ff |
children | ecaa8d0f1649 |
files | asf.h asfheader.c aviheader.c demux_asf.c |
diffstat | 4 files changed, 163 insertions(+), 180 deletions(-) [+] |
line wrap: on
line diff
--- a/asf.h Wed Jul 18 01:28:01 2001 +0000 +++ b/asf.h Thu Jul 19 15:15:21 2001 +0000 @@ -1,9 +1,12 @@ #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) @@ -114,10 +117,60 @@ } 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); \ +} +#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) /**/ +#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
--- a/asfheader.c Wed Jul 18 01:28:01 2001 +0000 +++ b/asfheader.c Thu Jul 19 15:15:21 2001 +0000 @@ -15,58 +15,28 @@ #include "codec-cfg.h" #include "stheader.h" - +#include "aviheader.h" +#include "asf.h" -// BB: Moved to asf.h --------------------- FROM HERE ------------------- -#ifndef STREAMING -typedef struct __attribute__((packed)) { - unsigned char guid[16]; - unsigned long long size; -} ASF_obj_header_t; - -typedef struct __attribute__((packed)) { - ASF_obj_header_t objh; - unsigned int cno; // number of subchunks - unsigned char v1; // unknown (0x01) - unsigned char v2; // unknown (0x02) -} ASF_header_t; +#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 -typedef struct __attribute__((packed)) { - unsigned char client[16]; // Client GUID - unsigned long long file_size; - unsigned long long creat_time; //File creation time FILETIME 8 - unsigned long long packets; //Number of packets UINT64 8 - unsigned long long end_timestamp; //Timestamp of the end position UINT64 8 - unsigned long long duration; //Duration of the playback UINT64 8 - unsigned long start_timestamp; //Timestamp of the start position UINT32 4 - unsigned long unk1; //Unknown, maybe reserved ( usually contains 0 ) UINT32 4 - unsigned long flags; //Unknown, maybe flags ( usually contains 2 ) UINT32 4 - unsigned long packetsize; //Size of packet, in bytes UINT32 4 - unsigned long packetsize2; //Size of packet ( confirm ) UINT32 4 - unsigned long frame_size; //Size of uncompressed video frame UINT32 4 -} ASF_file_header_t; +#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 -typedef struct __attribute__((packed)) { - unsigned char type[16]; // Stream type (audio/video) GUID 16 - unsigned char concealment[16]; // Audio error concealment type GUID 16 - unsigned long long unk1; // Unknown, maybe reserved ( usually contains 0 ) UINT64 8 - unsigned long type_size; //Total size of type-specific data UINT32 4 - unsigned long stream_size; //Size of stream-specific data UINT32 4 - unsigned short stream_no; //Stream number UINT16 2 - unsigned long unk2; //Unknown UINT32 4 -} ASF_stream_header_t; - -typedef struct __attribute__((packed)) { - unsigned short title_size; - unsigned short author_size; - unsigned short copyright_size; - unsigned short comment_size; - unsigned short rating_size; -} ASF_content_description_t; -#else -#include "asf.h" -#endif -// BB: Moved to asf.h --------------------- TO HERE ------------------- static ASF_header_t asfh; static ASF_obj_header_t objh; @@ -98,25 +68,50 @@ printf("%s%s\n", name, string); } -static char* asf_chunk_type(unsigned char* guid){ - switch(*((unsigned int*)guid)){ - case 0xF8699E40: return "guid_audio_stream"; - case 0xBC19EFC0: return "guid_video_stream"; - case 0x49f1a440: return "guid_audio_conceal_none"; - case 0xbfc3cd50: return "guid_audio_conceal_interleave"; - case 0x75B22630: return "guid_header"; - case 0x75b22636: return "guid_data_chunk"; - case 0x33000890: return "guid_index_chunk"; - case 0xB7DC0791: return "guid_stream_header"; - case 0xD6E229D1: return "guid_header_2_0"; - case 0x8CABDCA1: return "guid_file_header"; +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; } - return NULL; } 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)){ @@ -142,20 +137,22 @@ 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(*((unsigned int*)&objh.guid)){ - case 0xB7DC0791: // guid_stream_header + switch(ASF_LOAD_GUID_PREFIX(objh.guid)){ + case ASF_GUID_PREFIX_stream_header: stream_read(demuxer->stream,(char*) &streamh,sizeof(streamh)); -if(verbose){ - printf("stream type: %s\n",asf_chunk_type(streamh.type)); - printf("stream concealment: %s\n",asf_chunk_type(streamh.concealment)); - printf("type: %d bytes, stream: %d bytes ID: %d\n",(int)streamh.type_size,(int)streamh.stream_size,(int)streamh.stream_no); - printf("unk1: %lX unk2: %X\n",(unsigned long)streamh.unk1,(unsigned int)streamh.unk2); - printf("FILEPOS=0x%X\n",stream_tell(demuxer->stream)); -} + le2me_ASF_stream_header_t(&streamh); + if(verbose){ + printf("stream type: %s\n",asf_chunk_type(streamh.type)); + printf("stream concealment: %s\n",asf_chunk_type(streamh.concealment)); + printf("type: %d bytes, stream: %d bytes ID: %d\n",(int)streamh.type_size,(int)streamh.stream_size,(int)streamh.stream_no); + printf("unk1: %lX unk2: %X\n",(unsigned long)streamh.unk1,(unsigned int)streamh.unk2); + printf("FILEPOS=0x%X\n",stream_tell(demuxer->stream)); + } if(streamh.type_size>1024 || streamh.stream_size>1024){ printf("FATAL: header size bigger than 1024 bytes!\n"); printf("Please contact mplayer authors, and upload/send this file.\n"); @@ -163,13 +160,14 @@ } // type-specific data: stream_read(demuxer->stream,(char*) buffer,streamh.type_size); - switch(*((unsigned int*)&streamh.type)){ - case 0xF8699E40: { // guid_audio_stream + 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((*((unsigned int*)&streamh.concealment))==0xbfc3cd50){ + 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]; @@ -182,12 +180,13 @@ //if(demuxer->audio->id==-1) demuxer->audio->id=streamh.stream_no & 0x7F; break; } - case 0xBC19EFC0: { // guid_video_stream + 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); @@ -199,25 +198,27 @@ // stream-specific data: // stream_read(demuxer->stream,(char*) buffer,streamh.stream_size); break; -// case 0xD6E229D1: return "guid_header_2_0"; - case 0x8CABDCA1: // guid_file_header +// 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); if(verbose) printf("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); // !!! break; - case 0x75b22636: // guid_data_chunk + case ASF_GUID_PREFIX_data_chunk: // guid_data_chunk demuxer->movi_start=stream_tell(demuxer->stream)+26; demuxer->movi_end=endpos; if(verbose>=1) printf("Found movie at 0x%X - 0x%X\n",demuxer->movi_start,demuxer->movi_end); break; -// case 0x33000890: return "guid_index_chunk"; +// case ASF_GUID_PREFIX_index_chunk: return "guid_index_chunk"; - case 0x75b22633: // Content description + case ASF_GUID_PREFIX_content_desc: // Content description if(verbose){ char *string=NULL; stream_read(demuxer->stream,(char*) &contenth,sizeof(contenth)); + le2me_ASF_content_description_t(&contenth); // extract the title if( contenth.title_size!=0 ) { string=(char*)malloc(contenth.title_size); @@ -255,7 +256,7 @@ } // switch GUID - if((*((unsigned int*)&objh.guid))==0x75b22636) break; // movi chunk + if(ASF_LOAD_GUID_PREFIX(objh.guid)==ASF_GUID_PREFIX_data_chunk) break; // movi chunk if(!stream_seek(demuxer->stream,endpos)) break; } // while EOF
--- a/aviheader.c Wed Jul 18 01:28:01 2001 +0000 +++ b/aviheader.c Thu Jul 19 15:15:21 2001 +0000 @@ -15,86 +15,10 @@ #include "codec-cfg.h" #include "bswap.h" #include "stheader.h" +#include "aviheader.h" #define MIN(a,b) (((a)<(b))?(a):(b)) -/* - * Some macros to swap little endian structures read from an AVI file - * into machine endian format - */ -#ifdef WORDS_BIGENDIAN -#define le2me_MainAVIHeader(h) { \ - (h)->dwMicroSecPerFrame = le2me_32((h)->dwMicroSecPerFrame); \ - (h)->dwMaxBytesPerSec = le2me_32((h)->dwMaxBytesPerSec); \ - (h)->dwPaddingGranularity = le2me_32((h)->dwPaddingGranularity); \ - (h)->dwFlags = le2me_32((h)->dwFlags); \ - (h)->dwTotalFrames = le2me_32((h)->dwTotalFrames); \ - (h)->dwInitialFrames = le2me_32((h)->dwInitialFrames); \ - (h)->dwStreams = le2me_32((h)->dwStreams); \ - (h)->dwSuggestedBufferSize = le2me_32((h)->dwSuggestedBufferSize); \ - (h)->dwWidth = le2me_32((h)->dwWidth); \ - (h)->dwHeight = le2me_32((h)->dwHeight); \ -} - -#define le2me_AVIStreamHeader(h) { \ - (h)->fccType = le2me_32((h)->fccType); \ - (h)->fccHandler = le2me_32((h)->fccHandler); \ - (h)->dwFlags = le2me_32((h)->dwFlags); \ - (h)->wPriority = le2me_16((h)->wPriority); \ - (h)->wLanguage = le2me_16((h)->wLanguage); \ - (h)->dwInitialFrames = le2me_32((h)->dwInitialFrames); \ - (h)->dwScale = le2me_32((h)->dwScale); \ - (h)->dwRate = le2me_32((h)->dwRate); \ - (h)->dwStart = le2me_32((h)->dwStart); \ - (h)->dwLength = le2me_32((h)->dwLength); \ - (h)->dwSuggestedBufferSize = le2me_32((h)->dwSuggestedBufferSize); \ - (h)->dwQuality = le2me_32((h)->dwQuality); \ - (h)->dwSampleSize = le2me_32((h)->dwSampleSize); \ - le2me_RECT(&(h)->rcFrame); \ -} -#define le2me_RECT(h) { \ - (h)->left = le2me_16((h)->left); \ - (h)->top = le2me_16((h)->top); \ - (h)->right = le2me_16((h)->right); \ - (h)->bottom = le2me_16((h)->bottom); \ -} -#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); \ -} -#define le2me_AVIINDEXENTRY(h) { \ - (h)->ckid = le2me_32((h)->ckid); \ - (h)->dwFlags = le2me_32((h)->dwFlags); \ - (h)->dwChunkOffset = le2me_32((h)->dwChunkOffset); \ - (h)->dwChunkLength = le2me_32((h)->dwChunkLength); \ -} -#else -#define le2me_MainAVIHeader(h) /**/ -#define le2me_AVIStreamHeader(h) /**/ -#define le2me_RECT(h) /**/ -#define le2me_BITMAPINFOHEADER(h) /**/ -#define le2me_WAVEFORMATEX(h) /**/ -#define le2me_AVIINDEXENTRY(h) /**/ -#endif - static MainAVIHeader avih;
--- a/demux_asf.c Wed Jul 18 01:28:01 2001 +0000 +++ b/demux_asf.c Thu Jul 19 15:15:21 2001 +0000 @@ -6,9 +6,26 @@ extern int verbose; // defined in mplayer.c #include "stream.h" +#include "asf.h" #include "demuxer.h" +/* + * Load 16/32-bit values in little endian byte order + * from an unaligned address + */ +#ifdef ARCH_X86 +#define LOAD_LE32(p) (*(unsigned int*)(p)) +#define LOAD_LE16(p) (*(unsigned short*)(p)) +#else +#define LOAD_LE32(p) (((unsigned char*)(p))[0] | \ + ((unsigned char*)(p))[1]<< 8 | \ + ((unsigned char*)(p))[2]<<16 | \ + ((unsigned char*)(p))[3]<<24 ) +#define LOAD_LE16(p) (((unsigned char*)(p))[0] | \ + ((unsigned char*)(p))[1]<<8) +#endif + // defined at asfheader.c: extern unsigned char* asf_packet; extern int asf_scrambling_h; @@ -25,18 +42,6 @@ //static int skip_video_frames=0; -//BB: Moved to asf.h --------- FROM HERE -------- -#ifndef STREAMING -typedef struct __attribute__((packed)) { - unsigned char streamno; - unsigned char seq; - unsigned long x; - unsigned char flag; -} ASF_segmhdr_t; -#else -#include "asf.h" -#endif -//BB: Moved to asf.h --------- TO HERE -------- static void asf_descrambling(unsigned char *src,int len){ unsigned char *dst=malloc(len); @@ -172,7 +177,7 @@ // Calculate packet size (plen): if(flags&0x40){ // Explicit (absoulte) packet size - plen=p[0]|(p[1]<<8); p+=2; + plen=LOAD_LE16(p); p+=2; if(verbose>1)printf("Explicit packet size specified: %d \n",plen); if(plen>asf_packetsize) printf("Warning! plen>packetsize! (%d>%d) \n",plen,asf_packetsize); if(flags&(8|16)){ @@ -186,13 +191,13 @@ padding=p[0];++p; } else if(flags&16){ - padding=p[0]|(p[1]<<8);p+=2; + padding=LOAD_LE16(p);p+=2; } plen=asf_packetsize-padding; } - time=*((unsigned long*)p);p+=4; - duration=*((unsigned short*)p);p+=2; + time = LOAD_LE32(p); p+=4; + duration = LOAD_LE16(p); p+=2; if(flags&1){ segsizetype=p[0] & 0xC0; segs=p[0] & 0x3F; @@ -230,11 +235,11 @@ p++; break; case 0x59: - x=*((unsigned short*)p); + x=LOAD_LE16(p); p+=2; break; case 0x5D: - x=*((unsigned long*)p); + x=LOAD_LE32(p); p+=4; break; default: @@ -252,7 +257,7 @@ case 0x08: //printf("!!! obj_length = %d\n",*((unsigned long*)p)); p+=4; - time2=*((unsigned long*)p);p+=4; + time2=LOAD_LE32(p);p+=4; break; default: printf("unknown segment type: 0x%02X \n",type); @@ -261,9 +266,9 @@ if(flags&1){ // multiple segments if(segsizetype==0x40){ - len=*((unsigned char*)p);p++; // 1 byte + len=*((unsigned char*)p);p++; // 1 byte } else { - len=*((unsigned short*)p);p+=2; // 2 byte + len=LOAD_LE16(p);p+=2; // 2 byte } } else { // single segment