Example #1
0
int main (int argc, char* argv[]){
    FILE *fp;
    wavheader *wh = malloc(sizeof(wavheader));
    
    if((fp = fopen(argv[1], "rb"))==NULL) {
        printf("ERROR: fopen\n");
        return 1;
    }
    
    if(getHeader(wh, fp)==1) { 
        printf("ERROR: getHeader\n");
        fclose(fp);
        free(wh);
        return 1;
    }
    
    printWavHeader(wh);
    
    fclose(fp);
    free(wh);

    return 0;
}
void OpenDMLHeader::Dump( void )
{
        printf(  "Main header\n" );
        printf(  "______________________\n" );  

#define X_DUMP(x) printf(#x":\t\t:%ld\n",_mainaviheader.x);
    	X_DUMP(dwStreams);
    	X_DUMP(dwMicroSecPerFrame) ;
	X_DUMP(dwMaxBytesPerSec);
    	X_DUMP(dwPaddingGranularity);
    	X_DUMP(dwFlags);
    	X_DUMP(dwTotalFrames);
    	X_DUMP(dwInitialFrames);	
    	X_DUMP(dwWidth);
    	X_DUMP(dwHeight);
 	printf("\n");
#undef X_DUMP
#define X_DUMP(x) printf("\n "#x":\t\t:%ld",_videostream.x);

				
	printf(  "video stream attached:\n" );
	printf(  "______________________\n" );	
	printf(" Extra Data  : %ld",_videoExtraLen);
	if(_videoExtraLen)
	{
		mixDump( _videoExtraData, _videoExtraLen);
	}

	printf("\n fccType     :");
	fourCC::print(_videostream.fccType);
	printf("\n fccHandler :");
	fourCC::print(_videostream.fccHandler);

	X_DUMP(dwFlags);
	X_DUMP(dwInitialFrames);
	X_DUMP(dwRate);
	X_DUMP(dwStart);
	X_DUMP(dwSampleSize);
	X_DUMP(dwScale);
	X_DUMP(dwLength); 
    	X_DUMP(dwQuality);
	X_DUMP(dwSampleSize);
	printf("\n");
	  	  
        printBih(&_video_bih);

        /*****************************************************************
                Dump infos about all audio tracks found

        ******************************************************************/
        for(int i=0;i<_nbAudioTracks;i++)
     	{
#undef X_DUMP
#define X_DUMP(x) printf("\n "#x":\t\t:%ld",_audioTracks[i].avistream->x);



	   printf(  "\naudio stream attached:\n" );
	   printf(  "______________________\n" );


	  printf("\n fccType     :");
	  fourCC::print(_audioTracks[i].avistream->fccType);
	  printf("\n fccHandler :");
	  fourCC::print(_audioTracks[i].avistream->fccHandler);
	  printf("\n fccHandler :0x%lx", _audioTracks[i].avistream->fccHandler);


	  X_DUMP(dwFlags);
	  X_DUMP(dwInitialFrames);
	  X_DUMP(dwRate);
	  X_DUMP(dwScale);
	  X_DUMP(dwStart);
	  X_DUMP(dwLength);
	  X_DUMP(dwSuggestedBufferSize);
	  X_DUMP(dwQuality);
	  X_DUMP(dwSampleSize);
	  
	      	
	  
#undef X_DUMP

        printWavHeader(_audioTracks[i].wavHeader);
        printf(" Extra Data  : %ld\n",_audioTracks[i].extraDataLen);
	if(_audioTracks[i].extraDataLen)
	{
		mixDump( _audioTracks[i].extraData, _audioTracks[i].extraDataLen);
	}
	printf("\n");

      }
}
/**
        \fn parseStbl
        \brief parse sample table. this is the most important function.
*/
uint8_t       MP4Header::parseStbl(void *ztom,uint32_t trackType,uint32_t w,uint32_t h,uint32_t trackScale)
{
  adm_atom *tom=(adm_atom *)ztom;
  ADMAtoms id;
  uint32_t container;
  MPsampleinfo  info;
  
  
  memset(&info,0,sizeof(info));

  
  printf("<<Parsing Stbl>>\n");
  while(!tom->isDone())
  {
     adm_atom son(tom);
     if(!ADM_mp4SearchAtomName(son.getFCC(), &id,&container))
     {
       adm_printf(ADM_PRINT_DEBUG,"[STBL]Found atom %s unknown\n",fourCC::tostringBE(son.getFCC()));
       son.skipAtom();
       continue;
     }
     switch(id)
     {
       case ADM_MP4_STSS:  // Sync sample atom (i.e. keyframes)
       {
          son.read32();
          info.nbSync=son.read32();
          printf("Stss:%u\n",info.nbSync);
          if(info.nbSync)
          {
                  info.Sync=new uint32_t[info.nbSync];
                  for(int i=0;i<info.nbSync;i++)
                  {
                          info.Sync[i]=son.read32();
                  }
          }
          break;
         
       }
       case ADM_MP4_STTS: 
            {
                printf("stts:%lu\n",son.read32()); // version & flags
                info.nbStts=son.read32();
                printf("Time stts atom found (%lu)\n",info.nbStts);
                printf("Using myscale %lu\n",trackScale);
                info.SttsN=new uint32_t[info.nbStts];
                info.SttsC=new uint32_t[info.nbStts];
                double dur;
                for(int i=0;i<info.nbStts;i++)
                {
                        
                        info.SttsN[i]=son.read32();
                        info.SttsC[i]=son.read32();
                        adm_printf(ADM_PRINT_VERY_VERBOSE,"stts: count:%u size:%u (unscaled)\n",info.SttsN[i],info.SttsC[i]);	
                        //dur*=1000.*1000.;; // us
                        //dur/=myScale;
                }                
            }
            break;
       case ADM_MP4_STSC:
            {
                son.read32();
                info.nbSc=son.read32();
                info.Sc=new uint32_t[info.nbSc];
                info.Sn=new uint32_t[info.nbSc];
                for(int j=0;j<info.nbSc;j++)
                {

                        info.Sc[j]=son.read32();
                        info.Sn[j]=son.read32();
                        son.read32();
                        adm_printf(ADM_PRINT_VERY_VERBOSE,"\t sc  %d : sc start:%u sc count: %u\n",j,info.Sc[j],info.Sn[j]);
                }

            }
            break;
       case ADM_MP4_STSZ:
          {
            uint32_t n;
              son.read32();
              n=son.read32();
              info.nbSz=son.read32();
              info.SzIndentical=0;
              printf("%lu frames /%lu nbsz..\n",n,info.nbSz);
              if(n)
                      {
                            adm_printf(ADM_PRINT_VERY_VERBOSE,"\t\t%lu frames of the same size %lu , n=%lu\n",
                                info.nbSz,info.SzIndentical,n);
                            info.SzIndentical=n;
                            info.Sz=NULL;
                      }
              else
              {
                      info.Sz=new uint32_t[info.nbSz];
                      for(int j=0;j<info.nbSz;j++)
                      {
                                      info.Sz[j]=son.read32();
                      }
              }
          }
          break;
           case ADM_MP4_CTTS: // Composition time to sample             
            {
                uint32_t n,i,j,k,v;
                
                  printf("ctts:%lu\n",son.read32()); // version & flags
                  n=son.read32();
                  if(n==1) // all the same , ignore
                  {
                    break;
                  }
                uint32_t *values=new uint32_t [n];
                uint32_t *count=new uint32_t [n];
                for(i=0;i<n;i++)
                {
                    count[i]=son.read32();
                    values[i]=son.read32();
                }
                uint32_t sum=0;
                for(i=0;i<n;i++)
                {
                    sum+=count[i];
                }
                info.Ctts=new uint32_t[sum+1]; // keep a safe margin
                
                for(i=0;i<n;i++)
                {
                    if(i<20)
                    {
                        adm_printf(ADM_PRINT_VERY_VERBOSE,"Ctts: nb: %u (%x) val:%u (%x)\n",count[i],count[i],values[i],values[i]);   
                    }
                    for(k=0;k<count[i];k++)
                    {
                        info.Ctts[info.nbCtts++]=values[i];
                    }
                }
                delete [] values;
                delete [] count;
                if(!info.nbCtts)
                {
                    delete [] info.Ctts;
                    info.Ctts=NULL;
                    printf("Destroying Ctts, seems invalid\n");
                }
                ADM_assert(info.nbCtts<sum+1);
                printf("Found %u elements\n",info.nbCtts);
            }
            break;  
       case ADM_MP4_STCO:
       {
          son.read32();
          info.nbCo=son.read32();
          printf("\t\tnbCo:%u\n",info.nbCo);
          info.Co=new uint32_t[info.nbCo];
          for(int j=0;j< info.nbCo;j++)
          {
                  info.Co[j]=son.read32();
                  adm_printf(ADM_PRINT_VERY_VERBOSE,"Chunk offset : %u / %u  : %u\n",  j,info.nbCo,info.Co[j]);
          }

       }
       break;
       case ADM_MP4_STCO64:
       {
         printf("Incomplete support for 64 bits quicktime!!\n");
          son.read32();
          info.nbCo=son.read32();
          printf("\t\tnbCo:%u\n",info.nbCo);
          info.Co=new uint32_t[info.nbCo];
          for(int j=0;j< info.nbCo;j++)
          {
                  son.read32(); // Ignore MSB
                  info.Co[j]=son.read32();
                  adm_printf(ADM_PRINT_VERY_VERBOSE,"Chunk offset : %u / %u  : %lu\n",  j,info.nbCo,info.Co[j]);
          }

       }
       break;
       case ADM_MP4_STSD:
       {
                son.read32(); // flags & version
                int nbEntries=son.read32();
                int left;
                adm_printf(ADM_PRINT_DEBUG,"[STSD]Found %d entries\n",nbEntries);
                for(int i=0;i<nbEntries;i++)
                {
                   int entrySize=son.read32();
                   int entryName=son.read32();
                   left=entrySize-8;
                   if(i || (trackType==TRACK_VIDEO && _videoFound) || (trackType==TRACK_OTHER))
                   {
                    son.skipBytes(left); 
                    printf("[STSD] ignoring %s, size %u\n",fourCC::tostringBE(entryName),entrySize);
                    if(trackType==TRACK_OTHER) printf("[STSD] because track=other\n");
                    continue;
                   }
                   switch(trackType)
                   {
                     case TRACK_VIDEO:
                     {
                          uint32_t lw=0,lh=0;
                                printf("[STSD] VIDEO %s, size %u\n",fourCC::tostringBE(entryName),entrySize);
                                son.skipBytes(8);  // reserved etc..
                                left-=8;
                                son.read32(); // version/revision
                                left-=4;
                                printf("[STSD] vendor %s\n",fourCC::tostringBE(son.read32()));
                                left-=4;
                                
                                son.skipBytes(8); // spatial qual etc..
                                left-=8;
                                
                                printf("[STSD] width :%u\n",lw=son.read16());
                                printf("[STSD] height :%u\n",lh=son.read16());
                                left-=4;
                                
                                son.skipBytes(8); // Resolution
                                left-=8;
                                
                                printf("[STSD] datasize :%u\n",son.read32());
                                left-=4;
                     
                                printf("[STSD] FrameCount :%u\n",son.read16());
                                left-=4;
                                
                                // Codec name
                                uint32_t u32=son.read();
                                if(u32>31) u32=31;
                                printf("Codec string :%d <",u32);
                                for(int i=0;i<u32;i++) printf("%c",son.read());
                                printf(">\n");
                                son.skipBytes(32-1-u32);
                                left-=32;
                                // 
                                son.read32();
                                left-=4; //Depth & color Id
                                //
                                printf("LEFT:%d\n",left);
                                
                                if(left>8)
                                {
//                                  decodeVideoAtom(&son); 
                                }
                                //
#define commonPart(x)             _videostream.fccHandler=_video_bih.biCompression=fourCC::get((uint8_t *)#x);
                      

                                 _video_bih.biWidth=_mainaviheader.dwWidth=lw ; 
                                  _video_bih.biHeight=_mainaviheader.dwHeight=lh; 
                                  _video_bih.biCompression=_videostream.fccHandler;

                                //
                                switch(entryName)
                                {
                                  case MKFCCR('m','j','p','b'):  //mjpegb
                                  {
                                        commonPart(MJPB);
                                        left=0;
                                  }
                                  break;
                                case MKFCCR('s','2','6','3'):  //s263 d263
                                  {
                                        commonPart(H263);
                                         adm_atom d263(&son);
                                         printf("Reading s253, got %s\n",fourCC::tostringBE(d263.getFCC()));
                                          left=0;
                                  }
                                  break;
                                   case MKFCCR('m','p','4','v'):  //mp4v
                                  {
                                        commonPart(DIVX);
                                         adm_atom esds(&son);
                                         printf("Reading esds, got %s\n",fourCC::tostringBE(esds.getFCC()));
                                         if(esds.getFCC()==MKFCCR('e','s','d','s'))
                                              decodeEsds(&esds,TRACK_VIDEO);
                                          left=0;
                                  }
                                        break;
                                  case MKFCCR('S','V','Q','3'):
                                  {//'SVQ3':
                                    // For SVQ3, the codec needs it to begin by SVQ3
                                    // We go back by 4 bytes to get the 4CC
                                            printf("SVQ3 atom found\n");
                                            VDEO.extraDataSize=left+4;
                                            VDEO.extraData=new uint8_t[ VDEO.extraDataSize ];
                                            if(!son.readPayload(VDEO.extraData+4,VDEO.extraDataSize-4 ))
                                            {
                                              GUI_Error_HIG(QT_TR_NOOP("Problem reading SVQ3 headers"), NULL);
                                            }
                                            VDEO.extraData[0]='S';
                                            VDEO.extraData[1]='V';
                                            VDEO.extraData[2]='Q';
                                            VDEO.extraData[3]='3';
                                            printf("SVQ3 Header size : %lu",_videoExtraLen);
                                            commonPart(SVQ3);
                                            left=0;
                                  }
                                            break;
                                  case MKFCCR('d','v','c',' ') : //'dvc ':
                                  case MKFCCR('d','v','c','p'): //'dvcp':
                                          commonPart(DVDS);
                                          break;
                                  case MKFCCR('c','v','i','d'): //'cvid'
                                          commonPart(cvid);
                                          break;
                                  case MKFCCR('h','2','6','3'): //'dv':
                                          commonPart(H263);
                                          break;
                                  case MKFCCR('M','J','P','G'): //'jpeg':
                                  case MKFCCR('j','p','e','g'): //'jpeg':
                                  case MKFCCR('A','V','D','J'): //'jpeg':
                                          commonPart(MJPG);
                                          break;
                                  case MKFCCR('a','v','c','1'): // avc1
                                          {
                                          commonPart(H264);
                                          // There is a avcC atom just after
                                          // configuration data for h264
                                          adm_atom avcc(&son);
                                          printf("Reading avcC, got %s\n",fourCC::tostringBE(avcc.getFCC()));
                                          int len,offset;
                                          VDEO.extraDataSize=avcc.getRemainingSize();
                                          VDEO.extraData=new uint8_t [VDEO.extraDataSize];
                                          avcc.readPayload(VDEO.extraData,VDEO.extraDataSize);
                                          printf("avcC size:%d\n",VDEO.extraDataSize);
                                    // Dump some info
                                        #define MKD8(x) VDEO.extraData[x]
                                        #define MKD16(x) ((MKD8(x)<<8)+MKD8(x+1))
                                        #define MKD32(x) ((MKD16(x)<<16)+MKD16(x+2))

                                            printf("avcC Revision             :%x\n", MKD8(0));
                                            printf("avcC AVCProfileIndication :%x\n", MKD8(1));
                                            printf("avcC profile_compatibility:%x\n", MKD8(2));
                                            printf("avcC AVCLevelIndication   :%x\n", MKD8(3));
        
                                            printf("avcC lengthSizeMinusOne   :%x\n", MKD8(4));
                                            printf("avcC NumSeq               :%x\n", MKD8(5));
                                            len=MKD16(6);
                                            printf("avcC sequenceParSetLen    :%x ",len );
                                            offset=8;
                                            mixDump(VDEO.extraData+offset,len);
        
                                            offset=8+len;
                                            printf("\navcC numOfPictureParSets  :%x\n", MKD8(offset++));
                                            len=MKD16(offset++);
                                            printf("avcC Pic len              :%x\n",len);
                                            mixDump(VDEO.extraData+offset,len);
                                            left=0;
                                            }
                                            break;
                                  default:
                                            if(left>10)
                                            {
                                                adm_atom avcc(&son);
                                                printf("Reading , got %s\n",fourCC::tostringBE(avcc.getFCC()));
                                                left=0;
                                                
                                            }
                                            break;
                                } // Entry name
                     }
                     break;
                     case TRACK_AUDIO:
                     {
                        uint32_t channels,bpp,encoding,fq,packSize;
                        
                                // Put some defaults
                                ADIO.encoding=1234;
                                ADIO.frequency=44100;
                                ADIO.byterate=128000>>3;
                                ADIO.channels=2;
                                ADIO.bitspersample=16;
                        
                                printf("[STSD] AUDIO <%s>, 0x%08x, size %u\n",fourCC::tostringBE(entryName),entryName,entrySize);
                                son.skipBytes(8);  // reserved etc..
                                left-=8;
                                
                                int atomVersion=son.read16();  // version
                                left-=2;
                                printf("[STSD]Revision       :%d\n",atomVersion);
                                son.skipBytes(2);  // revision
                                left-=2;
                                
                                printf("[STSD]Vendor         : %s\n",fourCC::tostringBE(son.read32()));
                                left-=4;
                                
                                ADIO.channels=channels=son.read16(); // Channel
                                left-=2;
                                printf("[STSD]Channels       :%d\n",ADIO.channels);
                                ADIO.bitspersample=bpp=son.read16(); // version/revision
                                left-=2;
                                printf("[STSD]Bit per sample :%d\n",bpp);
                                
                                encoding=son.read16(); // version/revision
                                left-=2;
                                printf("[STSD]Encoding       :%d\n",encoding);

                                packSize=son.read16(); // Packet Size
                                left-=2;
                                printf("[STSD]Packet size    :%d\n",encoding);
                                
                              
                                fq=ADIO.frequency=son.read16();
                                printf("[STSD]Fq:%u\n",fq);
                                if(ADIO.frequency<6000) ADIO.frequency=48000;
                                printf("[STSD]Fq       :%d\n",ADIO.frequency); // Bps
                                        son.skipBytes(2); // Fixed point
                                left-=4;
                                if(atomVersion)
                                {
                                    info.samplePerPacket=son.read32();
                                    info.bytePerPacket=son.read32();
                                    info.bytePerFrame=son.read32();
                                    printf("[STSD] Sample per packet %u\n",info.samplePerPacket);
                                    printf("[STSD] Bytes per packet  %u\n",info.bytePerPacket);
                                    printf("[STSD] Bytes per frame   %u\n",info.bytePerFrame);
                                    printf("[STSD] Bytes per sample   %u\n",son.read32());
                                    left-=16;
                                }else
                                {
                                  info.samplePerPacket=1;
                                  info.bytePerPacket=1;
                                  info.bytePerFrame=1;
                                }
                                switch(atomVersion)
                                {
                                  case 0:break;
                                  case 1: break;
                                  case 2:
                                          ADIO.frequency=44100; // FIXME
                                          ADIO.channels=son.read32();
                                          printf("Channels            :%d\n",ADIO.channels); // Channels
                                          printf("Tak(7F000)          :%x\n",son.read32()); // Channels
                                          printf("Bits  per channel   :%d\n",son.read32());  // Vendor
                                          printf("Format specific     :%x\n",son.read32());  // Vendor
                                          printf("Byte per audio packe:%x\n",son.read32());  // Vendor
                                          printf("LPCM                :%x\n",son.read32());  // Vendor
                                          left-=(5*4+4+16);
                                          break;
                                }
                                printf("[STSD] chan:%u bpp:%u encoding:%u fq:%u (left %u)\n",channels,bpp,encoding,fq,left);
#define audioCodec(x) ADIO.encoding=WAV_##x;
                                switch(entryName)
                                {
                                    
                                    case MKFCCR('t','w','o','s'):
                                            audioCodec(LPCM);
                                            ADIO.byterate=ADIO.frequency*ADIO.bitspersample*ADIO.channels/8;
                                            break;
                                                
                                    case MKFCCR('u','l','a','w'):
                                            audioCodec(ULAW);
                                            ADIO.byterate=ADIO.frequency;
                                            break;
                                    case MKFCCR('s','o','w','t'):
                                            audioCodec(PCM);
                                            ADIO.byterate=ADIO.frequency*ADIO.bitspersample*ADIO.channels/8;
                                            break;
                                    case MKFCCR('.','m','p','3'): //.mp3
                                            audioCodec(MP3);
                                            ADIO.byterate=128000>>3;
                                            break;
                                    case MKFCCR('r','a','w',' '):
                                            audioCodec(8BITS_UNSIGNED);
                                            ADIO.byterate=ADIO.frequency*ADIO.channels;
                                            break;
                                    case MKFCCR('s','a','m','r'):
                                    {
                                            audioCodec(AMRNB);
                                            ADIO.frequency=8000;
                                            ADIO.channels=1;
                                            ADIO.bitspersample=16;
                                            ADIO.byterate=12000/8;
                                            if(left>10)
                                            {
                                               adm_atom amr(&son);
                                              printf("Reading wave, got %s\n",fourCC::tostringBE(amr.getFCC()));
                                              left=0;
                                            }
                                    }
                                            break;
                                    case MKFCCR('Q','D','M','2'):
                                        {
                                            uint32_t sz;
                                              audioCodec(QDM2);
                                              sz=son.getRemainingSize();
                                              _tracks[1+nbAudioTrack].extraDataSize=sz;
                                              _tracks[1+nbAudioTrack].extraData=new uint8_t[sz];
                                              son.readPayload(_tracks[1+nbAudioTrack].extraData,sz);
                                              left=0;
                                        }
                                        break;
                                    case MKFCCR('m','s',0,0x55): // why 55 ???
                                    case MKFCCR('m','p','4','a'):
                                    {
                                              audioCodec(AAC);
                                            if(left>10)
                                            {
                                              adm_atom wave(&son);
                                              printf("Reading wave, got %s\n",fourCC::tostringBE(wave.getFCC()));
                                              if(MKFCCR('w','a','v','e')==wave.getFCC())
                                              {
                                                 // mp4a
                                                 //   wave
                                                 //     frma
                                                 //     mp4a
                                                 //     esds
                                                 while(!wave.isDone())
                                                 {
                                                     adm_atom item(&wave);
                                                     printf("parsing wave, got %s,0x%x\n",fourCC::tostringBE(item.getFCC()),
                                                                  item.getFCC());
                                                     switch(item.getFCC())
                                                     {
                                                       case MKFCCR('f','r','m','a'):
                                                          {
                                                          uint32_t codecid=item.read32();
                                                          printf("frma Codec Id :%s\n",fourCC::tostringBE(codecid));
                                                          }
                                                          break;
                                                       case MKFCCR('m','s',0,0x55):
                                                        {
                                                          // We have a waveformat here
                                                          printf("[STSD]Found MS audio header:\n");
                                                          ADIO.encoding=ADM_swap16(item.read16());
                                                          ADIO.channels=ADM_swap16(item.read16());
                                                          ADIO.frequency=ADM_swap32(item.read32());
                                                          ADIO.byterate=ADM_swap32(item.read32());
                                                          ADIO.blockalign=ADM_swap16(item.read16());
                                                          ADIO.bitspersample=ADM_swap16(item.read16());
                                                          printWavHeader(&(ADIO));
                                                          
                                                        }
                                                       break;
                                                        case MKFCCR('m','p','4','a'):
                                                          break; 
                                                        case MKFCCR('e','s','d','s'):
                                                          {
                                                               decodeEsds(&item,TRACK_AUDIO);
                                                          goto foundit; // FIXME!!!
                                                          }
                                                          break;
                                                       default:
                                                         break;
                                                     }

                                                     item.skipAtom();
                                                   
                                                 }  // Wave iddone
                                                 left=0;
                                              }  // if ==wave
                                              else
                                              {
                                                if(wave.getFCC()==MKFCCR('e','s','d','s'))
                                                          {
                                                               decodeEsds(&wave,TRACK_AUDIO);
                                                               goto foundit; // FIXME!!!
                                                          } 
                                                else
                                                {
                                                  printf("UNHANDLED ATOM : %s\n",fourCC::tostringBE(wave.getFCC())); 
                                                }
                                              }
                                            } // if left > 10
foundit: // HACK FIXME     
                                            left=0;
                                    }       
                                            break; // mp4a
                                  
                                }
                     }
                          break;
                     default:
                          ADM_assert(0);
                   }
                   son.skipBytes(left); 
                }
       }
              break;
       default:
          printf("[STBL]Skipping atom %s\n",fourCC::tostringBE(son.getFCC()));
     }
     son.skipAtom();
  }
  uint8_t r=0;
  uint32_t nbo=0;
  switch(trackType)
  {
    case TRACK_VIDEO:
        {
          if(_tracks[0].index)
          {
              printf("Already got a video track\n");
              return 1;
          }
          r=indexify(&(_tracks[0]),trackScale,&info,0,&nbo);
          
          _videostream.dwLength= _mainaviheader.dwTotalFrames=_tracks[0].nbIndex;
          // update fps
          float f=_videostream.dwLength;
          if(_movieDuration) f=1000000.*f/_movieDuration;
              else  f=25000;
          _videostream.dwRate=(uint32_t)floor(f);
           _mainaviheader.dwMicroSecPerFrame=ADM_UsecFromFps1000(_videostream.dwRate);
          // if we have a sync atom ???
          if(info.nbSync)
          {
            // Mark keyframes
            for(int i=0;i<info.nbSync;i++)
            {
              int sync=info.Sync[i];
              if(sync) sync--;
              _tracks[0].index[sync].intra=AVI_KEY_FRAME;
            }
          }
          else
          { // All frames are kf
            for(int i=0;i<_tracks[0].nbIndex;i++)
            {
              _tracks[0].index[i].intra=AVI_KEY_FRAME;
            }
          }
          // Now do the CTTS thing
          if(info.Ctts)
          {
            updateCtts(&info);
          }

          
           VDEO.index[0].intra=AVI_KEY_FRAME;
        }
          break;
    case TRACK_AUDIO:
          printf("Cur audio track :%u\n",nbAudioTrack);
          if(info.SzIndentical ==1 && (ADIO.encoding==WAV_LPCM || ADIO.encoding==WAV_PCM ))
            {
              printf("Overriding size %lu -> %lu\n", info.SzIndentical,info.SzIndentical*2*ADIO.channels);
              info.SzIndentical=info.SzIndentical*2*ADIO.channels;
            }
            r=indexify(&(_tracks[1+nbAudioTrack]),trackScale,&info,1,&nbo);
            printf("Indexed audio, nb blocks:%u\n",nbo);
            if(r)
            {
                nbo=_tracks[1+nbAudioTrack].nbIndex;
                if(nbo)
                    _tracks[1+nbAudioTrack].nbIndex=nbo;
                else
                    _tracks[1+nbAudioTrack].nbIndex=info.nbSz;
                printf("Indexed audio, nb blocks:%u (final)\n",_tracks[1+nbAudioTrack].nbIndex);
                _tracks[1+nbAudioTrack].scale=trackScale;
                nbAudioTrack++;
            }
            
            break;
    case TRACK_OTHER:
        r=1;
        break;
  }
  return r;
}