From d34041569e71fc9bd772354e94dc9d16061072a5 Mon Sep 17 00:00:00 2001 From: arpi_esp Date: Sat, 24 Feb 2001 20:28:24 +0000 Subject: Initial revision git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2 b3059339-0415-0410-9bf9-f77b7e298cf2 --- demux_asf.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 demux_asf.c (limited to 'demux_asf.c') diff --git a/demux_asf.c b/demux_asf.c new file mode 100644 index 0000000000..ed8532a7a1 --- /dev/null +++ b/demux_asf.c @@ -0,0 +1,268 @@ +// ASF file parser for DEMUXER v0.3 by A'rpi/ESP-team + +// based on asf file-format doc by Eugene [http://divx.euro.ru] + +//static float avi_pts_frametime=1.0f/25.0f; +//static float avi_audio_pts=0; +//static float avi_video_pts=0; + +//static int skip_video_frames=0; + +typedef struct __attribute__((packed)) { + unsigned char streamno; + unsigned char seq; + unsigned long x; + unsigned char flag; +} ASF_segmhdr_t; + + +static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,unsigned long time,unsigned short dur,int offs){ + int d; +// int len; + int skip; + float pts=0; + unsigned char c=0; + demux_stream_t *ds=NULL; + + if(verbose>=4) printf("demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len); + +#if 0 + if(demux->video->id==-1) { + demux->video->id=asf_video_id; + if(verbose) printf("ASF video ID = %d\n",demux->video->id); + } + if(demux->audio->id==-1) + if(id!=asf_video_id && id!=demux->video->id){ + demux->audio->id=id; + if(verbose) printf("ASF audio ID = %d\n",demux->audio->id); + } +#endif + + if(id==demux->audio->id){ + // audio + ds=demux->audio; + } else + if(id==demux->video->id){ + // video + ds=demux->video; + } + + if(ds){ + if(ds->asf_packet){ + if(ds->asf_seq!=seq){ + // closed segment, finalize packet: + if(ds==demux->audio) + if(asf_scrambling_h>1 && asf_scrambling_w>1) + asf_descrambling(ds->asf_packet->buffer,ds->asf_packet->len); + ds_add_packet(ds,ds->asf_packet); + ds->asf_packet=NULL; + } else { + // append data to it! + demux_packet_t* dp=ds->asf_packet; + if(dp->len!=offs && offs!=-1) printf("warning! fragment.len=%d BUT next fragment offset=%d \n",dp->len,offs); + dp->buffer=realloc(dp->buffer,dp->len+len); + memcpy(dp->buffer+dp->len,data,len); + if(verbose>=4) printf("data appended! %d+%d\n",dp->len,len); + dp->len+=len; + // we are ready now. + return 1; + } + } + // create new packet: + { demux_packet_t* dp; + if(offs>0){ + printf("warning! broken fragment, %d bytes missing \n",offs); + return 0; + } + dp=new_demux_packet(len); + memcpy(dp->buffer,data,len); + dp->pts=time*0.001f; +// if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur); + dp->pos=demux->filepos; + ds->asf_packet=dp; + ds->asf_seq=seq; + // we are ready now. + return 1; + } + } + + return 0; +} + +//static int num_elementary_packets100=0; +//static int num_elementary_packets101=0; + +// return value: +// 0 = EOF or no stream found +// 1 = successfully read a packet +int demux_asf_fill_buffer(demuxer_t *demux){ +unsigned int id=0; +unsigned int len; +int skipped=0; +int max_packs=128; +int ret=0; + + demux->filepos=stream_tell(demux->stream); + if(demux->filepos>=demux->endpos){ + demux->stream->eof=1; + return 0; + } + + stream_read(demux->stream,asf_packet,(int)fileh.packetsize); + if(demux->stream->eof) return 0; // EOF + + if(asf_packet[0]==0x82){ + unsigned char flags=asf_packet[3]; + unsigned char segtype=asf_packet[4]; + unsigned char* p=&asf_packet[5]; + unsigned char* p_end=p+(int)fileh.packetsize; + unsigned long time; + unsigned short duration; + int segs=1; + unsigned char segsizetype=0x80; + int seg; + int padding=0; + int plen; + + if(verbose>1){ + int i; + for(i=0;i<16;i++) printf(" %02X",asf_packet[i]); + printf("\n"); + } + + //if(segtype!=0x5d) printf("Warning! packet[4] != 0x5d \n"); + + // Calculate packet size (plen): + if(flags&0x40){ + // Explicit (absoulte) packet size + plen=p[0]|(p[1]<<8); p+=2; + if(verbose>1)printf("Explicit packet size specified: %d \n",plen); + if(plen>fileh.packetsize) printf("Warning! plen>packetsize! (%d>%d) \n",plen,(int)fileh.packetsize); + if(flags&(8|16)){ + padding=p[0];p++; + if(flags&16){ padding|=p[0]<<8; p++;} + if(verbose)printf("Warning! explicit=%d padding=%d \n",plen,fileh.packetsize-padding); + } + } else { + // Padding (relative) size + if(flags&8){ + padding=p[0];++p; + } else + if(flags&16){ + padding=p[0]|(p[1]<<8);p+=2; + } + plen=fileh.packetsize-padding; + } + + time=*((unsigned long*)p);p+=4; + duration=*((unsigned short*)p);p+=2; + if(flags&1){ + segsizetype=p[0] & 0xC0; + segs=p[0] & 0x3F; + ++p; + } + if(verbose>=4) printf("%08X: flag=%02X segs=%d pad=%d time=%d dur=%d\n", + demux->filepos,flags,segs,padding,time,duration); + for(seg=0;seg=p_end) printf("Warning! invalid packet 1, sig11 coming soon...\n"); + + if(verbose>1){ + int i; + printf("seg %d:",seg); + for(i=0;i<16;i++) printf(" %02X",p[i]); + printf("\n"); + } + + streamno=p[0]&0x7F; + seq=p[1]; + p+=2; + + switch(segtype){ + case 0x55: + x=*((unsigned char*)p); + p++; + break; + case 0x59: + x=*((unsigned short*)p); + p+=2; + break; + case 0x5D: + x=*((unsigned long*)p); + p+=4; + break; + default: + printf("Warning! unknown segtype == 0x%2X \n",segtype); + } + + type=p[0]; p++; // 0x01: grouping 0x08: single + + switch(type){ + case 0x01: + //printf("grouping: %02X \n",p[0]); + ++p; // skip unknown byte + break; + case 0x08: + //printf("!!! obj_length = %d\n",*((unsigned long*)p)); + p+=4; + time2=*((unsigned long*)p);p+=4; + break; + default: + printf("unknown segment type: 0x%02X \n",type); + } + + if(flags&1){ + // multiple segments + if(segsizetype==0x40){ + len=*((unsigned char*)p);p++; // 1 byte + } else { + len=*((unsigned short*)p);p+=2; // 2 byte + } + } else { + // single segment + len=plen-(p-asf_packet); + } + if(len<0 || (p+len)>=p_end){ + printf("ASF_parser: warning! segment len=%d\n",len); + } + if(verbose>=4) printf(" seg #%d: streamno=%d seq=%d type=%02X len=%d\n",seg,streamno,seq,type,len); + + switch(type){ + case 0x01: + // GROUPING: + //printf("ASF_parser: warning! grouping (flag=1) not yet supported!\n",len); + //printf(" total: %d \n",len); + while(len>0){ + int len2=p[0]; + p++; + //printf(" group part: %d bytes\n",len2); + demux_asf_read_packet(demux,p,len2,streamno,seq,x,duration,-1); + p+=len2; + len-=len2+1; + } + if(len!=0){ + printf("ASF_parser: warning! groups total != len\n"); + } + break; + case 0x08: + // NO GROUPING: + //printf("fragment offset: %d \n",sh->x); + demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x); + p+=len; + break; + } + + } // for segs + return 1; // success + } + + printf("%08X: UNKNOWN TYPE %02X %02X %02X %02X %02X...\n",demux->filepos,asf_packet[0],asf_packet[1],asf_packet[2],asf_packet[3],asf_packet[4]); + return 0; +} -- cgit v1.2.3