Instantly share code, notes, and snippets.

Embed
What would you like to do?
Unfinished FLV parser
#include <stdio.h>
#include <fcntl.h>
typedef struct{
char unsigned F;
char unsigned L;
char unsigned V;
char unsigned version;
char unsigned video:1;
char unsigned res2:1;
char unsigned audio:1;
char unsigned res1:5;
int unsigned size;
}Header;
typedef struct{
int unsigned length:24;
int unsigned type:5;
int unsigned res:2;
int unsigned filter:1;
int unsigned ts:24;
int unsigned tsEx:8;
char unsigned id[3];
//(A/V)TAG
//enc header
//filter param
//DATA
}Tag;
typedef struct{
char unsigned ch:1;
char unsigned bps:1;
char unsigned khz:2;
char unsigned fmt:4;
//char aac;
}ATag;
typedef struct{
char unsigned codec:4;
char unsigned type:4;
//if(codec==7)
// char AVCtype:1;
// char ch:1;
}VTag;
typedef struct{
char unsigned ver;
char unsigned AVCprofile;
char unsigned AVCprofileCompatibility;
char unsigned AVClevel;
char unsigned len:2;
char unsigned res:6;//111111
char unsigned num:5;
char unsigned res:3;//111
}DCR;//AVCDecoderConfigurationRecord #define BE(x) ((x>>24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x<<24))
#define BE16(x) (((x<<8)&0xFF00)|((x>>8)&0xFF))
//#define printf(...); ;
int fd;
//unsigned BE(unsigned*x){return (x[0]>>24) | ((x[0]<<8) & 0x00FF0000) | ((x[0]>>8) & 0x0000FF00) | (x[0]<<24);}
unsigned*Astsz,*Astco,*Vstsz,*Vstco;
unsigned Alen=0,Vlen=0;
parseA(int size){
ATag au;
int end=lseek(fd,0,SEEK_CUR)+size;
read(fd,&au,sizeof(au));size-=sizeof(au);
if(au.fmt==10){
char type;
read(fd,&type,sizeof(char));size-=sizeof(char);
//printf("%s ",type?"data":"info",size);
if(!type)return lseek(fd,end,SEEK_SET);//AAC header
}
Alen++;
Astsz=(unsigned*)realloc(Astsz,Alen*sizeof(unsigned));
Astco=(unsigned*)realloc(Astco,Alen*sizeof(unsigned));
Astsz[Alen-1]=size;
Astco[Alen-1]=end-size;
//printf("[%i] %i %s %s",au.fmt,au.khz,au.bps?"16b":"8b",au.ch?"stereo":"mono");
return lseek(fd,end,SEEK_SET);
}
parseV(int size){
VTag vi;
int end=lseek(fd,0,SEEK_CUR)+size;
read(fd,&vi,sizeof(VTag)); size-=sizeof(VTag);
// printf("video [%i]",vi.codec);
if(vi.codec==7){
unsigned char pkgType,compoTime[3];
read(fd,&pkgType,sizeof(char));
// printf(" %s ",pkgType?"NALU":"header");
read(fd,&compoTime,sizeof(compoTime));
size-=sizeof(compoTime)+sizeof(char);
// if(pkgType==1)printf(" %03X",compoTime);
if(pkgType==0){//header
DCR cfg;
read(fd,&cfg,sizeof(DCR));//len+1=avc_nal_prefix_size
// printf("ver:%i ",cfg.ver);
// printf("profile:%02X ",cfg.AVCprofile);
// printf("compatibility:%02X ",cfg.AVCprofileCompatibility);
// printf("level:%02X ",cfg.AVClevel);
unsigned short sps_size,pps_size;unsigned char num;
read(fd,&sps_size,sizeof(sps_size));
unsigned char*sps=(unsigned char*)malloc((sps_size=BE16(sps_size)));
read(fd,sps,sizeof(sps_size));
read(fd,&num,sizeof(num));//numOfPictureParameterSets
read(fd,&pps_size,sizeof(sps_size));
unsigned char*pps=(unsigned char*)malloc((pps_size=BE16(pps_size)));
read(fd,pps,sizeof(pps_size));
return lseek(fd,end,SEEK_SET);
}
}
Vlen++;
Vstsz=(unsigned*)realloc(Vstsz,Vlen*sizeof(unsigned));
Vstco=(unsigned*)realloc(Vstco,Vlen*sizeof(unsigned));
Vstsz[Vlen-1]=size;
Vstco[Vlen-1]=end-size;
return lseek(fd,end,SEEK_SET);
}
parseS(int size){
// printf("%08X\n",lseek(fd,0,SEEK_CUR));
return lseek(fd,size,SEEK_CUR);
lseek(fd,size,SEEK_CUR);
// printf("script\n");
}
//#undef printf(...);
parseR(int size){
// printf("unk tagType %08X %i\n",size,type);
return lseek(fd,size,SEEK_CUR);// exit(0);
}
printInfo(){
printf("--- A U D I O --- --- V I D E O ---\n");
printf(" offset size offset size \n");
int max=Alen>Vlen?Alen:Vlen;
int i;for(i=0;i<max;i++){
if(i<Alen)printf("%08X %08X ",Astco[i],Astsz[i]);else printf(" ");
if(i<Vlen)printf("%08X %08X\n",Vstco[i],Vstsz[i]);else printf(" \n");
}
printf(" total %8i total %8i\n",Alen,Vlen);
}
int main(int argc,char* argv[]){
if(argc<2)return printf("Usage :flv-demuxer video.flv");
fd=open("240.flv",O_RDONLY,0777);
int len=lseek(fd,0,SEEK_END);
lseek(fd,9,SEEK_SET);
Tag t;int i=0;
do{
read(fd,&i,sizeof(i));//prev tag size
read(fd,&t,11);//real sizeof(Tag)
i=BE((unsigned)t);
(&t)[0]=(Tag)i;
// printf("\n%2i %08X:",t.type,lseek(fd,0,SEEK_CUR));
// if(size>0xAA0D)puts("strange");
switch(t.type){//7=sizeof(Tag)-sizeof(Tag.length)
case 8:parseA(t.length);break;
case 9:parseV(t.length);break;
case 18:parseS(t.length);break;
default:printf("unk:%i %08X (%i)\n",t.type,lseek(fd,0,SEEK_CUR),t.length);parseR(t.length);break;
}
}while(lseek(fd,0,SEEK_CUR)<=len);
// printInfo();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment