Ignore:
Timestamp:
Aug 14, 2006, 10:01:29 PM (19 years ago)
Author:
vladest
Message:

Latest code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/libmpdemux/demux_mov.c

    r172 r181  
    551551}
    552552
     553unsigned int store_ughvlc(unsigned char *s, unsigned int v){
     554    unsigned int n = 0;
     555
     556    while(v >= 0xff) {
     557        *s++ = 0xff;
     558        v -= 0xff;
     559        n++;
     560    }
     561    *s = v;
     562    n++;
     563
     564    return n;
     565}
     566
    553567static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id,
    554568                           off_t pos, off_t len, mov_track_t* trak);
     
    556570static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak){
    557571    mov_priv_t* priv=demuxer->priv;
    558 //    printf("lschunks (level=%d,endpos=%x)\n", level, endpos);
     572    //    printf("lschunks (level=%d,endpos=%x)\n", level, endpos);
    559573    while(1){
    560         off_t pos;
    561         off_t len;
    562         unsigned int id;
    563         //
    564         pos=stream_tell(demuxer->stream);
     574        off_t pos;
     575        off_t len;
     576        unsigned int id;
     577        //
     578        pos=stream_tell(demuxer->stream);
    565579        dprintf("MOV: stream_tell==%lli\n",pos);
    566         if(pos>=endpos) return; // END
    567         len=stream_read_dword(demuxer->stream);
    568 //      printf("len==%d\n",len);
    569         if(len<8) return; // error
    570         len-=8;
    571         id=stream_read_dword(demuxer->stream);
    572         //
    573         dprintf("lschunks %.4s  %d\n",(char *)&id,(int)len);
    574         //
    575         if(trak){
    576           if (lschunks_intrak(demuxer, level, id, pos, len, trak) < 0)
    577             return;
    578         } else { /* not in track */
    579           switch(id) {
    580             case MOV_FOURCC('m','v','h','d'): {
    581                 stream_skip(demuxer->stream,12);
    582                 priv->timescale=stream_read_dword(demuxer->stream);
    583                 priv->duration=stream_read_dword(demuxer->stream);
    584                 dprintf("MOV: %*sMovie header (%d bytes): tscale=%d  dur=%d\n",level,"",(int)len,
    585                     (int)priv->timescale,(int)priv->duration);
    586                 break;
    587             }
    588             case MOV_FOURCC('t','r','a','k'): {
    589 //          if(trak) printf("MOV: Warning! trak in trak?\n");
    590             if(priv->track_db>=MOV_MAX_TRACKS){
    591                 dprintf("MOV: too may tracks\n");
    592                 return;
    593             }
    594             if(!priv->track_db) dprintf( "--------------\n");
    595             trak=malloc(sizeof(mov_track_t));
    596             memset(trak,0,sizeof(mov_track_t));
    597             dprintf("MOV: Track #%d:\n",priv->track_db);
    598             trak->id=priv->track_db;
    599             priv->tracks[priv->track_db]=trak;
    600             lschunks(demuxer,level+1,pos+len,trak);
    601             mov_build_index(trak,priv->timescale);
    602             switch(trak->type){
    603             case MOV_TRAK_AUDIO: {
    604 #if 0
    605                 struct {
    606                    int16_t version;             // 0 or 1 (version 1 is qt3.0+)
    607                    int16_t revision;            // 0
    608                    int32_t vendor_id;           // 0
    609                    int16_t channels;            // 1 or 2  (Mono/Stereo)
    610                    int16_t samplesize;          // 8 or 16 (8Bit/16Bit)
    611                    int16_t compression_id;      // if version 0 then 0
    612                                                 // if version 1 and vbr then -2 else 0
    613                    int16_t packet_size;         // 0
    614                    uint16_t sample_rate;        // samplerate (Hz)
    615                    // qt3.0+ (version == 1)
    616                    uint32_t samples_per_packet; // 0 or num uncompressed samples in a packet
    617                                                 // if 0 below three values are also 0
    618                    uint32_t bytes_per_packet;   // 0 or num compressed bytes for one channel
    619                    uint32_t bytes_per_frame;    // 0 or num compressed bytes for all channels
    620                                                 // (channels * bytes_per_packet)
    621                    uint32_t bytes_per_sample;   // 0 or size of uncompressed sample
    622                    // if samples_per_packet and bytes_per_packet are constant (CBR)
    623                    // then bytes_per_frame and bytes_per_sample must be 0 (else is VBR)
    624                    // ---
    625                    // optional additional atom-based fields
    626                    // ([int32_t size,int32_t type,some data ],repeat)
    627                 } my_stdata;
    628 #endif
    629                 int version, adjust;
    630                 sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db);
    631                 sh->format=trak->fourcc;
    632 
    633                 switch( sh->format ) {
    634                     case 0x726D6173: /* samr */
    635                         /* amr narrowband */
    636                         trak->samplebytes=sh->samplesize=1;
    637                         trak->nchannels=sh->channels=1;
    638                         sh->samplerate=8000;
    639                         break;
    640 
    641                     case 0x62776173: /* sawb */
    642                         /* amr wideband */
    643                         trak->samplebytes=sh->samplesize=1;
    644                         trak->nchannels=sh->channels=1;
    645                         sh->samplerate=16000;
    646                         break;
    647 
    648                     default:
    649 
    650 // assumptions for below table: short is 16bit, int is 32bit, intfp is 16bit
    651 // XXX: 32bit fixed point numbers (intfp) are only 2 Byte!
    652 // short values are usually one byte leftpadded by zero
    653 //   int values are usually two byte leftpadded by zero
    654 //  stdata[]:
    655 //      8   short       version
    656 //      10  short       revision
    657 //      12  int         vendor_id
    658 //      16  short       channels
    659 //      18  short       samplesize
    660 //      20  short       compression_id
    661 //      22  short       packet_size (==0)
    662 //      24  intfp       sample_rate
    663 //     (26  short)      unknown (==0)
    664 //    ---- qt3.0+ (version>=1)
    665 //      28  int         samples_per_packet
    666 //      32  int         bytes_per_packet
    667 //      36  int         bytes_per_frame
    668 //      40  int         bytes_per_sample
    669 // there may be additional atoms following at 28 (version 0)
    670 // or 44 (version 1), eg. esds atom of .MP4 files
    671 // esds atom:
    672 //      28  int         atom size (bytes of int size, int type and data)
    673 //      32  char[4]     atom type (fourc charater code -> esds)
    674 //      36  char[]      atom data (len=size-8)
    675 
    676 // TODO: fix parsing for files using version 2.
    677                 version=char2short(trak->stdata,8);
    678                 if (version > 1)
    679                   dprintf( "MOV: version %d sound atom may not parse correctly!\n", version);
    680                 trak->samplebytes=sh->samplesize=char2short(trak->stdata,18)/8;
    681 
    682                 /* I can't find documentation, but so far this is the case. -Corey */
    683                 switch (char2short(trak->stdata,16)) {
    684                   case 1:
    685                     trak->nchannels = 1; break;
    686                   case 2:
    687                     trak->nchannels = 2; break;
    688                   case 3:
    689                     trak->nchannels = 6; break;
    690                   default:
    691                     dprintf(
    692                         "MOV: unable to determine audio channels, assuming 2 (got %d)\n",
    693                         char2short(trak->stdata,16));
    694                     trak->nchannels = 2;
    695                 }
    696                 sh->channels = trak->nchannels;
    697 
    698                 /*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n",
    699                     trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur,
    700                     trak->durmap[0].num, trak->timescale/trak->durmap[0].dur,
    701                     char2short(trak->stdata,24)/trak->durmap[0].dur);*/
    702                 sh->samplerate=char2short(trak->stdata,24);
    703                 if((sh->samplerate < 7000) && trak->durmap) {
    704                   switch(char2short(trak->stdata,24)/trak->durmap[0].dur) {
    705                     // TODO: add more cases.
    706                     case 31:
    707                       sh->samplerate = 32000; break;
    708                     case 43:
    709                       sh->samplerate = 44100; break;
    710                     case 47:
    711                       sh->samplerate = 48000; break;
    712                     default:
    713                       dprintf(
    714                           "MOV: unable to determine audio samplerate, "
    715                           "assuming 44.1kHz (got %d)\n",
    716                           char2short(trak->stdata,24)/trak->durmap[0].dur);
    717                       sh->samplerate = 44100;
    718                   }
    719                 }
    720                 }
    721                 dprintf( "Audio bits: %d  chans: %d  rate: %d\n",
    722                     sh->samplesize*8,sh->channels,sh->samplerate);
    723 
    724                 if(trak->stdata_len >= 44 && trak->stdata[9]>=1){
    725                   dprintf("Audio header: samp/pack=%d bytes/pack=%d bytes/frame=%d bytes/samp=%d  \n",
    726                     char2int(trak->stdata,28),
    727                     char2int(trak->stdata,32),
    728                     char2int(trak->stdata,36),
    729                     char2int(trak->stdata,40));
    730                   if(trak->stdata_len>=44+8){
    731                     int len=char2int(trak->stdata,44);
    732                     int fcc=char2int(trak->stdata,48);
    733                     // we have extra audio headers!!!
    734                     dprintf("Audio extra header: len=%d  fcc=0x%X\n",len,fcc);
    735                     if((len >= 4) &&
    736                        (char2int(trak->stdata,52) >= 12) &&
    737                        (char2int(trak->stdata,52+4) == MOV_FOURCC('f','r','m','a'))) {
    738                         switch(char2int(trak->stdata,52+8)) {
    739                          case MOV_FOURCC('a','l','a','c'):
    740                           if (len >= 36 + char2int(trak->stdata,52)) {
    741                             sh->codecdata_len = char2int(trak->stdata,52+char2int(trak->stdata,52));
    742                             dprintf( "MOV: Found alac atom (%d)!\n", sh->codecdata_len);
    743                             sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
    744                             memcpy(sh->codecdata, &trak->stdata[52+char2int(trak->stdata,52)], sh->codecdata_len);
    745                           }
    746                           break;
    747                          case MOV_FOURCC('i','n','2','4'):
    748                          case MOV_FOURCC('i','n','3','2'):
    749                          case MOV_FOURCC('f','l','3','2'):
    750                          case MOV_FOURCC('f','l','6','4'):
    751                           if ((len >= 22) &&
    752                               (char2int(trak->stdata,52+16)==MOV_FOURCC('e','n','d','a')) &&
    753                               (char2short(trak->stdata,52+20))) {
    754                                 sh->format=char2int(trak->stdata,52+8);
    755                                 dprintf( "MOV: Found little endian PCM data, reversed fourcc:%04x\n", sh->format);
    756                           }
    757                           break;
    758                          default:
    759                           if (len > 8 && len + 44 <= trak->stdata_len) {
    760                                 sh->codecdata_len = len-8;
    761                                 sh->codecdata = trak->stdata+44+8;
    762                           }
    763                         }
    764                     } else {
    765                       if (len > 8 && len + 44 <= trak->stdata_len) {
    766                     sh->codecdata_len = len-8;
    767                     sh->codecdata = trak->stdata+44+8;
    768                       }
    769                     }
    770                   }
    771                 }
    772 
    773                 switch (version) {
    774                   case 0:
    775                     adjust =  0; break;
    776                   case 1:
    777                     adjust = 48; break;
    778                   case 2:
    779                     adjust = 68; break;
    780                   default:
    781                     dprintf( "MOV: unknown sound atom version (%d); may not work!\n", version);
    782                     adjust = 68;
    783                 }
    784                 if (trak->stdata_len >= 36 + adjust) {
    785                     int atom_len = char2int(trak->stdata,28+adjust);
    786                     switch(char2int(trak->stdata,32+adjust)) { // atom type
    787                       case MOV_FOURCC('e','s','d','s'): {
    788                         dprintf( "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len);
    789                         if(atom_len > 8) {
    790                           esds_t esds;
    791                           if(!mp4_parse_esds(&trak->stdata[36+adjust], atom_len-8, &esds)) {
    792 
    793                             sh->i_bps = esds.avgBitrate/8;
    794 
    795 //                          printf("######## audio format = %d ########\n",esds.objectTypeId);
    796                             if(esds.objectTypeId==MP4OTI_MPEG1Audio || esds.objectTypeId==MP4OTI_MPEG2AudioPart3)
    797                                 sh->format=0x55; // .mp3
    798 
    799                             // dump away the codec specific configuration for the AAC decoder
    800                             if(esds.decoderConfigLen){
    801                             if( (esds.decoderConfig[0]>>3) == 29 )
    802                                 sh->format = 0x1d61346d; // request multi-channel mp3 decoder
    803                             sh->codecdata_len = esds.decoderConfigLen;
    804                             sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
    805                             memcpy(sh->codecdata, esds.decoderConfig, sh->codecdata_len);
    806                             }
    807                           }
    808                           mp4_free_esds(&esds); // freeup esds mem
    809 #if 0
    810                           { FILE* f=fopen("esds.dat","wb");
    811                           fwrite(&trak->stdata[36],atom_len-8,1,f);
    812                           fclose(f); }
    813 #endif
    814                         }
    815                       } break;
    816                       case MOV_FOURCC('a','l','a','c'): {
    817                         dprintf( "MOV: Found alac atom (%d)!\n", atom_len);
    818                         if(atom_len > 8) {
    819                             // copy all the atom (not only payload) for lavc alac decoder
    820                             sh->codecdata_len = atom_len;
    821                             sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
    822                             memcpy(sh->codecdata, &trak->stdata[28], sh->codecdata_len);
    823                         }
    824                       } break;
    825                       case MOV_FOURCC('d','a','m','r'):
    826                         dprintf( "MOV: Found AMR audio atom %c%c%c%c (%d)!\n", trak->stdata[32+adjust],trak->stdata[33+adjust],trak->stdata[34+adjust],trak->stdata[35+adjust], atom_len);
    827                         if (atom_len>14) {
    828                           dprintf( "mov: vendor: %c%c%c%c Version: %d\n",trak->stdata[36+adjust],trak->stdata[37+adjust],trak->stdata[38+adjust], trak->stdata[39+adjust],trak->stdata[40+adjust]);
    829                           dprintf( "MOV: Modes set: %02x%02x\n",trak->stdata[41+adjust],trak->stdata[42+adjust]);
    830                           dprintf( "MOV: Mode change period: %d Frames per sample: %d\n",trak->stdata[43+adjust],trak->stdata[44+adjust]);
    831                         }
    832                         break;
    833                       default:
    834                         dprintf( "MOV: Found unknown audio atom %c%c%c%c (%d)!\n",
    835                             trak->stdata[32+adjust],trak->stdata[33+adjust],trak->stdata[34+adjust],trak->stdata[35+adjust],
    836                             atom_len);
    837                     }
    838                 }
    839                 dprintf( "Fourcc: %.4s\n",(char *)&trak->fourcc);
    840 #if 0
    841                 { FILE* f=fopen("stdata.dat","wb");
    842                   fwrite(trak->stdata,trak->stdata_len,1,f);
    843                   fclose(f); }
    844                 { FILE* f=fopen("tkdata.dat","wb");
    845                   fwrite(trak->tkdata,trak->tkdata_len,1,f);
    846                   fclose(f); }
    847 #endif
    848                 // Emulate WAVEFORMATEX struct:
    849                 sh->wf=malloc(sizeof(WAVEFORMATEX));
    850                 memset(sh->wf,0,sizeof(WAVEFORMATEX));
    851                 sh->wf->nChannels=sh->channels;
    852                 sh->wf->wBitsPerSample=(trak->stdata[18]<<8)+trak->stdata[19];
    853                 // sh->wf->nSamplesPerSec=trak->timescale;
    854                 sh->wf->nSamplesPerSec=sh->samplerate;
    855                 if(trak->stdata_len >= 44 && trak->stdata[9]>=1 && char2int(trak->stdata,28)>0){
    856                 //Audio header: samp/pack=4096 bytes/pack=743 bytes/frame=1486 bytes/samp=2
    857                   sh->wf->nAvgBytesPerSec=(sh->wf->nChannels*sh->wf->nSamplesPerSec*
    858                       char2int(trak->stdata,32)+char2int(trak->stdata,28)/2)
    859                       /char2int(trak->stdata,28);
    860                   sh->wf->nBlockAlign=char2int(trak->stdata,36);
    861                 } else {
    862                   sh->wf->nAvgBytesPerSec=sh->wf->nChannels*sh->wf->wBitsPerSample*sh->wf->nSamplesPerSec/8;
    863                   // workaround for ms11 ima4
    864                   if (sh->format == 0x1100736d && trak->stdata_len >= 36)
    865                       sh->wf->nBlockAlign=char2int(trak->stdata,36);
    866                 }
    867                 // Selection:
    868 //              if(demuxer->audio->id==-1 || demuxer->audio->id==priv->track_db){
    869 //                  // (auto)selected audio track:
    870 //                  demuxer->audio->id=priv->track_db;
    871 //                  demuxer->audio->sh=sh; sh->ds=demuxer->audio;
    872 //              }
    873                 break;
    874             }
    875             case MOV_TRAK_VIDEO: {
    876                 int i, entry;
    877                 int flag, start, count_flag, end, palette_count, gray;
    878                 int hdr_ptr = 76;  // the byte just after depth
    879                 unsigned char *palette_map;
    880                 sh_video_t* sh=new_sh_video(demuxer,priv->track_db);
    881                 int depth;
    882                 sh->format=trak->fourcc;
    883 
    884                 if (trak->stdata_len < 78) {
    885                   dprintf("MOV: Invalid (%d bytes instead of >= 78) video trak desc\n",
    886                   trak->stdata_len);
    887                   break;
    888                 }
    889                 depth = trak->stdata[75] | (trak->stdata[74] << 8);
    890 //  stdata[]:
    891 //      8   short       version
    892 //      10  short       revision
    893 //      12  int         vendor_id
    894 //      16  int         temporal_quality
    895 //      20  int         spatial_quality
    896 //      24  short       width
    897 //      26  short       height
    898 //      28  int         h_dpi
    899 //      32  int         v_dpi
    900 //      36  int         0
    901 //      40  short       frames_per_sample
    902 //      42  char[4]     compressor_name
    903 //      74  short       depth
    904 //      76  short       color_table_id
    905 // additional atoms may follow,
    906 // eg esds atom from .MP4 files
    907 //      78  int         atom size
    908 //      82  char[4]     atom type
    909 //      86  ...         atom data
    910 
    911         {       ImageDescription* id=malloc(8+trak->stdata_len);  // safe
    912                 trak->desc=id;
    913                 id->idSize=8+trak->stdata_len;
    914 //              id->cType=bswap_32(trak->fourcc);
    915                 id->cType=le2me_32(trak->fourcc);
    916                 id->version=char2short(trak->stdata,8);
    917                 id->revisionLevel=char2short(trak->stdata,10);
    918                 id->vendor=char2int(trak->stdata,12);
    919                 id->temporalQuality=char2int(trak->stdata,16);
    920                 id->spatialQuality=char2int(trak->stdata,20);
    921                 id->width=char2short(trak->stdata,24);
    922                 id->height=char2short(trak->stdata,26);
    923                 id->hRes=char2int(trak->stdata,28);
    924                 id->vRes=char2int(trak->stdata,32);
    925                 id->dataSize=char2int(trak->stdata,36);
    926                 id->frameCount=char2short(trak->stdata,40);
    927                 memcpy(&id->name,trak->stdata+42,32);
    928                 id->depth=char2short(trak->stdata,74);
    929                 id->clutID=char2short(trak->stdata,76);
    930                 if(trak->stdata_len>78) memcpy(((char*)&id->clutID)+2,trak->stdata+78,trak->stdata_len-78);
    931                 sh->ImageDesc=id;
    932 #if 0
    933                 {   FILE *f=fopen("ImageDescription","wb");
    934                     fwrite(id,id->idSize,1,f);
    935                     fclose(f);
    936                 }
    937 #endif
    938         }
    939 
    940                 if(trak->stdata_len >= 86) { // extra atoms found
    941                   int pos=78;
    942                   int atom_len;
    943                   while(pos+8<=trak->stdata_len &&
    944                     (pos+(atom_len=char2int(trak->stdata,pos)))<=trak->stdata_len){
    945                    switch(char2int(trak->stdata,pos+4)) { // switch atom type
    946                     case MOV_FOURCC('g','a','m','a'):
    947                       // intfp with gamma value at which movie was captured
    948                       // can be used to gamma correct movie display
    949                       dprintf( "MOV: Found unsupported Gamma-Correction movie atom (%d)!\n",
    950                           atom_len);
    951                       break;
    952                     case MOV_FOURCC('f','i','e','l'):
    953                       // 2 char-values (8bit int) that specify field handling
    954                       // see the Apple's QuickTime Fileformat PDF for more info
    955                       dprintf( "MOV: Found unsupported Field-Handling movie atom (%d)!\n",
    956                           atom_len);
    957                       break;
    958                     case MOV_FOURCC('m','j','q','t'):
    959                       // Motion-JPEG default quantization table
    960                       dprintf( "MOV: Found unsupported MJPEG-Quantization movie atom (%d)!\n",
    961                           atom_len);
    962                       break;
    963                     case MOV_FOURCC('m','j','h','t'):
    964                       // Motion-JPEG default huffman table
    965                       dprintf( "MOV: Found unsupported MJPEG-Huffman movie atom (%d)!\n",
    966                           atom_len);
    967                       break;
    968                     case MOV_FOURCC('e','s','d','s'):
    969                       // MPEG4 Elementary Stream Descriptor header
    970                       dprintf( "MOV: Found MPEG4 movie Elementary Stream Descriptor atom (%d)!\n", atom_len);
    971                       // add code here to save esds header of length atom_len-8
    972                       // beginning at stdata[86] to some variable to pass it
    973                       // on to the decoder ::atmos
    974                       if(atom_len > 8) {
    975                         esds_t esds;
    976                         if(!mp4_parse_esds(trak->stdata+pos+8, atom_len-8, &esds)) {
    977 
    978                           if(esds.objectTypeId==MP4OTI_MPEG2VisualSimple || esds.objectTypeId==MP4OTI_MPEG2VisualMain ||
    979                              esds.objectTypeId==MP4OTI_MPEG2VisualSNR || esds.objectTypeId==MP4OTI_MPEG2VisualSpatial ||
    980                              esds.objectTypeId==MP4OTI_MPEG2VisualHigh || esds.objectTypeId==MP4OTI_MPEG2Visual422)
    981                             sh->format=mmioFOURCC('m', 'p', 'g', '2');
    982                           else if(esds.objectTypeId==MP4OTI_MPEG1Visual)
    983                             sh->format=mmioFOURCC('m', 'p', 'g', '1');
    984 
    985                           // dump away the codec specific configuration for the AAC decoder
    986                           trak->stream_header_len = esds.decoderConfigLen;
    987                           trak->stream_header = (unsigned char *)malloc(trak->stream_header_len);
    988                           memcpy(trak->stream_header, esds.decoderConfig, trak->stream_header_len);
    989                         }
    990                         mp4_free_esds(&esds); // freeup esds mem
    991                       }
    992                       break;
    993                     case MOV_FOURCC('a','v','c','C'):
    994                       // AVC decoder configuration record
    995                       dprintf( "MOV: AVC decoder configuration record atom (%d)!\n", atom_len);
    996                       if(atom_len > 8) {
    997                         int i, poffs, cnt;
    998                         // Parse some parts of avcC, just for fun :)
    999                         // real parsing is done by avc1 decoder
    1000                         dprintf( "MOV: avcC version: %d\n", *(trak->stdata+pos+8));
    1001                         if (*(trak->stdata+pos+8) != 1)
    1002                           dprintf( "MOV: unknown avcC version (%d). Expexct problems.\n", *(trak->stdata+pos+9));
    1003                         dprintf( "MOV: avcC profile: %d\n", *(trak->stdata+pos+9));
    1004                         dprintf( "MOV: avcC profile compatibility: %d\n", *(trak->stdata+pos+10));
    1005                         dprintf( "MOV: avcC level: %d\n", *(trak->stdata+pos+11));
    1006                         dprintf( "MOV: avcC nal length size: %d\n", ((*(trak->stdata+pos+12))&0x03)+1);
    1007                         dprintf( "MOV: avcC number of sequence param sets: %d\n", cnt = (*(trak->stdata+pos+13) & 0x1f));
    1008                         poffs = pos + 14;
    1009                         for (i = 0; i < cnt; i++) {
    1010                           dprintf( "MOV: avcC sps %d have length %d\n", i, BE_16(trak->stdata+poffs));
    1011                           poffs += BE_16(trak->stdata+poffs) + 2;
    1012                         }
    1013                         dprintf( "MOV: avcC number of picture param sets: %d\n", *(trak->stdata+poffs));
    1014                         poffs++;
    1015                         for (i = 0; i < cnt; i++) {
    1016                           dprintf( "MOV: avcC pps %d have length %d\n", i, BE_16(trak->stdata+poffs));
    1017                           poffs += BE_16(trak->stdata+poffs) + 2;
    1018                         }
    1019                         // Copy avcC for the AVC decoder
    1020                         // This data will be put in extradata below, where BITMAPINFOHEADER is created
    1021                         trak->stream_header_len = atom_len-8;
    1022                         trak->stream_header = (unsigned char *)malloc(trak->stream_header_len);
    1023                         memcpy(trak->stream_header, trak->stdata+pos+8, trak->stream_header_len);
    1024                       }
    1025                       break;
    1026                     case MOV_FOURCC('d','2','6','3'):
    1027                       dprintf( "MOV: Found H.263 decoder atom %c%c%c%c (%d)!\n", trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],atom_len);
    1028                       if (atom_len>10)
    1029                         dprintf( "MOV: Vendor: %c%c%c%c H.263 level: %d H.263 profile: %d \n", trak->stdata[pos+8],trak->stdata[pos+9],trak->stdata[pos+10],trak->stdata[pos+11],trak->stdata[pos+12],trak->stdata[pos+13]);
    1030                       break;
    1031                     case 0:
    1032                       break;
    1033                     default:
    1034                       dprintf( "MOV: Found unknown movie atom %c%c%c%c (%d)!\n",
    1035                           trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],
    1036                           atom_len);
    1037                    }
    1038                    if(atom_len<8) break;
    1039                    pos+=atom_len;
    1040 //                 printf("pos=%d max=%d\n",pos,trak->stdata_len);
    1041                   }
    1042                 }
    1043                 sh->fps=trak->timescale/
    1044                     ((trak->durmap_size>=1)?(float)trak->durmap[0].dur:1);
    1045                 sh->frametime=1.0f/sh->fps;
    1046 
    1047                 sh->disp_w=trak->stdata[25]|(trak->stdata[24]<<8);
    1048                 sh->disp_h=trak->stdata[27]|(trak->stdata[26]<<8);
    1049                 // if image size is zero, fallback to display size
    1050                 if(!sh->disp_w && !sh->disp_h) {
    1051                   sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8);
    1052                   sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8);
    1053                 } else if(sh->disp_w!=(trak->tkdata[77]|(trak->tkdata[76]<<8))){
    1054                   // codec and display width differ... use display one for aspect
    1055                   sh->aspect=trak->tkdata[77]|(trak->tkdata[76]<<8);
    1056                   sh->aspect/=trak->tkdata[81]|(trak->tkdata[80]<<8);
    1057                 }
    1058 
    1059                 if(depth>32+8) printf("*** depth = 0x%X\n",depth);
    1060 
    1061                 // palettized?
    1062                 gray = 0;
    1063                 if (depth > 32) { depth&=31; gray = 1; } // depth > 32 means grayscale
    1064                 if ((depth == 2) || (depth == 4) || (depth == 8))
    1065                   palette_count = (1 << depth);
    1066                 else
    1067                   palette_count = 0;
    1068 
    1069                 // emulate BITMAPINFOHEADER:
    1070                 if (palette_count)
    1071                 {
    1072                   sh->bih=malloc(sizeof(BITMAPINFOHEADERw) + palette_count * 4);
    1073                   memset(sh->bih,0,sizeof(BITMAPINFOHEADERw) + palette_count * 4);
    1074                   sh->bih->biSize=40 + palette_count * 4;
    1075                   // fetch the relevant fields
    1076                   flag = BE_16(&trak->stdata[hdr_ptr]);
    1077                   hdr_ptr += 2;
    1078                   start = BE_32(&trak->stdata[hdr_ptr]);
    1079                   hdr_ptr += 4;
    1080                   count_flag = BE_16(&trak->stdata[hdr_ptr]);
    1081                   hdr_ptr += 2;
    1082                   end = BE_16(&trak->stdata[hdr_ptr]);
    1083                   hdr_ptr += 2;
    1084                   palette_map = (unsigned char *)sh->bih + 40;
    1085                   dprintf( "Allocated %d entries for palette\n",
    1086                     palette_count);
    1087                   dprintf( "QT palette: start: %x, end: %x, count flag: %d, flags: %x\n",
    1088                     start, end, count_flag, flag);
    1089 
    1090                   /* XXX: problems with sample (statunit6.mov) with flag&0x4 set! - alex*/
    1091 
    1092                   // load default palette
    1093                   if (flag & 0x08)
    1094                   {
    1095                     if (gray)
    1096                     {
    1097                       dprintf( "Using default QT grayscale palette\n");
    1098                       if (palette_count == 16)
    1099                         memcpy(palette_map, qt_default_grayscale_palette_16, 16 * 4);
    1100                       else if (palette_count == 256) {
    1101                         memcpy(palette_map, qt_default_grayscale_palette_256, 256 * 4);
    1102                         if (trak->fourcc == mmioFOURCC('c','v','i','d')) {
    1103                           int i;
    1104                           // Hack for grayscale CVID, negative palette
    1105                           // If you have samples where this is not required contact me (rxt)
    1106                           dprintf( "MOV: greyscale cvid with default palette,"
    1107                             " enabling negative palette hack.\n");
    1108                           for (i = 0; i < 256 * 4; i++)
    1109                             palette_map[i] = palette_map[i] ^ 0xff;
    1110                         }
    1111                       }
    1112                     }
    1113                     else
    1114                     {
    1115                       dprintf( "Using default QT colour palette\n");
    1116                       if (palette_count == 4)
    1117                         memcpy(palette_map, qt_default_palette_4, 4 * 4);
    1118                       else if (palette_count == 16)
    1119                         memcpy(palette_map, qt_default_palette_16, 16 * 4);
    1120                       else if (palette_count == 256)
    1121                         memcpy(palette_map, qt_default_palette_256, 256 * 4);
    1122                     }
    1123                   }
    1124                   // load palette from file
    1125                   else
    1126                   {
    1127                     dprintf( "Loading palette from file\n");
    1128                     for (i = start; i <= end; i++)
    1129                     {
    1130                       entry = BE_16(&trak->stdata[hdr_ptr]);
    1131                       hdr_ptr += 2;
    1132                       // apparently, if count_flag is set, entry is same as i
    1133                       if (count_flag & 0x8000)
    1134                         entry = i;
    1135                       // only care about top 8 bits of 16-bit R, G, or B value
    1136                       if (entry <= palette_count && entry >= 0)
    1137                       {
    1138                         palette_map[entry * 4 + 2] = trak->stdata[hdr_ptr + 0];
    1139                         palette_map[entry * 4 + 1] = trak->stdata[hdr_ptr + 2];
    1140                         palette_map[entry * 4 + 0] = trak->stdata[hdr_ptr + 4];
    1141                         dprintf("QT palette: added entry: %d of %d (colors: R:%x G:%x B:%x)\n",
    1142                             entry, palette_count,
    1143                             palette_map[entry * 4 + 2],
    1144                             palette_map[entry * 4 + 1],
    1145                             palette_map[entry * 4 + 0]);
    1146                       }
    1147                       else
    1148                         dprintf( "QT palette: skipped entry (out of count): %d of %d\n",
    1149                             entry, palette_count);
    1150                       hdr_ptr += 6;
    1151                     }
    1152                   }
    1153                 }
    1154                 else
    1155                 {
    1156                     if (trak->fourcc == mmioFOURCC('a','v','c','1')) {
    1157                         if (trak->stream_header_len > 0xffffffff - sizeof(BITMAPINFOHEADERw)) {
    1158                             dprintf("Invalid extradata size %d, skipping\n");
    1159                             trak->stream_header_len = 0;
    1160                         }
    1161 
    1162                         sh->bih=malloc(sizeof(BITMAPINFOHEADERw) + trak->stream_header_len);
    1163                         memset(sh->bih,0,sizeof(BITMAPINFOHEADERw) + trak->stream_header_len);
    1164                         sh->bih->biSize=40  + trak->stream_header_len;
    1165                         memcpy(((unsigned char *)sh->bih)+40,  trak->stream_header, trak->stream_header_len);
    1166                         free (trak->stream_header);
    1167                         trak->stream_header_len = 0;
    1168                         trak->stream_header = NULL;
    1169                     } else {
    1170                         sh->bih=malloc(sizeof(BITMAPINFOHEADERw));
    1171                         memset(sh->bih,0,sizeof(BITMAPINFOHEADERw));
    1172                         sh->bih->biSize=40;
    1173                     }
    1174                 }
    1175                 sh->bih->biWidth=sh->disp_w;
    1176                 sh->bih->biHeight=sh->disp_h;
    1177                 sh->bih->biPlanes=0;
    1178                 sh->bih->biBitCount=depth;
    1179                 sh->bih->biCompression=trak->fourcc;
    1180                 sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight;
    1181 
    1182                 dprintf( "Image size: %d x %d (%d bpp)\n",sh->disp_w,sh->disp_h,sh->bih->biBitCount);
    1183                 if(trak->tkdata_len>81)
    1184                 dprintf( "Display size: %d x %d\n",
    1185                     trak->tkdata[77]|(trak->tkdata[76]<<8),
    1186                     trak->tkdata[81]|(trak->tkdata[80]<<8));
    1187                 dprintf( "Fourcc: %.4s  Codec: '%.*s'\n",(char *)&trak->fourcc,trak->stdata[42]&31,trak->stdata+43);
    1188 
    1189 //              if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){
    1190 //                  // (auto)selected video track:
    1191 //                  demuxer->video->id=priv->track_db;
    1192 //                  demuxer->video->sh=sh; sh->ds=demuxer->video;
    1193 //              }
    1194                 break;
    1195             }
    1196             case MOV_TRAK_GENERIC:
    1197                 dprintf( "Generic track - not completely understood! (id: %d)\n",
    1198                     trak->id);
    1199                 /* XXX: Also this contains the FLASH data */
    1200 
    1201 #if 0
    1202             {
    1203                 int pos = stream_tell(demuxer->stream);
    1204                 int i;
    1205                 int fd;
    1206                 char name[20];
    1207 
    1208                 for (i=0; i<trak->samples_size; i++)
    1209                 {
    1210                     char buf[trak->samples[i].size];
    1211                     stream_seek(demuxer->stream, trak->samples[i].pos);
    1212                     snprintf((char *)&name[0], 20, "samp%d", i);
    1213                     fd = open((char *)&name[0], O_CREAT|O_WRONLY);
    1214                     stream_read(demuxer->stream, &buf[0], trak->samples[i].size);
    1215                     write(fd, &buf[0], trak->samples[i].size);
    1216                     close(fd);
    1217                  }
    1218                 for (i=0; i<trak->chunks_size; i++)
    1219                 {
    1220                     char buf[trak->length];
    1221                     stream_seek(demuxer->stream, trak->chunks[i].pos);
    1222                     snprintf((char *)&name[0], 20, "chunk%d", i);
    1223                     fd = open((char *)&name[0], O_CREAT|O_WRONLY);
    1224                     stream_read(demuxer->stream, &buf[0], trak->length);
    1225                     write(fd, &buf[0], trak->length);
    1226                     close(fd);
    1227                  }
    1228                  if (trak->samplesize > 0)
    1229                  {
    1230                     char *buf;
    1231 
    1232                     buf = malloc(trak->samplesize);
    1233                     stream_seek(demuxer->stream, trak->chunks[0].pos);
    1234                     snprintf((char *)&name[0], 20, "trak%d", trak->id);
    1235                     fd = open((char *)&name[0], O_CREAT|O_WRONLY);
    1236                     stream_read(demuxer->stream, buf, trak->samplesize);
    1237                     write(fd, buf, trak->samplesize);
    1238                     close(fd);
    1239                  }
    1240                  stream_seek(demuxer->stream, pos);
    1241             }
    1242 #endif
    1243                 break;
    1244             default:
    1245                 dprintf( "Unknown track type found (type: %d)\n", trak->type);
    1246                 break;
    1247             }
    1248             dprintf( "--------------\n");
    1249             priv->track_db++;
    1250             trak=NULL;
    1251             break;
    1252         }
    1253 #ifndef HAVE_ZLIB
    1254         case MOV_FOURCC('c','m','o','v'): {
    1255             dprintf("MOV: got compressed header but have no zlib\n");
    1256             return;
    1257         }
    1258 #else
    1259         case MOV_FOURCC('m','o','o','v'):
    1260         case MOV_FOURCC('c','m','o','v'): {
    1261 //          dprintf(MSGTR_MOVcomprhdr);
    1262             lschunks(demuxer,level+1,pos+len,NULL);
    1263             break;
    1264         }
    1265         case MOV_FOURCC('d','c','o','m'): {
    1266 //          int temp=stream_read_dword(demuxer->stream);
    1267             unsigned int algo=be2me_32(stream_read_dword(demuxer->stream));
    1268             dprintf( "Compressed header uses %.4s algo!\n",(char *)&algo);
    1269             break;
    1270         }
    1271         case MOV_FOURCC('c','m','v','d'): {
    1272 //          int temp=stream_read_dword(demuxer->stream);
    1273             unsigned int moov_sz=stream_read_dword(demuxer->stream);
    1274             unsigned int cmov_sz=len-4;
    1275             unsigned char* cmov_buf;
    1276             unsigned char* moov_buf;
    1277             int zret;
    1278             z_stream zstrm;
    1279             stream_t* backup;
    1280 
    1281             if (moov_sz > 0xffffffff - 16) {
    1282                 dprintf("Invalid cmvd atom size %d\n", moov_sz);
     580        if(pos>=endpos) return; // END
     581        len=stream_read_dword(demuxer->stream);
     582        //      printf("len==%d\n",len);
     583        if(len<8) return; // error
     584        len-=8;
     585        id=stream_read_dword(demuxer->stream);
     586        //
     587        dprintf("lschunks %.4s  %d\n",(char *)&id,(int)len);
     588        //
     589        if(trak){
     590            if (lschunks_intrak(demuxer, level, id, pos, len, trak) < 0)
     591                return;
     592        } else { /* not in track */
     593            switch(id) {
     594            case MOV_FOURCC('m','v','h','d'): {
     595                int version = stream_read_char(demuxer->stream);
     596                stream_skip(demuxer->stream, (version == 1) ? 19 : 11);
     597                priv->timescale=stream_read_dword(demuxer->stream);
     598                if (version == 1)
     599                    priv->duration=stream_read_qword(demuxer->stream);
     600                else
     601                    priv->duration=stream_read_dword(demuxer->stream);
     602                dprintf("MOV: %*sMovie header (%d bytes): tscale=%d  dur=%d\n",level,"",(int)len,
     603                        (int)priv->timescale,(int)priv->duration);
    1283604                break;
    1284605            }
    1285             cmov_buf=malloc(cmov_sz);
    1286             moov_buf=malloc(moov_sz+16);
    1287             dprintf( "Compressed header size: %d / %d\n",cmov_sz,moov_sz);
    1288 
    1289             stream_read(demuxer->stream,cmov_buf,cmov_sz);
    1290 
    1291               zstrm.zalloc          = (alloc_func)0;
    1292               zstrm.zfree           = (free_func)0;
    1293               zstrm.opaque          = (voidpf)0;
    1294               zstrm.next_in         = cmov_buf;
    1295               zstrm.avail_in        = cmov_sz;
    1296               zstrm.next_out        = moov_buf;
    1297               zstrm.avail_out       = moov_sz;
    1298 
    1299               zret = inflateInit(&zstrm);
    1300               if (zret != Z_OK)
    1301                 { dprintf( "QT cmov: inflateInit err %d\n",zret);
    1302                 return;
    1303                 }
    1304               zret = inflate(&zstrm, Z_NO_FLUSH);
    1305               if ((zret != Z_OK) && (zret != Z_STREAM_END))
    1306                 { dprintf( "QT cmov inflate: ERR %d\n",zret);
    1307                 return;
    1308                 }
     606            case MOV_FOURCC('t','r','a','k'): {
     607                //          if(trak) printf("MOV: Warning! trak in trak?\n");
     608                if(priv->track_db>=MOV_MAX_TRACKS){
     609                    dprintf("MOV: too may tracks\n");
     610                    return;
     611                }
     612                if(!priv->track_db) dprintf( "--------------\n");
     613                trak=malloc(sizeof(mov_track_t));
     614                memset(trak,0,sizeof(mov_track_t));
     615                dprintf("MOV: Track #%d:\n",priv->track_db);
     616                trak->id=priv->track_db;
     617                priv->tracks[priv->track_db]=trak;
     618                lschunks(demuxer,level+1,pos+len,trak);
     619                mov_build_index(trak,priv->timescale);
     620                switch(trak->type){
     621                case MOV_TRAK_AUDIO: {
    1309622#if 0
    1310               else {
    1311                 FILE *DecOut;
    1312                 DecOut = fopen("Out.bin", "w");
    1313                 fwrite(moov_buf, 1, moov_sz, DecOut);
    1314                 fclose(DecOut);
    1315               }
     623                    struct {
     624                        int16_t version;                // 0 or 1 (version 1 is qt3.0+)
     625                        int16_t revision;               // 0
     626                        int32_t vendor_id;              // 0
     627                        int16_t channels;               // 1 or 2  (Mono/Stereo)
     628                        int16_t samplesize;             // 8 or 16 (8Bit/16Bit)
     629                        int16_t compression_id; // if version 0 then 0
     630                        // if version 1 and vbr then -2 else 0
     631                        int16_t packet_size;            // 0
     632                        uint16_t sample_rate;   // samplerate (Hz)
     633                        // qt3.0+ (version == 1)
     634                        uint32_t samples_per_packet;    // 0 or num uncompressed samples in a packet
     635                        // if 0 below three values are also 0
     636                        uint32_t bytes_per_packet;      // 0 or num compressed bytes for one channel
     637                        uint32_t bytes_per_frame;       // 0 or num compressed bytes for all channels
     638                        // (channels * bytes_per_packet)
     639                        uint32_t bytes_per_sample;      // 0 or size of uncompressed sample
     640                        // if samples_per_packet and bytes_per_packet are constant (CBR)
     641                        // then bytes_per_frame and bytes_per_sample must be 0 (else is VBR)
     642                        // ---
     643                        // optional additional atom-based fields
     644                        // ([int32_t size,int32_t type,some data ],repeat)
     645                    } my_stdata;
    1316646#endif
    1317               if(moov_sz != zstrm.total_out)
    1318                 dprintf( "Warning! moov size differs cmov: %d  zlib: %ld\n",moov_sz,zstrm.total_out);
    1319               zret = inflateEnd(&zstrm);
    1320 
    1321               backup=demuxer->stream;
    1322                demuxer->stream=new_memory_stream(moov_buf,moov_sz);
    1323                stream_skip(demuxer->stream,8);
    1324                lschunks(demuxer,level+1,moov_sz,NULL); // parse uncompr. 'moov'
    1325                //free_stream(demuxer->stream);
    1326               demuxer->stream=backup;
    1327               free(cmov_buf);
    1328               free(moov_buf);
    1329               break;
    1330         }
     647                    int version, adjust;
     648                    int is_vorbis = 0;
     649                    sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db);
     650                    sh->format=trak->fourcc;
     651
     652                    // crude audio delay from editlist0 hack ::atm
     653                    if(trak->editlist_size>=1) {
     654                        if(trak->editlist[0].pos == -1) {
     655                            sh->stream_delay = (float)trak->editlist[0].dur/(float)priv->timescale;
     656                            dprintf("MOV: Initial Audio-Delay: %.3f sec\n", sh->stream_delay);
     657                        }
     658                    }
     659
     660                    switch( sh->format ) {
     661                    case 0x726D6173: /* samr */
     662                        /* amr narrowband */
     663                        trak->samplebytes=sh->samplesize=1;
     664                        trak->nchannels=sh->channels=1;
     665                        sh->samplerate=8000;
     666                        break;
     667
     668                    case 0x62776173: /* sawb */
     669                        /* amr wideband */
     670                        trak->samplebytes=sh->samplesize=1;
     671                        trak->nchannels=sh->channels=1;
     672                        sh->samplerate=16000;
     673                        break;
     674
     675                    default:
     676
     677                        // assumptions for below table: short is 16bit, int is 32bit, intfp is 16bit
     678                        // XXX: 32bit fixed point numbers (intfp) are only 2 Byte!
     679                        // short values are usually one byte leftpadded by zero
     680                        //   int values are usually two byte leftpadded by zero
     681                        //  stdata[]:
     682                        //      8   short       version
     683                        //      10  short       revision
     684                        //      12  int         vendor_id
     685                        //      16  short       channels
     686                        //      18  short       samplesize
     687                        //      20  short       compression_id
     688                        //      22  short       packet_size (==0)
     689                        //      24  intfp       sample_rate
     690                        //     (26  short)      unknown (==0)
     691                        //    ---- qt3.0+ (version>=1)
     692                        //      28  int         samples_per_packet
     693                        //      32  int         bytes_per_packet
     694                        //      36  int         bytes_per_frame
     695                        //      40  int         bytes_per_sample
     696                        // there may be additional atoms following at 28 (version 0)
     697                        // or 44 (version 1), eg. esds atom of .MP4 files
     698                        // esds atom:
     699                        //      28  int         atom size (bytes of int size, int type and data)
     700                        //      32  char[4]     atom type (fourc charater code -> esds)
     701                        //      36  char[]      atom data (len=size-8)
     702
     703                        // TODO: fix parsing for files using version 2.
     704                        version=char2short(trak->stdata,8);
     705                        if (version > 1)
     706                            dprintf( "MOV: version %d sound atom may not parse correctly!\n", version);
     707                        trak->samplebytes=sh->samplesize=char2short(trak->stdata,18)/8;
     708
     709                        /* I can't find documentation, but so far this is the case. -Corey */
     710                        switch (char2short(trak->stdata,16)) {
     711                        case 1:
     712                            trak->nchannels = 1; break;
     713                        case 2:
     714                            trak->nchannels = 2; break;
     715                        case 3:
     716                            trak->nchannels = 6; break;
     717                        default:
     718                            dprintf(
     719                                    "MOV: unable to determine audio channels, assuming 2 (got %d)\n",
     720                                    char2short(trak->stdata,16));
     721                            trak->nchannels = 2;
     722                        }
     723                        sh->channels = trak->nchannels;
     724
     725                        /*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n",
     726                         trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur,
     727                         trak->durmap[0].num, trak->timescale/trak->durmap[0].dur,
     728                         char2short(trak->stdata,24)/trak->durmap[0].dur);*/
     729                        sh->samplerate=char2short(trak->stdata,24);
     730                        if((sh->samplerate < 7000) && trak->durmap) {
     731                            switch(char2short(trak->stdata,24)/trak->durmap[0].dur) {
     732                                // TODO: add more cases.
     733                            case 31:
     734                                sh->samplerate = 32000; break;
     735                            case 43:
     736                                sh->samplerate = 44100; break;
     737                            case 47:
     738                                sh->samplerate = 48000; break;
     739                            default:
     740                                dprintf(
     741                                        "MOV: unable to determine audio samplerate, "
     742                                        "assuming 44.1kHz (got %d)\n",
     743                                        char2short(trak->stdata,24)/trak->durmap[0].dur);
     744                                sh->samplerate = 44100;
     745                            }
     746                        }
     747                    }
     748                    dprintf( "Audio bits: %d  chans: %d  rate: %d\n",
     749                            sh->samplesize*8,sh->channels,sh->samplerate);
     750
     751                    if(trak->stdata_len >= 44 && trak->stdata[9]>=1){
     752                        dprintf("Audio header: samp/pack=%d bytes/pack=%d bytes/frame=%d bytes/samp=%d  \n",
     753                                char2int(trak->stdata,28),
     754                                char2int(trak->stdata,32),
     755                                char2int(trak->stdata,36),
     756                                char2int(trak->stdata,40));
     757                        if(trak->stdata_len>=44+8){
     758                            int len=char2int(trak->stdata,44);
     759                            int fcc=char2int(trak->stdata,48);
     760                            // we have extra audio headers!!!
     761                            dprintf("Audio extra header: len=%d  fcc=0x%X\n",len,fcc);
     762                            if((len >= 4) &&
     763                               (char2int(trak->stdata,52) >= 12) &&
     764                               (char2int(trak->stdata,52+4) == MOV_FOURCC('f','r','m','a'))) {
     765                                switch(char2int(trak->stdata,52+8)) {
     766                                case MOV_FOURCC('a','l','a','c'):
     767                                    if (len >= 36 + char2int(trak->stdata,52)) {
     768                                        sh->codecdata_len = char2int(trak->stdata,52+char2int(trak->stdata,52));
     769                                        dprintf( "MOV: Found alac atom (%d)!\n", sh->codecdata_len);
     770                                        sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
     771                                        memcpy(sh->codecdata, &trak->stdata[52+char2int(trak->stdata,52)], sh->codecdata_len);
     772                                    }
     773                                    break;
     774                                case MOV_FOURCC('i','n','2','4'):
     775                                case MOV_FOURCC('i','n','3','2'):
     776                                case MOV_FOURCC('f','l','3','2'):
     777                                case MOV_FOURCC('f','l','6','4'):
     778                                    if ((len >= 22) &&
     779                                        (char2int(trak->stdata,52+16)==MOV_FOURCC('e','n','d','a')) &&
     780                                        (char2short(trak->stdata,52+20))) {
     781                                        sh->format=char2int(trak->stdata,52+8);
     782                                        dprintf( "MOV: Found little endian PCM data, reversed fourcc:%04x\n", sh->format);
     783                                    }
     784                                    break;
     785                                default:
     786                                    if (len > 8 && len + 44 <= trak->stdata_len) {
     787                                        sh->codecdata_len = len-8;
     788                                        sh->codecdata = trak->stdata+44+8;
     789                                    }
     790                                }
     791                            } else {
     792                                if (len > 8 && len + 44 <= trak->stdata_len) {
     793                                    sh->codecdata_len = len-8;
     794                                    sh->codecdata = trak->stdata+44+8;
     795                                }
     796                            }
     797                        }
     798                    }
     799
     800                    switch (version) {
     801                    case 0:
     802                        adjust =  0; break;
     803                    case 1:
     804                        adjust = 48; break;
     805                    case 2:
     806                        adjust = 68; break;
     807                    default:
     808                        dprintf( "MOV: unknown sound atom version (%d); may not work!\n", version);
     809                        adjust = 68;
     810                    }
     811                    if (trak->stdata_len >= 36 + adjust) {
     812                        int atom_len = char2int(trak->stdata,28+adjust);
     813                        switch(char2int(trak->stdata,32+adjust)) { // atom type
     814                        case MOV_FOURCC('e','s','d','s'): {
     815                            dprintf( "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len);
     816                            if(atom_len > 8) {
     817                                esds_t esds;
     818                                if(!mp4_parse_esds(&trak->stdata[36+adjust], atom_len-8, &esds)) {
     819                                    /* 0xdd is a "user private" id, not an official allocated id (see http://www.mp4ra.org/object.html),
     820                                     so perform some extra checks to be sure that this is really vorbis audio */
     821                                    if(esds.objectTypeId==0xdd && esds.streamType==0x15 && sh->format==0x6134706D && esds.decoderConfigLen > 8)
     822                                    {
     823                                        //vorbis audio
     824                                        unsigned char *buf[3];
     825                                        unsigned short sizes[3];
     826                                        int offset, len, k;
     827                                        unsigned char *ptr = esds.decoderConfig;
     828
     829                                        if(ptr[0] != 0 || ptr[1] != 30) goto quit_vorbis_block; //wrong extradata layout
     830
     831                                        offset = len = 0;
     832                                        for(k = 0; k < 3; k++)
     833                                        {
     834                                            sizes[k] = (ptr[offset]<<8) | ptr[offset+1];
     835                                            len += sizes[k];
     836                                            offset += 2;
     837                                            if(offset + sizes[k] > esds.decoderConfigLen)
     838                                            {
     839                                                dprintf("MOV: ERROR!, not enough vorbis extradata to read: offset = %d, k=%d, size=%d, len: %d\n", offset, k, sizes[k], esds.decoderConfigLen);
     840                                                goto quit_vorbis_block;
     841                                            }
     842                                            buf[k] = malloc(sizes[k]);
     843                                            if(!buf[k]) goto quit_vorbis_block;
     844                                            memcpy(buf[k], &ptr[offset], sizes[k]);
     845                                            offset += sizes[k];
     846                                        }
     847
     848                                        sh->codecdata_len = len + len/255 + 64;
     849                                        sh->codecdata = malloc(sh->codecdata_len);
     850                                        ptr = sh->codecdata;
     851
     852                                        ptr[0] = 2;
     853                                        offset = 1;
     854                                        offset += store_ughvlc(&ptr[offset], sizes[0]);
     855                                        offset += store_ughvlc(&ptr[offset], sizes[1]);
     856                                        for(k = 0; k < 3; k++)
     857                                        {
     858                                            memcpy(&ptr[offset], buf[k], sizes[k]);
     859                                            offset += sizes[k];
     860                                        }
     861
     862                                        sh->codecdata_len = offset;
     863                                        sh->codecdata = realloc(sh->codecdata, offset);
     864                                        dprintf("demux_mov, vorbis extradata size: %d\n", offset);
     865                                        is_vorbis = 1;
     866                                    quit_vorbis_block:
     867                                        sh->format = mmioFOURCC('v', 'r', 'b', 's');
     868                                    }
     869                                    sh->i_bps = esds.avgBitrate/8;
     870
     871                                    //                      printf("######## audio format = %d ########\n",esds.objectTypeId);
     872                                    if(esds.objectTypeId==MP4OTI_MPEG1Audio || esds.objectTypeId==MP4OTI_MPEG2AudioPart3)
     873                                        sh->format=0x55; // .mp3
     874                                    if(esds.objectTypeId==MP4OTI_13kVoice) { // 13K Voice, defined by 3GPP2
     875                                        sh->format=mmioFOURCC('Q', 'c', 'l', 'p');
     876                                        trak->nchannels=sh->channels=1;
     877                                        trak->samplebytes=sh->samplesize=1;
     878                                    }
     879
     880                                    // dump away the codec specific configuration for the AAC decoder
     881                                    if(esds.decoderConfigLen){
     882                                        if( (esds.decoderConfig[0]>>3) == 29 )
     883                                            sh->format = 0x1d61346d; // request multi-channel mp3 decoder
     884                                        if(!is_vorbis)
     885                                        {
     886                                            sh->codecdata_len = esds.decoderConfigLen;
     887                                            sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
     888                                            memcpy(sh->codecdata, esds.decoderConfig, sh->codecdata_len);
     889                                        }
     890                                    }
     891                                }
     892                                mp4_free_esds(&esds); // freeup esds mem
     893#if 0
     894                                { FILE* f=fopen("esds.dat","wb");
     895                                    fwrite(&trak->stdata[36],atom_len-8,1,f);
     896                                fclose(f); }
    1331897#endif
    1332         case MOV_FOURCC('u','d','t','a'):
    1333         {
    1334             unsigned int udta_id;
    1335             off_t udta_len;
    1336             off_t udta_size = len;
    1337 
    1338             dprintf( "mov: user data record found\n");
    1339             dprintf( "Quicktime Clip Info:\n");
    1340 
    1341             while((len > 8) && (udta_size > 8))
    1342             {
    1343                 udta_len = stream_read_dword(demuxer->stream);
    1344                 udta_id = stream_read_dword(demuxer->stream);
    1345                 udta_size -= 8;
    1346                 dprintf( "udta_id: %.4s (len: %"PRId64")\n", (char *)&udta_id, (int64_t)udta_len);
    1347                 switch (udta_id)
    1348                 {
    1349                     case MOV_FOURCC(0xa9,'c','p','y'):
    1350                     case MOV_FOURCC(0xa9,'d','a','y'):
    1351                     case MOV_FOURCC(0xa9,'d','i','r'):
    1352                     /* 0xa9,'e','d','1' - '9' : edit timestamps */
    1353                     case MOV_FOURCC(0xa9,'f','m','t'):
    1354                     case MOV_FOURCC(0xa9,'i','n','f'):
    1355                     case MOV_FOURCC(0xa9,'p','r','d'):
    1356                     case MOV_FOURCC(0xa9,'p','r','f'):
    1357                     case MOV_FOURCC(0xa9,'r','e','q'):
    1358                     case MOV_FOURCC(0xa9,'s','r','c'):
    1359                     case MOV_FOURCC('n','a','m','e'):
    1360                     case MOV_FOURCC(0xa9,'n','a','m'):
    1361                     case MOV_FOURCC(0xa9,'A','R','T'):
    1362                     case MOV_FOURCC(0xa9,'c','m','t'):
    1363                     case MOV_FOURCC(0xa9,'a','u','t'):
    1364                     case MOV_FOURCC(0xa9,'s','w','r'):
    1365                     {
    1366                         off_t text_len = stream_read_word(demuxer->stream);
    1367                         char text[text_len+2+1];
    1368                         stream_read(demuxer->stream, (char *)&text, text_len+2);
    1369                         text[text_len+2] = 0x0;
    1370                         switch(udta_id)
    1371                         {
    1372                             case MOV_FOURCC(0xa9,'a','u','t'):
    1373                                 demux_info_add(demuxer, "author", &text[2]);
    1374                                 dprintf( " Author: %s\n", &text[2]);
    1375                                 break;
    1376                             case MOV_FOURCC(0xa9,'c','p','y'):
    1377                                 demux_info_add(demuxer, "copyright", &text[2]);
    1378                                 dprintf( " Copyright: %s\n", &text[2]);
    1379                                 break;
    1380                             case MOV_FOURCC(0xa9,'i','n','f'):
    1381                                 dprintf( " Info: %s\n", &text[2]);
    1382                                 break;
    1383                             case MOV_FOURCC('n','a','m','e'):
    1384                             case MOV_FOURCC(0xa9,'n','a','m'):
    1385                                 demux_info_add(demuxer, "name", &text[2]);
    1386                                 dprintf( " Name: %s\n", &text[2]);
    1387                                 break;
    1388                             case MOV_FOURCC(0xa9,'A','R','T'):
    1389                                 dprintf( " Artist: %s\n", &text[2]);
    1390                                 break;
    1391                             case MOV_FOURCC(0xa9,'d','i','r'):
    1392                                 dprintf( " Director: %s\n", &text[2]);
    1393                                 break;
    1394                             case MOV_FOURCC(0xa9,'c','m','t'):
    1395                                 demux_info_add(demuxer, "comments", &text[2]);
    1396                                 dprintf( " Comment: %s\n", &text[2]);
    1397                                 break;
    1398                             case MOV_FOURCC(0xa9,'r','e','q'):
    1399                                 dprintf( " Requirements: %s\n", &text[2]);
    1400                                 break;
    1401                             case MOV_FOURCC(0xa9,'s','w','r'):
    1402                                 demux_info_add(demuxer, "encoder", &text[2]);
    1403                                 dprintf( " Software: %s\n", &text[2]);
    1404                                 break;
    1405                             case MOV_FOURCC(0xa9,'d','a','y'):
    1406                                 dprintf( " Creation timestamp: %s\n", &text[2]);
    1407                                 break;
    1408                             case MOV_FOURCC(0xa9,'f','m','t'):
    1409                                 dprintf( " Format: %s\n", &text[2]);
    1410                                 break;
    1411                             case MOV_FOURCC(0xa9,'p','r','d'):
    1412                                 dprintf( " Producer: %s\n", &text[2]);
    1413                                 break;
    1414                             case MOV_FOURCC(0xa9,'p','r','f'):
    1415                                 dprintf( " Performer(s): %s\n", &text[2]);
    1416                                 break;
    1417                             case MOV_FOURCC(0xa9,'s','r','c'):
    1418                                 dprintf( " Source providers: %s\n", &text[2]);
    1419                                 break;
    1420                         }
    1421                         udta_size -= 4+text_len;
    1422                         break;
    1423                     }
    1424                     /* some other shits:    WLOC - window location,
    1425                                             LOOP - looping style,
    1426                                             SelO - play only selected frames
    1427                                             AllF - play all frames
    1428                     */
    1429                     case MOV_FOURCC('W','L','O','C'):
    1430                     case MOV_FOURCC('L','O','O','P'):
    1431                     case MOV_FOURCC('S','e','l','O'):
    1432                     case MOV_FOURCC('A','l','l','F'):
    1433                     default:
    1434                     {
    1435                         if( udta_len>udta_size)
    1436                                 udta_len=udta_size;
    1437                         {
    1438                         char dump[udta_len-4];
    1439                         stream_read(demuxer->stream, (char *)&dump, udta_len-4-4);
    1440                         udta_size -= udta_len;
    1441                         }
    1442                     }
    1443                 }
    1444             }
    1445             break;
    1446         } /* eof udta */
    1447         default:
    1448           id = be2me_32(id);
    1449           dprintf("MOV: unknown chunk: %.4s %d\n",(char *)&id,(int)len);
    1450         } /* endof switch */
    1451         } /* endof else */
    1452 
    1453         pos+=len+8;
    1454         if(pos>=endpos) break;
    1455         if(!stream_seek(demuxer->stream,pos)) break;
     898                            }
     899                        } break;
     900                        case MOV_FOURCC('a','l','a','c'): {
     901                            dprintf( "MOV: Found alac atom (%d)!\n", atom_len);
     902                            if(atom_len > 8) {
     903                                // copy all the atom (not only payload) for lavc alac decoder
     904                                sh->codecdata_len = atom_len;
     905                                sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
     906                                memcpy(sh->codecdata, &trak->stdata[28], sh->codecdata_len);
     907                            }
     908                        } break;
     909                        case MOV_FOURCC('d','a','m','r'):
     910                            dprintf( "MOV: Found AMR audio atom %c%c%c%c (%d)!\n", trak->stdata[32+adjust],trak->stdata[33+adjust],trak->stdata[34+adjust],trak->stdata[35+adjust], atom_len);
     911                            if (atom_len>14) {
     912                                dprintf( "mov: vendor: %c%c%c%c Version: %d\n",trak->stdata[36+adjust],trak->stdata[37+adjust],trak->stdata[38+adjust], trak->stdata[39+adjust],trak->stdata[40+adjust]);
     913                                dprintf( "MOV: Modes set: %02x%02x\n",trak->stdata[41+adjust],trak->stdata[42+adjust]);
     914                                dprintf( "MOV: Mode change period: %d Frames per sample: %d\n",trak->stdata[43+adjust],trak->stdata[44+adjust]);
     915                            }
     916                            break;
     917                        default:
     918                            dprintf( "MOV: Found unknown audio atom %c%c%c%c (%d)!\n",
     919                                    trak->stdata[32+adjust],trak->stdata[33+adjust],trak->stdata[34+adjust],trak->stdata[35+adjust],
     920                                    atom_len);
     921                        }
     922                    }
     923                    dprintf( "Fourcc: %.4s\n",(char *)&trak->fourcc);
     924#if 0
     925                    { FILE* f=fopen("stdata.dat","wb");
     926                        fwrite(trak->stdata,trak->stdata_len,1,f);
     927                    fclose(f); }
     928                    { FILE* f=fopen("tkdata.dat","wb");
     929                        fwrite(trak->tkdata,trak->tkdata_len,1,f);
     930                    fclose(f); }
     931#endif
     932                    // Emulate WAVEFORMATEX struct:
     933                    sh->wf=malloc(sizeof(WAVEFORMATEX) + (is_vorbis ? sh->codecdata_len : 0));
     934                    memset(sh->wf,0,sizeof(WAVEFORMATEX));
     935                    sh->wf->nChannels=sh->channels;
     936                    sh->wf->wBitsPerSample=(trak->stdata[18]<<8)+trak->stdata[19];
     937                    // sh->wf->nSamplesPerSec=trak->timescale;
     938                    sh->wf->nSamplesPerSec=sh->samplerate;
     939                    if(trak->stdata_len >= 44 && trak->stdata[9]>=1 && char2int(trak->stdata,28)>0){
     940                        //Audio header: samp/pack=4096 bytes/pack=743 bytes/frame=1486 bytes/samp=2
     941                        sh->wf->nAvgBytesPerSec=(sh->wf->nChannels*sh->wf->nSamplesPerSec*
     942                                                 char2int(trak->stdata,32)+char2int(trak->stdata,28)/2)
     943                            /char2int(trak->stdata,28);
     944                        sh->wf->nBlockAlign=char2int(trak->stdata,36);
     945                    } else {
     946                        sh->wf->nAvgBytesPerSec=sh->wf->nChannels*sh->wf->wBitsPerSample*sh->wf->nSamplesPerSec/8;
     947                        // workaround for ms11 ima4
     948                        if (sh->format == 0x1100736d && trak->stdata_len >= 36)
     949                            sh->wf->nBlockAlign=char2int(trak->stdata,36);
     950                    }
     951                    if(is_vorbis && sh->codecdata_len)
     952                    {
     953                        memcpy(sh->wf+1, sh->codecdata, sh->codecdata_len);
     954                        sh->wf->cbSize = sh->codecdata_len;
     955                    }
     956                    // Selection:
     957                    //          if(demuxer->audio->id==-1 || demuxer->audio->id==priv->track_db){
     958                    //              // (auto)selected audio track:
     959                    //              demuxer->audio->id=priv->track_db;
     960                    //              demuxer->audio->sh=sh; sh->ds=demuxer->audio;
     961                    //          }
     962                    break;
     963                }
     964                case MOV_TRAK_VIDEO: {
     965                    int i, entry;
     966                    int flag, start, count_flag, end, palette_count, gray;
     967                    int hdr_ptr = 76;  // the byte just after depth
     968                    unsigned char *palette_map;
     969                    sh_video_t* sh=new_sh_video(demuxer,priv->track_db);
     970                    int depth;
     971                    sh->format=trak->fourcc;
     972
     973                    // crude video delay from editlist0 hack ::atm
     974                    if(trak->editlist_size>=1) {
     975                        if(trak->editlist[0].pos == -1) {
     976                            sh->stream_delay = (float)trak->editlist[0].dur/(float)priv->timescale;
     977                            dprintf("MOV: Initial Video-Delay: %.3f sec\n", sh->stream_delay);
     978                        }
     979                    }
     980
     981                    if (trak->stdata_len < 78) {
     982                        dprintf("MOV: Invalid (%d bytes instead of >= 78) video trak desc\n",
     983                                trak->stdata_len);
     984                        break;
     985                    }
     986                    depth = trak->stdata[75] | (trak->stdata[74] << 8);
     987                    //  stdata[]:
     988                    //  8   short       version
     989                    //  10  short       revision
     990                    //  12  int         vendor_id
     991                    //  16  int         temporal_quality
     992                    //  20  int         spatial_quality
     993                    //  24  short       width
     994                    //  26  short       height
     995                    //  28  int         h_dpi
     996                    //  32  int         v_dpi
     997                    //  36  int         0
     998                    //  40  short       frames_per_sample
     999                    //  42  char[4]     compressor_name
     1000                    //  74  short       depth
     1001                    //  76  short       color_table_id
     1002                    // additional atoms may follow,
     1003                    // eg esds atom from .MP4 files
     1004                    //      78  int             atom size
     1005                    //      82  char[4] atom type
     1006                    //  86  ...         atom data
     1007
     1008                    {   ImageDescription* id=malloc(8+trak->stdata_len);  // safe
     1009                        trak->desc=id;
     1010                    id->idSize=8+trak->stdata_len;
     1011                    //          id->cType=bswap_32(trak->fourcc);
     1012                    id->cType=le2me_32(trak->fourcc);
     1013                    id->version=char2short(trak->stdata,8);
     1014                    id->revisionLevel=char2short(trak->stdata,10);
     1015                    id->vendor=char2int(trak->stdata,12);
     1016                    id->temporalQuality=char2int(trak->stdata,16);
     1017                    id->spatialQuality=char2int(trak->stdata,20);
     1018                    id->width=char2short(trak->stdata,24);
     1019                    id->height=char2short(trak->stdata,26);
     1020                    id->hRes=char2int(trak->stdata,28);
     1021                    id->vRes=char2int(trak->stdata,32);
     1022                    id->dataSize=char2int(trak->stdata,36);
     1023                    id->frameCount=char2short(trak->stdata,40);
     1024                    memcpy(&id->name,trak->stdata+42,32);
     1025                    id->depth=char2short(trak->stdata,74);
     1026                    id->clutID=char2short(trak->stdata,76);
     1027                    if(trak->stdata_len>78)     memcpy(((char*)&id->clutID)+2,trak->stdata+78,trak->stdata_len-78);
     1028                    sh->ImageDesc=id;
     1029#if 0
     1030                    {   FILE *f=fopen("ImageDescription","wb");
     1031                        fwrite(id,id->idSize,1,f);
     1032                    fclose(f);
     1033                    }
     1034#endif
     1035                    }
     1036
     1037                    if(trak->stdata_len >= 86) { // extra atoms found
     1038                        int pos=78;
     1039                        int atom_len;
     1040                        while(pos+8<=trak->stdata_len &&
     1041                              (pos+(atom_len=char2int(trak->stdata,pos)))<=trak->stdata_len){
     1042                            switch(char2int(trak->stdata,pos+4)) { // switch atom type
     1043                            case MOV_FOURCC('g','a','m','a'):
     1044                                // intfp with gamma value at which movie was captured
     1045                                // can be used to gamma correct movie display
     1046                                dprintf( "MOV: Found unsupported Gamma-Correction movie atom (%d)!\n",
     1047                                        atom_len);
     1048                                break;
     1049                            case MOV_FOURCC('f','i','e','l'):
     1050                                // 2 char-values (8bit int) that specify field handling
     1051                                // see the Apple's QuickTime Fileformat PDF for more info
     1052                                dprintf( "MOV: Found unsupported Field-Handling movie atom (%d)!\n",
     1053                                        atom_len);
     1054                                break;
     1055                            case MOV_FOURCC('m','j','q','t'):
     1056                                // Motion-JPEG default quantization table
     1057                                dprintf( "MOV: Found unsupported MJPEG-Quantization movie atom (%d)!\n",
     1058                                        atom_len);
     1059                                break;
     1060                            case MOV_FOURCC('m','j','h','t'):
     1061                                // Motion-JPEG default huffman table
     1062                                dprintf( "MOV: Found unsupported MJPEG-Huffman movie atom (%d)!\n",
     1063                                        atom_len);
     1064                                break;
     1065                            case MOV_FOURCC('e','s','d','s'):
     1066                                // MPEG4 Elementary Stream Descriptor header
     1067                                dprintf( "MOV: Found MPEG4 movie Elementary Stream Descriptor atom (%d)!\n", atom_len);
     1068                                // add code here to save esds header of length atom_len-8
     1069                                // beginning at stdata[86] to some variable to pass it
     1070                                // on to the decoder ::atmos
     1071                                if(atom_len > 8) {
     1072                                    esds_t esds;
     1073                                    if(!mp4_parse_esds(trak->stdata+pos+8, atom_len-8, &esds)) {
     1074
     1075                                        if(esds.objectTypeId==MP4OTI_MPEG2VisualSimple || esds.objectTypeId==MP4OTI_MPEG2VisualMain ||
     1076                                           esds.objectTypeId==MP4OTI_MPEG2VisualSNR || esds.objectTypeId==MP4OTI_MPEG2VisualSpatial ||
     1077                                           esds.objectTypeId==MP4OTI_MPEG2VisualHigh || esds.objectTypeId==MP4OTI_MPEG2Visual422)
     1078                                            sh->format=mmioFOURCC('m', 'p', 'g', '2');
     1079                                        else if(esds.objectTypeId==MP4OTI_MPEG1Visual)
     1080                                            sh->format=mmioFOURCC('m', 'p', 'g', '1');
     1081
     1082                                        // dump away the codec specific configuration for the AAC decoder
     1083                                        trak->stream_header_len = esds.decoderConfigLen;
     1084                                        trak->stream_header = (unsigned char *)malloc(trak->stream_header_len);
     1085                                        memcpy(trak->stream_header, esds.decoderConfig, trak->stream_header_len);
     1086                                    }
     1087                                    mp4_free_esds(&esds); // freeup esds mem
     1088                                }
     1089                                break;
     1090                            case MOV_FOURCC('a','v','c','C'):
     1091                                // AVC decoder configuration record
     1092                                dprintf( "MOV: AVC decoder configuration record atom (%d)!\n", atom_len);
     1093                                if(atom_len > 8) {
     1094                                    int i, poffs, cnt;
     1095                                    // Parse some parts of avcC, just for fun :)
     1096                                    // real parsing is done by avc1 decoder
     1097                                    dprintf( "MOV: avcC version: %d\n", *(trak->stdata+pos+8));
     1098                                    if (*(trak->stdata+pos+8) != 1)
     1099                                        dprintf( "MOV: unknown avcC version (%d). Expexct problems.\n", *(trak->stdata+pos+9));
     1100                                    dprintf( "MOV: avcC profile: %d\n", *(trak->stdata+pos+9));
     1101                                    dprintf( "MOV: avcC profile compatibility: %d\n", *(trak->stdata+pos+10));
     1102                                    dprintf( "MOV: avcC level: %d\n", *(trak->stdata+pos+11));
     1103                                    dprintf( "MOV: avcC nal length size: %d\n", ((*(trak->stdata+pos+12))&0x03)+1);
     1104                                    dprintf( "MOV: avcC number of sequence param sets: %d\n", cnt = (*(trak->stdata+pos+13) & 0x1f));
     1105                                    poffs = pos + 14;
     1106                                    for (i = 0; i < cnt; i++) {
     1107                                        dprintf( "MOV: avcC sps %d have length %d\n", i, BE_16(trak->stdata+poffs));
     1108                                        poffs += BE_16(trak->stdata+poffs) + 2;
     1109                                    }
     1110                                    dprintf( "MOV: avcC number of picture param sets: %d\n", *(trak->stdata+poffs));
     1111                                    poffs++;
     1112                                    for (i = 0; i < cnt; i++) {
     1113                                        dprintf( "MOV: avcC pps %d have length %d\n", i, BE_16(trak->stdata+poffs));
     1114                                        poffs += BE_16(trak->stdata+poffs) + 2;
     1115                                    }
     1116                                    // Copy avcC for the AVC decoder
     1117                                    // This data will be put in extradata below, where BITMAPINFOHEADER is created
     1118                                    trak->stream_header_len = atom_len-8;
     1119                                    trak->stream_header = (unsigned char *)malloc(trak->stream_header_len);
     1120                                    memcpy(trak->stream_header, trak->stdata+pos+8, trak->stream_header_len);
     1121                                }
     1122                                break;
     1123                            case MOV_FOURCC('d','2','6','3'):
     1124                                dprintf( "MOV: Found H.263 decoder atom %c%c%c%c (%d)!\n", trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],atom_len);
     1125                                if (atom_len>10)
     1126                                    dprintf( "MOV: Vendor: %c%c%c%c H.263 level: %d H.263 profile: %d \n", trak->stdata[pos+8],trak->stdata[pos+9],trak->stdata[pos+10],trak->stdata[pos+11],trak->stdata[pos+12],trak->stdata[pos+13]);
     1127                                break;
     1128                            case 0:
     1129                                break;
     1130                            default:
     1131                                dprintf( "MOV: Found unknown movie atom %c%c%c%c (%d)!\n",
     1132                                        trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],
     1133                                        atom_len);
     1134                            }
     1135                            if(atom_len<8) break;
     1136                            pos+=atom_len;
     1137                            //             printf("pos=%d max=%d\n",pos,trak->stdata_len);
     1138                        }
     1139                    }
     1140                    sh->fps=trak->timescale/
     1141                        ((trak->durmap_size>=1)?(float)trak->durmap[0].dur:1);
     1142                    sh->frametime=1.0f/sh->fps;
     1143
     1144                    sh->disp_w=trak->stdata[25]|(trak->stdata[24]<<8);
     1145                    sh->disp_h=trak->stdata[27]|(trak->stdata[26]<<8);
     1146                    // if image size is zero, fallback to display size
     1147                    if(!sh->disp_w && !sh->disp_h) {
     1148                        sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8);
     1149                        sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8);
     1150                    } else if(sh->disp_w!=(trak->tkdata[77]|(trak->tkdata[76]<<8))){
     1151                        // codec and display width differ... use display one for aspect
     1152                        sh->aspect=trak->tkdata[77]|(trak->tkdata[76]<<8);
     1153                        sh->aspect/=trak->tkdata[81]|(trak->tkdata[80]<<8);
     1154                    }
     1155
     1156                    if(depth>32+8) printf("*** depth = 0x%X\n",depth);
     1157
     1158                    // palettized?
     1159                    gray = 0;
     1160                    if (depth > 32) { depth&=31; gray = 1; } // depth > 32 means grayscale
     1161                    if ((depth == 2) || (depth == 4) || (depth == 8))
     1162                        palette_count = (1 << depth);
     1163                    else
     1164                        palette_count = 0;
     1165
     1166                    // emulate BITMAPINFOHEADER:
     1167                    if (palette_count)
     1168                    {
     1169                        sh->bih=malloc(sizeof(BITMAPINFOHEADERw) + palette_count * 4);
     1170                        memset(sh->bih,0,sizeof(BITMAPINFOHEADERw) + palette_count * 4);
     1171                        sh->bih->biSize=40 + palette_count * 4;
     1172                        // fetch the relevant fields
     1173                        flag = BE_16(&trak->stdata[hdr_ptr]);
     1174                        hdr_ptr += 2;
     1175                        start = BE_32(&trak->stdata[hdr_ptr]);
     1176                        hdr_ptr += 4;
     1177                        count_flag = BE_16(&trak->stdata[hdr_ptr]);
     1178                        hdr_ptr += 2;
     1179                        end = BE_16(&trak->stdata[hdr_ptr]);
     1180                        hdr_ptr += 2;
     1181                        palette_map = (unsigned char *)sh->bih + 40;
     1182                        dprintf( "Allocated %d entries for palette\n",
     1183                                palette_count);
     1184                        dprintf( "QT palette: start: %x, end: %x, count flag: %d, flags: %x\n",
     1185                                start, end, count_flag, flag);
     1186
     1187                        /* XXX: problems with sample (statunit6.mov) with flag&0x4 set! - alex*/
     1188
     1189                        // load default palette
     1190                        if (flag & 0x08)
     1191                        {
     1192                            if (gray)
     1193                            {
     1194                                dprintf( "Using default QT grayscale palette\n");
     1195                                if (palette_count == 16)
     1196                                    memcpy(palette_map, qt_default_grayscale_palette_16, 16 * 4);
     1197                                else if (palette_count == 256) {
     1198                                    memcpy(palette_map, qt_default_grayscale_palette_256, 256 * 4);
     1199                                    if (trak->fourcc == mmioFOURCC('c','v','i','d')) {
     1200                                        int i;
     1201                                        // Hack for grayscale CVID, negative palette
     1202                                        // If you have samples where this is not required contact me (rxt)
     1203                                        dprintf( "MOV: greyscale cvid with default palette,"
     1204                                                " enabling negative palette hack.\n");
     1205                                        for (i = 0; i < 256 * 4; i++)
     1206                                            palette_map[i] = palette_map[i] ^ 0xff;
     1207                                    }
     1208                                }
     1209                            }
     1210                            else
     1211                            {
     1212                                dprintf( "Using default QT colour palette\n");
     1213                                if (palette_count == 4)
     1214                                    memcpy(palette_map, qt_default_palette_4, 4 * 4);
     1215                                else if (palette_count == 16)
     1216                                    memcpy(palette_map, qt_default_palette_16, 16 * 4);
     1217                                else if (palette_count == 256)
     1218                                    memcpy(palette_map, qt_default_palette_256, 256 * 4);
     1219                            }
     1220                        }
     1221                        // load palette from file
     1222                        else
     1223                        {
     1224                            dprintf( "Loading palette from file\n");
     1225                            for (i = start; i <= end; i++)
     1226                            {
     1227                                entry = BE_16(&trak->stdata[hdr_ptr]);
     1228                                hdr_ptr += 2;
     1229                                // apparently, if count_flag is set, entry is same as i
     1230                                if (count_flag & 0x8000)
     1231                                    entry = i;
     1232                                // only care about top 8 bits of 16-bit R, G, or B value
     1233                                if (entry <= palette_count && entry >= 0)
     1234                                {
     1235                                    palette_map[entry * 4 + 2] = trak->stdata[hdr_ptr + 0];
     1236                                    palette_map[entry * 4 + 1] = trak->stdata[hdr_ptr + 2];
     1237                                    palette_map[entry * 4 + 0] = trak->stdata[hdr_ptr + 4];
     1238                                    dprintf("QT palette: added entry: %d of %d (colors: R:%x G:%x B:%x)\n",
     1239                                            entry, palette_count,
     1240                                            palette_map[entry * 4 + 2],
     1241                                            palette_map[entry * 4 + 1],
     1242                                            palette_map[entry * 4 + 0]);
     1243                                }
     1244                                else
     1245                                    dprintf( "QT palette: skipped entry (out of count): %d of %d\n",
     1246                                            entry, palette_count);
     1247                                hdr_ptr += 6;
     1248                            }
     1249                        }
     1250                    }
     1251                    else
     1252                    {
     1253                        if (trak->fourcc == mmioFOURCC('a','v','c','1')) {
     1254                            if (trak->stream_header_len > 0xffffffff - sizeof(BITMAPINFOHEADERw)) {
     1255                                dprintf("Invalid extradata size %d, skipping\n");
     1256                                trak->stream_header_len = 0;
     1257                            }
     1258
     1259                            sh->bih=malloc(sizeof(BITMAPINFOHEADERw) + trak->stream_header_len);
     1260                            memset(sh->bih,0,sizeof(BITMAPINFOHEADERw) + trak->stream_header_len);
     1261                            sh->bih->biSize=40  + trak->stream_header_len;
     1262                            memcpy(((unsigned char *)sh->bih)+40,  trak->stream_header, trak->stream_header_len);
     1263                            free (trak->stream_header);
     1264                            trak->stream_header_len = 0;
     1265                            trak->stream_header = NULL;
     1266                        } else {
     1267                            sh->bih=malloc(sizeof(BITMAPINFOHEADERw));
     1268                            memset(sh->bih,0,sizeof(BITMAPINFOHEADERw));
     1269                            sh->bih->biSize=40;
     1270                        }
     1271                    }
     1272                    sh->bih->biWidth=sh->disp_w;
     1273                    sh->bih->biHeight=sh->disp_h;
     1274                    sh->bih->biPlanes=0;
     1275                    sh->bih->biBitCount=depth;
     1276                    sh->bih->biCompression=trak->fourcc;
     1277                    sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight;
     1278
     1279                    dprintf( "Image size: %d x %d (%d bpp)\n",sh->disp_w,sh->disp_h,sh->bih->biBitCount);
     1280                    if(trak->tkdata_len>81)
     1281                        dprintf( "Display size: %d x %d\n",
     1282                                trak->tkdata[77]|(trak->tkdata[76]<<8),
     1283                                trak->tkdata[81]|(trak->tkdata[80]<<8));
     1284                    dprintf( "Fourcc: %.4s  Codec: '%.*s'\n",(char *)&trak->fourcc,trak->stdata[42]&31,trak->stdata+43);
     1285
     1286                    //          if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){
     1287                    //              // (auto)selected video track:
     1288                    //              demuxer->video->id=priv->track_db;
     1289                    //              demuxer->video->sh=sh; sh->ds=demuxer->video;
     1290                    //          }
     1291                    break;
     1292                }
     1293                case MOV_TRAK_GENERIC:
     1294                    dprintf( "Generic track - not completely understood! (id: %d)\n",
     1295                            trak->id);
     1296                    /* XXX: Also this contains the FLASH data */
     1297
     1298#if 0
     1299                    {
     1300                        int pos = stream_tell(demuxer->stream);
     1301                        int i;
     1302                        int fd;
     1303                        char name[20];
     1304
     1305                        for (i=0; i<trak->samples_size; i++)
     1306                        {
     1307                            char buf[trak->samples[i].size];
     1308                            stream_seek(demuxer->stream, trak->samples[i].pos);
     1309                            snprintf((char *)&name[0], 20, "samp%d", i);
     1310                            fd = open((char *)&name[0], O_CREAT|O_WRONLY);
     1311                            stream_read(demuxer->stream, &buf[0], trak->samples[i].size);
     1312                            write(fd, &buf[0], trak->samples[i].size);
     1313                            close(fd);
     1314                        }
     1315                        for (i=0; i<trak->chunks_size; i++)
     1316                        {
     1317                            char buf[trak->length];
     1318                            stream_seek(demuxer->stream, trak->chunks[i].pos);
     1319                            snprintf((char *)&name[0], 20, "chunk%d", i);
     1320                            fd = open((char *)&name[0], O_CREAT|O_WRONLY);
     1321                            stream_read(demuxer->stream, &buf[0], trak->length);
     1322                            write(fd, &buf[0], trak->length);
     1323                            close(fd);
     1324                        }
     1325                        if (trak->samplesize > 0)
     1326                        {
     1327                            char *buf;
     1328
     1329                            buf = malloc(trak->samplesize);
     1330                            stream_seek(demuxer->stream, trak->chunks[0].pos);
     1331                            snprintf((char *)&name[0], 20, "trak%d", trak->id);
     1332                            fd = open((char *)&name[0], O_CREAT|O_WRONLY);
     1333                            stream_read(demuxer->stream, buf, trak->samplesize);
     1334                            write(fd, buf, trak->samplesize);
     1335                            close(fd);
     1336                        }
     1337                        stream_seek(demuxer->stream, pos);
     1338                    }
     1339#endif
     1340                    break;
     1341                default:
     1342                    dprintf( "Unknown track type found (type: %d)\n", trak->type);
     1343                    break;
     1344                }
     1345                dprintf( "--------------\n");
     1346                priv->track_db++;
     1347                trak=NULL;
     1348                break;
     1349            }
     1350#ifndef HAVE_ZLIB
     1351            case MOV_FOURCC('c','m','o','v'): {
     1352                dprintf("MOV: got compressed header but have no zlib\n");
     1353                return;
     1354            }
     1355#else
     1356            case MOV_FOURCC('m','o','o','v'):
     1357            case MOV_FOURCC('c','m','o','v'): {
     1358                //          dprintf(MSGTR_MOVcomprhdr);
     1359                lschunks(demuxer,level+1,pos+len,NULL);
     1360                break;
     1361            }
     1362            case MOV_FOURCC('d','c','o','m'): {
     1363                //          int temp=stream_read_dword(demuxer->stream);
     1364                unsigned int algo=be2me_32(stream_read_dword(demuxer->stream));
     1365                dprintf( "Compressed header uses %.4s algo!\n",(char *)&algo);
     1366                break;
     1367            }
     1368            case MOV_FOURCC('c','m','v','d'): {
     1369                //          int temp=stream_read_dword(demuxer->stream);
     1370                unsigned int moov_sz=stream_read_dword(demuxer->stream);
     1371                unsigned int cmov_sz=len-4;
     1372                unsigned char* cmov_buf;
     1373                unsigned char* moov_buf;
     1374                int zret;
     1375                z_stream zstrm;
     1376                stream_t* backup;
     1377
     1378                if (moov_sz > 0xffffffff - 16) {
     1379                    dprintf("Invalid cmvd atom size %d\n", moov_sz);
     1380                    break;
     1381                }
     1382                cmov_buf=malloc(cmov_sz);
     1383                moov_buf=malloc(moov_sz+16);
     1384                dprintf( "Compressed header size: %d / %d\n",cmov_sz,moov_sz);
     1385
     1386                stream_read(demuxer->stream,cmov_buf,cmov_sz);
     1387
     1388                zstrm.zalloc          = (alloc_func)0;
     1389                zstrm.zfree           = (free_func)0;
     1390                zstrm.opaque          = (voidpf)0;
     1391                zstrm.next_in         = cmov_buf;
     1392                zstrm.avail_in        = cmov_sz;
     1393                zstrm.next_out        = moov_buf;
     1394                zstrm.avail_out       = moov_sz;
     1395
     1396                zret = inflateInit(&zstrm);
     1397                if (zret != Z_OK)
     1398                { dprintf( "QT cmov: inflateInit err %d\n",zret);
     1399                    return;
     1400                }
     1401                zret = inflate(&zstrm, Z_NO_FLUSH);
     1402                if ((zret != Z_OK) && (zret != Z_STREAM_END))
     1403                { dprintf( "QT cmov inflate: ERR %d\n",zret);
     1404                    return;
     1405                }
     1406#if 0
     1407                else {
     1408                    FILE *DecOut;
     1409                    DecOut = fopen("Out.bin", "w");
     1410                    fwrite(moov_buf, 1, moov_sz, DecOut);
     1411                    fclose(DecOut);
     1412                }
     1413#endif
     1414                if(moov_sz != zstrm.total_out)
     1415                    dprintf( "Warning! moov size differs cmov: %d  zlib: %ld\n",moov_sz,zstrm.total_out);
     1416                zret = inflateEnd(&zstrm);
     1417
     1418                backup=demuxer->stream;
     1419                demuxer->stream=new_memory_stream(moov_buf,moov_sz);
     1420                stream_skip(demuxer->stream,8);
     1421                lschunks(demuxer,level+1,moov_sz,NULL); // parse uncompr. 'moov'
     1422                //free_stream(demuxer->stream);
     1423                demuxer->stream=backup;
     1424                free(cmov_buf);
     1425                free(moov_buf);
     1426                break;
     1427            }
     1428#endif
     1429            case MOV_FOURCC('u','d','t','a'):
     1430                {
     1431                    unsigned int udta_id;
     1432                    off_t udta_len;
     1433                    off_t udta_size = len;
     1434
     1435                    dprintf( "mov: user data record found\n");
     1436                    dprintf( "Quicktime Clip Info:\n");
     1437
     1438                    while((len > 8) && (udta_size > 8))
     1439                    {
     1440                        udta_len = stream_read_dword(demuxer->stream);
     1441                        udta_id = stream_read_dword(demuxer->stream);
     1442                        udta_size -= 8;
     1443                        dprintf( "udta_id: %.4s (len: %"PRId64")\n", (char *)&udta_id, (int64_t)udta_len);
     1444                        switch (udta_id)
     1445                        {
     1446                        case MOV_FOURCC(0xa9,'c','p','y'):
     1447                        case MOV_FOURCC(0xa9,'d','a','y'):
     1448                        case MOV_FOURCC(0xa9,'d','i','r'):
     1449                            /* 0xa9,'e','d','1' - '9' : edit timestamps */
     1450                        case MOV_FOURCC(0xa9,'f','m','t'):
     1451                        case MOV_FOURCC(0xa9,'i','n','f'):
     1452                        case MOV_FOURCC(0xa9,'p','r','d'):
     1453                        case MOV_FOURCC(0xa9,'p','r','f'):
     1454                        case MOV_FOURCC(0xa9,'r','e','q'):
     1455                        case MOV_FOURCC(0xa9,'s','r','c'):
     1456                        case MOV_FOURCC('n','a','m','e'):
     1457                        case MOV_FOURCC(0xa9,'n','a','m'):
     1458                        case MOV_FOURCC(0xa9,'A','R','T'):
     1459                        case MOV_FOURCC(0xa9,'c','m','t'):
     1460                        case MOV_FOURCC(0xa9,'a','u','t'):
     1461                        case MOV_FOURCC(0xa9,'s','w','r'):
     1462                            {
     1463                                off_t text_len = stream_read_word(demuxer->stream);
     1464                                char text[text_len+2+1];
     1465                                stream_read(demuxer->stream, (char *)&text, text_len+2);
     1466                                text[text_len+2] = 0x0;
     1467                                switch(udta_id)
     1468                                {
     1469                                case MOV_FOURCC(0xa9,'a','u','t'):
     1470                                    demux_info_add(demuxer, "author", &text[2]);
     1471                                    dprintf( " Author: %s\n", &text[2]);
     1472                                    break;
     1473                                case MOV_FOURCC(0xa9,'c','p','y'):
     1474                                    demux_info_add(demuxer, "copyright", &text[2]);
     1475                                    dprintf( " Copyright: %s\n", &text[2]);
     1476                                    break;
     1477                                case MOV_FOURCC(0xa9,'i','n','f'):
     1478                                    dprintf( " Info: %s\n", &text[2]);
     1479                                    break;
     1480                                case MOV_FOURCC('n','a','m','e'):
     1481                                case MOV_FOURCC(0xa9,'n','a','m'):
     1482                                    demux_info_add(demuxer, "name", &text[2]);
     1483                                    dprintf( " Name: %s\n", &text[2]);
     1484                                    break;
     1485                                case MOV_FOURCC(0xa9,'A','R','T'):
     1486                                    dprintf( " Artist: %s\n", &text[2]);
     1487                                    break;
     1488                                case MOV_FOURCC(0xa9,'d','i','r'):
     1489                                    dprintf( " Director: %s\n", &text[2]);
     1490                                    break;
     1491                                case MOV_FOURCC(0xa9,'c','m','t'):
     1492                                    demux_info_add(demuxer, "comments", &text[2]);
     1493                                    dprintf( " Comment: %s\n", &text[2]);
     1494                                    break;
     1495                                case MOV_FOURCC(0xa9,'r','e','q'):
     1496                                    dprintf( " Requirements: %s\n", &text[2]);
     1497                                    break;
     1498                                case MOV_FOURCC(0xa9,'s','w','r'):
     1499                                    demux_info_add(demuxer, "encoder", &text[2]);
     1500                                    dprintf( " Software: %s\n", &text[2]);
     1501                                    break;
     1502                                case MOV_FOURCC(0xa9,'d','a','y'):
     1503                                    dprintf( " Creation timestamp: %s\n", &text[2]);
     1504                                    break;
     1505                                case MOV_FOURCC(0xa9,'f','m','t'):
     1506                                    dprintf( " Format: %s\n", &text[2]);
     1507                                    break;
     1508                                case MOV_FOURCC(0xa9,'p','r','d'):
     1509                                    dprintf( " Producer: %s\n", &text[2]);
     1510                                    break;
     1511                                case MOV_FOURCC(0xa9,'p','r','f'):
     1512                                    dprintf( " Performer(s): %s\n", &text[2]);
     1513                                    break;
     1514                                case MOV_FOURCC(0xa9,'s','r','c'):
     1515                                    dprintf( " Source providers: %s\n", &text[2]);
     1516                                    break;
     1517                                }
     1518                                udta_size -= 4+text_len;
     1519                                break;
     1520                            }
     1521                            /* some other shits:    WLOC - window location,
     1522                             LOOP - looping style,
     1523                             SelO - play only selected frames
     1524                             AllF - play all frames
     1525                             */
     1526                        case MOV_FOURCC('W','L','O','C'):
     1527                        case MOV_FOURCC('L','O','O','P'):
     1528                        case MOV_FOURCC('S','e','l','O'):
     1529                        case MOV_FOURCC('A','l','l','F'):
     1530                        default:
     1531                            {
     1532                                if( udta_len>udta_size)
     1533                                    udta_len=udta_size;
     1534                                {
     1535                                    char dump[udta_len-4];
     1536                                    stream_read(demuxer->stream, (char *)&dump, udta_len-4-4);
     1537                                    udta_size -= udta_len;
     1538                                }
     1539                            }
     1540                        }
     1541                    }
     1542                    break;
     1543                } /* eof udta */
     1544            default:
     1545                id = be2me_32(id);
     1546                dprintf("MOV: unknown chunk: %.4s %d\n",(char *)&id,(int)len);
     1547            } /* endof switch */
     1548        } /* endof else */
     1549
     1550        pos+=len+8;
     1551        if(pos>=endpos) break;
     1552        if(!stream_seek(demuxer->stream,pos)) break;
    14561553    }
    14571554}
     
    15021599    }
    15031600    case MOV_FOURCC('m','d','h','d'): {
    1504       dprintf( "MOV: %*sMedia header!\n", level, "");
    1505       stream_skip(demuxer->stream, 12);
    1506       // read timescale
    1507       trak->timescale = stream_read_dword(demuxer->stream);
    1508       // read length
    1509       trak->length = stream_read_dword(demuxer->stream);
     1601        dprintf( "MOV: %*sMedia header!\n", level, "");
     1602        int version = stream_read_char(demuxer->stream);
     1603        stream_skip(demuxer->stream, (version == 1) ? 19 : 11);
     1604        // read timescale
     1605        trak->timescale = stream_read_dword(demuxer->stream);
     1606        // read length
     1607        if (version == 1)
     1608            trak->length = stream_read_qword(demuxer->stream);
     1609        else
     1610            trak->length = stream_read_dword(demuxer->stream);
    15101611      break;
    15111612    }
     
    18231924            demuxer->video->id=-2;
    18241925        }
     1926    }
     1927
     1928    if(demuxer->video->id<0 && demuxer->audio->id<0) {
     1929        /* No AV streams found. Try to find an MPEG stream. */
     1930        for(t_no=0;t_no<priv->track_db;t_no++){
     1931            mov_track_t* trak=priv->tracks[t_no];
     1932            if(trak->media_handler == MOV_FOURCC('M','P','E','G')) {
     1933                stream_t *s;
     1934                demuxer_t *od;
     1935
     1936                demuxer->video->id = t_no;
     1937                s = new_ds_stream(demuxer->video);
     1938                od = demux_open(s, DEMUXER_TYPE_MPEG_PS, -1, -1, -1, NULL);
     1939                if(od) return new_demuxers_demuxer(od, od, od);
     1940                demuxer->video->id = -2;        //new linked demuxer couldn't be allocated
     1941                break;
     1942            }
     1943        }
    18251944    }
    18261945
Note: See TracChangeset for help on using the changeset viewer.