ADM_AudiocodecWMA::ADM_AudiocodecWMA(uint32_t fourcc,WAVHeader *info,uint32_t l,uint8_t *d) : ADM_Audiocodec(fourcc) { _tail=_head=0; _contextVoid=(void *)avcodec_alloc_context(); ADM_assert(_contextVoid); // Fills in some values... _context->sample_rate = info->frequency; _context->channels = info->channels; _channels=info->channels; _blockalign=_context->block_align = info->blockalign; _context->bit_rate = info->byterate*8; _context->codec_type=CODEC_TYPE_AUDIO; switch(fourcc) { case WAV_WMA: _context->codec_id = CODEC_ID_WMAV2; break; case WAV_QDM2: _context->codec_id = CODEC_ID_QDM2; break; case WAV_AMV_ADPCM: _context->codec_id = CODEC_ID_ADPCM_IMA_AMV; _blockalign=1; break; case WAV_NELLYMOSER: _context->codec_id = CODEC_ID_NELLYMOSER; _blockalign=1; break; case WAV_DTS: _context->codec_id = CODEC_ID_DTS; _blockalign = 1; break; default: ADM_assert(0); } _context->extradata=(uint8_t *)d; _context->extradata_size=(int)l; printf(" Using %ld bytes of extra header data\n",l); mixDump((uint8_t *)_context->extradata,_context->extradata_size); AVCodec *codec=avcodec_find_decoder(_context->codec_id); if(!codec) {GUI_Error_HIG(QT_TR_NOOP("Internal error"), QT_TR_NOOP("Cannot open WMA2 codec."));ADM_assert(0);} if (avcodec_open(_context, codec) < 0) { printf("\n Lavc audio decoder init failed !\n"); ADM_assert(0); } if(!_blockalign) { if(_context->block_align) _blockalign=_context->block_align; else { printf("FFWMA : no blockalign taking 378\n"); _blockalign=378; } } printf("FFwma init successful (blockalign %d)\n",info->blockalign); }
void user_data(void ) { char buffer[512]; uint16_t k=0; uint8_t c; do { c=buffer[k++]=parser->readByte(); }while(c && (k<500)); mixDump((uint8_t *)buffer,k); printf("\n"); }
/* Extract H263 width & height from header */ uint8_t extractH263Info(uint8_t *data,uint32_t dataSize,uint32_t *w,uint32_t *h) { uint32_t val; GetBitContext s; init_get_bits( &s,data, dataSize*8); mixDump(data,10); val=get_bits(&s,16); if(val) { printf("incorrect H263 header sync\n"); return 0; } val=get_bits(&s,6); if(val!=0x20) { printf("incorrect H263 header sync (2)\n"); return 0; } // skip_bits(&s,8); // timestamps in 30 fps tick skip_bits(&s,1); // Marker skip_bits(&s,1); // Id skip_bits(&s,1); // Split skip_bits(&s,1); // Document Camera indicator skip_bits(&s,1); // Full Picture Freeze Release val=get_bits(&s,3); switch(val) { case 1: *w=128; *h=96; return 1; break; case 2: *w=176; *h=144; return 1; break; case 6: case 7: printf("H263+:Todo\n"); default: printf("Invalid format\n"); return 0; break; } return 0; }
/** \fn ADM_tsAccess \param name [in] Name of the file to take audio from \param pid [in] Pid of the audio track \param append [in] Flag to auto append files (ignored for now) \param aacAdts[in] Set to true if the file is aac/adts \param myLen/myExtra[in] ExtraData if any */ ADM_tsAccess::ADM_tsAccess(const char *name,uint32_t pid,bool append,ADM_TS_MUX_TYPE muxing,int myLen,uint8_t *myExtra) { FP_TYPE fp=FP_DONT_APPEND; if(append) fp=FP_APPEND; this->pid=pid; if(!demuxer.open(name,fp)) ADM_assert(0); packet=new TS_PESpacket(pid); this->muxing=muxing; ADM_info("Creating audio track, pid=%x, muxing =%d\n",pid,muxing); if(myLen && myExtra) { extraData=new uint8_t [myLen+16]; // guards again lavcodec overread extraDataLen=myLen; memcpy(extraData,myExtra,extraDataLen); ADM_info("Creating ts audio access with %d bytes of extradata.",myLen); mixDump(extraData,extraDataLen); ADM_info("\n"); } }
ADM_AudiocodecWMA::ADM_AudiocodecWMA(uint32_t fourcc,WAVHeader *info,uint32_t l,uint8_t *d) : ADM_Audiocodec(fourcc) { _tail=_head=0; ADM_assert(fourcc==WAV_WMA || fourcc==WAV_QDM2); _contextVoid=(void *)avcodec_alloc_context(); ADM_assert(_contextVoid); // Fills in some values... _context->sample_rate = info->frequency; _context->channels = info->channels; _blockalign=_context->block_align = info->blockalign; _context->bit_rate = info->byterate*8; if(fourcc==WAV_WMA) _context->codec_id = CODEC_ID_WMAV2; else if(fourcc==WAV_QDM2) _context->codec_id = CODEC_ID_QDM2; else ADM_assert(0); _context->extradata=(void *)d; _context->extradata_size=(int)l; printf(" Using %ld bytes of extra header data\n",l); mixDump((uint8_t *)_context->extradata,_context->extradata_size); AVCodec *codec=avcodec_find_decoder(_context->codec_id); if(!codec) {GUI_Error_HIG(_("Internal error"), _("Cannot open WMA2 codec."));ADM_assert(0);} if (avcodec_open(_context, codec) < 0) { printf("\n WMA decoder init failed !\n"); ADM_assert(0); } if(!_blockalign) { if(_context->block_align) _blockalign=_context->block_align; else { printf("FFWMA : no blockalign taking 378\n"); _blockalign=378; } } printf("FFwma init successful (blockalign %d)\n",info->blockalign); }
char *flvHeader::readFlvString(void) { static uint8_t stringz[FLV_MAX_STRING+1]; int size=read16(); if(size>FLV_MAX_STRING) { int pre=FLV_MAX_STRING; read(pre,stringz); ADM_warning("String way too large :%d\n",size); mixDump(stringz,pre); stringz[0]='X'; stringz[1]='X'; stringz[2]=0; stringz[FLV_MAX_STRING]=0; Skip(size-FLV_MAX_STRING); return (char *)stringz; } read(size,stringz); stringz[size]=0; return (char *)stringz; }
/** \fn parseStbl \brief parse sample table. this is the most important function. */ uint8_t MP4Header::parseStbl(void *ztom,uint32_t trackType,uint32_t w,uint32_t h,uint32_t trackScale) { adm_atom *tom=(adm_atom *)ztom; ADMAtoms id; uint32_t container; MPsampleinfo info; memset(&info,0,sizeof(info)); printf("<<Parsing Stbl>>\n"); while(!tom->isDone()) { adm_atom son(tom); if(!ADM_mp4SearchAtomName(son.getFCC(), &id,&container)) { adm_printf(ADM_PRINT_DEBUG,"[STBL]Found atom %s unknown\n",fourCC::tostringBE(son.getFCC())); son.skipAtom(); continue; } switch(id) { case ADM_MP4_STSS: // Sync sample atom (i.e. keyframes) { son.read32(); info.nbSync=son.read32(); printf("Stss:%u\n",info.nbSync); if(info.nbSync) { info.Sync=new uint32_t[info.nbSync]; for(int i=0;i<info.nbSync;i++) { info.Sync[i]=son.read32(); } } break; } case ADM_MP4_STTS: { printf("stts:%lu\n",son.read32()); // version & flags info.nbStts=son.read32(); printf("Time stts atom found (%lu)\n",info.nbStts); printf("Using myscale %lu\n",trackScale); info.SttsN=new uint32_t[info.nbStts]; info.SttsC=new uint32_t[info.nbStts]; double dur; for(int i=0;i<info.nbStts;i++) { info.SttsN[i]=son.read32(); info.SttsC[i]=son.read32(); adm_printf(ADM_PRINT_VERY_VERBOSE,"stts: count:%u size:%u (unscaled)\n",info.SttsN[i],info.SttsC[i]); //dur*=1000.*1000.;; // us //dur/=myScale; } } break; case ADM_MP4_STSC: { son.read32(); info.nbSc=son.read32(); info.Sc=new uint32_t[info.nbSc]; info.Sn=new uint32_t[info.nbSc]; for(int j=0;j<info.nbSc;j++) { info.Sc[j]=son.read32(); info.Sn[j]=son.read32(); son.read32(); adm_printf(ADM_PRINT_VERY_VERBOSE,"\t sc %d : sc start:%u sc count: %u\n",j,info.Sc[j],info.Sn[j]); } } break; case ADM_MP4_STSZ: { uint32_t n; son.read32(); n=son.read32(); info.nbSz=son.read32(); info.SzIndentical=0; printf("%lu frames /%lu nbsz..\n",n,info.nbSz); if(n) { adm_printf(ADM_PRINT_VERY_VERBOSE,"\t\t%lu frames of the same size %lu , n=%lu\n", info.nbSz,info.SzIndentical,n); info.SzIndentical=n; info.Sz=NULL; } else { info.Sz=new uint32_t[info.nbSz]; for(int j=0;j<info.nbSz;j++) { info.Sz[j]=son.read32(); } } } break; case ADM_MP4_CTTS: // Composition time to sample { uint32_t n,i,j,k,v; printf("ctts:%lu\n",son.read32()); // version & flags n=son.read32(); if(n==1) // all the same , ignore { break; } uint32_t *values=new uint32_t [n]; uint32_t *count=new uint32_t [n]; for(i=0;i<n;i++) { count[i]=son.read32(); values[i]=son.read32(); } uint32_t sum=0; for(i=0;i<n;i++) { sum+=count[i]; } info.Ctts=new uint32_t[sum+1]; // keep a safe margin for(i=0;i<n;i++) { if(i<20) { adm_printf(ADM_PRINT_VERY_VERBOSE,"Ctts: nb: %u (%x) val:%u (%x)\n",count[i],count[i],values[i],values[i]); } for(k=0;k<count[i];k++) { info.Ctts[info.nbCtts++]=values[i]; } } delete [] values; delete [] count; if(!info.nbCtts) { delete [] info.Ctts; info.Ctts=NULL; printf("Destroying Ctts, seems invalid\n"); } ADM_assert(info.nbCtts<sum+1); printf("Found %u elements\n",info.nbCtts); } break; case ADM_MP4_STCO: { son.read32(); info.nbCo=son.read32(); printf("\t\tnbCo:%u\n",info.nbCo); info.Co=new uint32_t[info.nbCo]; for(int j=0;j< info.nbCo;j++) { info.Co[j]=son.read32(); adm_printf(ADM_PRINT_VERY_VERBOSE,"Chunk offset : %u / %u : %u\n", j,info.nbCo,info.Co[j]); } } break; case ADM_MP4_STCO64: { printf("Incomplete support for 64 bits quicktime!!\n"); son.read32(); info.nbCo=son.read32(); printf("\t\tnbCo:%u\n",info.nbCo); info.Co=new uint32_t[info.nbCo]; for(int j=0;j< info.nbCo;j++) { son.read32(); // Ignore MSB info.Co[j]=son.read32(); adm_printf(ADM_PRINT_VERY_VERBOSE,"Chunk offset : %u / %u : %lu\n", j,info.nbCo,info.Co[j]); } } break; case ADM_MP4_STSD: { son.read32(); // flags & version int nbEntries=son.read32(); int left; adm_printf(ADM_PRINT_DEBUG,"[STSD]Found %d entries\n",nbEntries); for(int i=0;i<nbEntries;i++) { int entrySize=son.read32(); int entryName=son.read32(); left=entrySize-8; if(i || (trackType==TRACK_VIDEO && _videoFound) || (trackType==TRACK_OTHER)) { son.skipBytes(left); printf("[STSD] ignoring %s, size %u\n",fourCC::tostringBE(entryName),entrySize); if(trackType==TRACK_OTHER) printf("[STSD] because track=other\n"); continue; } switch(trackType) { case TRACK_VIDEO: { uint32_t lw=0,lh=0; printf("[STSD] VIDEO %s, size %u\n",fourCC::tostringBE(entryName),entrySize); son.skipBytes(8); // reserved etc.. left-=8; son.read32(); // version/revision left-=4; printf("[STSD] vendor %s\n",fourCC::tostringBE(son.read32())); left-=4; son.skipBytes(8); // spatial qual etc.. left-=8; printf("[STSD] width :%u\n",lw=son.read16()); printf("[STSD] height :%u\n",lh=son.read16()); left-=4; son.skipBytes(8); // Resolution left-=8; printf("[STSD] datasize :%u\n",son.read32()); left-=4; printf("[STSD] FrameCount :%u\n",son.read16()); left-=4; // Codec name uint32_t u32=son.read(); if(u32>31) u32=31; printf("Codec string :%d <",u32); for(int i=0;i<u32;i++) printf("%c",son.read()); printf(">\n"); son.skipBytes(32-1-u32); left-=32; // son.read32(); left-=4; //Depth & color Id // printf("LEFT:%d\n",left); if(left>8) { // decodeVideoAtom(&son); } // #define commonPart(x) _videostream.fccHandler=_video_bih.biCompression=fourCC::get((uint8_t *)#x); _video_bih.biWidth=_mainaviheader.dwWidth=lw ; _video_bih.biHeight=_mainaviheader.dwHeight=lh; _video_bih.biCompression=_videostream.fccHandler; // switch(entryName) { case MKFCCR('m','j','p','b'): //mjpegb { commonPart(MJPB); left=0; } break; case MKFCCR('s','2','6','3'): //s263 d263 { commonPart(H263); adm_atom d263(&son); printf("Reading s253, got %s\n",fourCC::tostringBE(d263.getFCC())); left=0; } break; case MKFCCR('m','p','4','v'): //mp4v { commonPart(DIVX); adm_atom esds(&son); printf("Reading esds, got %s\n",fourCC::tostringBE(esds.getFCC())); if(esds.getFCC()==MKFCCR('e','s','d','s')) decodeEsds(&esds,TRACK_VIDEO); left=0; } break; case MKFCCR('S','V','Q','3'): {//'SVQ3': // For SVQ3, the codec needs it to begin by SVQ3 // We go back by 4 bytes to get the 4CC printf("SVQ3 atom found\n"); VDEO.extraDataSize=left+4; VDEO.extraData=new uint8_t[ VDEO.extraDataSize ]; if(!son.readPayload(VDEO.extraData+4,VDEO.extraDataSize-4 )) { GUI_Error_HIG(QT_TR_NOOP("Problem reading SVQ3 headers"), NULL); } VDEO.extraData[0]='S'; VDEO.extraData[1]='V'; VDEO.extraData[2]='Q'; VDEO.extraData[3]='3'; printf("SVQ3 Header size : %lu",_videoExtraLen); commonPart(SVQ3); left=0; } break; case MKFCCR('d','v','c',' ') : //'dvc ': case MKFCCR('d','v','c','p'): //'dvcp': commonPart(DVDS); break; case MKFCCR('c','v','i','d'): //'cvid' commonPart(cvid); break; case MKFCCR('h','2','6','3'): //'dv': commonPart(H263); break; case MKFCCR('M','J','P','G'): //'jpeg': case MKFCCR('j','p','e','g'): //'jpeg': case MKFCCR('A','V','D','J'): //'jpeg': commonPart(MJPG); break; case MKFCCR('a','v','c','1'): // avc1 { commonPart(H264); // There is a avcC atom just after // configuration data for h264 adm_atom avcc(&son); printf("Reading avcC, got %s\n",fourCC::tostringBE(avcc.getFCC())); int len,offset; VDEO.extraDataSize=avcc.getRemainingSize(); VDEO.extraData=new uint8_t [VDEO.extraDataSize]; avcc.readPayload(VDEO.extraData,VDEO.extraDataSize); printf("avcC size:%d\n",VDEO.extraDataSize); // Dump some info #define MKD8(x) VDEO.extraData[x] #define MKD16(x) ((MKD8(x)<<8)+MKD8(x+1)) #define MKD32(x) ((MKD16(x)<<16)+MKD16(x+2)) printf("avcC Revision :%x\n", MKD8(0)); printf("avcC AVCProfileIndication :%x\n", MKD8(1)); printf("avcC profile_compatibility:%x\n", MKD8(2)); printf("avcC AVCLevelIndication :%x\n", MKD8(3)); printf("avcC lengthSizeMinusOne :%x\n", MKD8(4)); printf("avcC NumSeq :%x\n", MKD8(5)); len=MKD16(6); printf("avcC sequenceParSetLen :%x ",len ); offset=8; mixDump(VDEO.extraData+offset,len); offset=8+len; printf("\navcC numOfPictureParSets :%x\n", MKD8(offset++)); len=MKD16(offset++); printf("avcC Pic len :%x\n",len); mixDump(VDEO.extraData+offset,len); left=0; } break; default: if(left>10) { adm_atom avcc(&son); printf("Reading , got %s\n",fourCC::tostringBE(avcc.getFCC())); left=0; } break; } // Entry name } break; case TRACK_AUDIO: { uint32_t channels,bpp,encoding,fq,packSize; // Put some defaults ADIO.encoding=1234; ADIO.frequency=44100; ADIO.byterate=128000>>3; ADIO.channels=2; ADIO.bitspersample=16; printf("[STSD] AUDIO <%s>, 0x%08x, size %u\n",fourCC::tostringBE(entryName),entryName,entrySize); son.skipBytes(8); // reserved etc.. left-=8; int atomVersion=son.read16(); // version left-=2; printf("[STSD]Revision :%d\n",atomVersion); son.skipBytes(2); // revision left-=2; printf("[STSD]Vendor : %s\n",fourCC::tostringBE(son.read32())); left-=4; ADIO.channels=channels=son.read16(); // Channel left-=2; printf("[STSD]Channels :%d\n",ADIO.channels); ADIO.bitspersample=bpp=son.read16(); // version/revision left-=2; printf("[STSD]Bit per sample :%d\n",bpp); encoding=son.read16(); // version/revision left-=2; printf("[STSD]Encoding :%d\n",encoding); packSize=son.read16(); // Packet Size left-=2; printf("[STSD]Packet size :%d\n",encoding); fq=ADIO.frequency=son.read16(); printf("[STSD]Fq:%u\n",fq); if(ADIO.frequency<6000) ADIO.frequency=48000; printf("[STSD]Fq :%d\n",ADIO.frequency); // Bps son.skipBytes(2); // Fixed point left-=4; if(atomVersion) { info.samplePerPacket=son.read32(); info.bytePerPacket=son.read32(); info.bytePerFrame=son.read32(); printf("[STSD] Sample per packet %u\n",info.samplePerPacket); printf("[STSD] Bytes per packet %u\n",info.bytePerPacket); printf("[STSD] Bytes per frame %u\n",info.bytePerFrame); printf("[STSD] Bytes per sample %u\n",son.read32()); left-=16; }else { info.samplePerPacket=1; info.bytePerPacket=1; info.bytePerFrame=1; } switch(atomVersion) { case 0:break; case 1: break; case 2: ADIO.frequency=44100; // FIXME ADIO.channels=son.read32(); printf("Channels :%d\n",ADIO.channels); // Channels printf("Tak(7F000) :%x\n",son.read32()); // Channels printf("Bits per channel :%d\n",son.read32()); // Vendor printf("Format specific :%x\n",son.read32()); // Vendor printf("Byte per audio packe:%x\n",son.read32()); // Vendor printf("LPCM :%x\n",son.read32()); // Vendor left-=(5*4+4+16); break; } printf("[STSD] chan:%u bpp:%u encoding:%u fq:%u (left %u)\n",channels,bpp,encoding,fq,left); #define audioCodec(x) ADIO.encoding=WAV_##x; switch(entryName) { case MKFCCR('t','w','o','s'): audioCodec(LPCM); ADIO.byterate=ADIO.frequency*ADIO.bitspersample*ADIO.channels/8; break; case MKFCCR('u','l','a','w'): audioCodec(ULAW); ADIO.byterate=ADIO.frequency; break; case MKFCCR('s','o','w','t'): audioCodec(PCM); ADIO.byterate=ADIO.frequency*ADIO.bitspersample*ADIO.channels/8; break; case MKFCCR('.','m','p','3'): //.mp3 audioCodec(MP3); ADIO.byterate=128000>>3; break; case MKFCCR('r','a','w',' '): audioCodec(8BITS_UNSIGNED); ADIO.byterate=ADIO.frequency*ADIO.channels; break; case MKFCCR('s','a','m','r'): { audioCodec(AMRNB); ADIO.frequency=8000; ADIO.channels=1; ADIO.bitspersample=16; ADIO.byterate=12000/8; if(left>10) { adm_atom amr(&son); printf("Reading wave, got %s\n",fourCC::tostringBE(amr.getFCC())); left=0; } } break; case MKFCCR('Q','D','M','2'): { uint32_t sz; audioCodec(QDM2); sz=son.getRemainingSize(); _tracks[1+nbAudioTrack].extraDataSize=sz; _tracks[1+nbAudioTrack].extraData=new uint8_t[sz]; son.readPayload(_tracks[1+nbAudioTrack].extraData,sz); left=0; } break; case MKFCCR('m','s',0,0x55): // why 55 ??? case MKFCCR('m','p','4','a'): { audioCodec(AAC); if(left>10) { adm_atom wave(&son); printf("Reading wave, got %s\n",fourCC::tostringBE(wave.getFCC())); if(MKFCCR('w','a','v','e')==wave.getFCC()) { // mp4a // wave // frma // mp4a // esds while(!wave.isDone()) { adm_atom item(&wave); printf("parsing wave, got %s,0x%x\n",fourCC::tostringBE(item.getFCC()), item.getFCC()); switch(item.getFCC()) { case MKFCCR('f','r','m','a'): { uint32_t codecid=item.read32(); printf("frma Codec Id :%s\n",fourCC::tostringBE(codecid)); } break; case MKFCCR('m','s',0,0x55): { // We have a waveformat here printf("[STSD]Found MS audio header:\n"); ADIO.encoding=ADM_swap16(item.read16()); ADIO.channels=ADM_swap16(item.read16()); ADIO.frequency=ADM_swap32(item.read32()); ADIO.byterate=ADM_swap32(item.read32()); ADIO.blockalign=ADM_swap16(item.read16()); ADIO.bitspersample=ADM_swap16(item.read16()); printWavHeader(&(ADIO)); } break; case MKFCCR('m','p','4','a'): break; case MKFCCR('e','s','d','s'): { decodeEsds(&item,TRACK_AUDIO); goto foundit; // FIXME!!! } break; default: break; } item.skipAtom(); } // Wave iddone left=0; } // if ==wave else { if(wave.getFCC()==MKFCCR('e','s','d','s')) { decodeEsds(&wave,TRACK_AUDIO); goto foundit; // FIXME!!! } else { printf("UNHANDLED ATOM : %s\n",fourCC::tostringBE(wave.getFCC())); } } } // if left > 10 foundit: // HACK FIXME left=0; } break; // mp4a } } break; default: ADM_assert(0); } son.skipBytes(left); } } break; default: printf("[STBL]Skipping atom %s\n",fourCC::tostringBE(son.getFCC())); } son.skipAtom(); } uint8_t r=0; uint32_t nbo=0; switch(trackType) { case TRACK_VIDEO: { if(_tracks[0].index) { printf("Already got a video track\n"); return 1; } r=indexify(&(_tracks[0]),trackScale,&info,0,&nbo); _videostream.dwLength= _mainaviheader.dwTotalFrames=_tracks[0].nbIndex; // update fps float f=_videostream.dwLength; if(_movieDuration) f=1000000.*f/_movieDuration; else f=25000; _videostream.dwRate=(uint32_t)floor(f); _mainaviheader.dwMicroSecPerFrame=ADM_UsecFromFps1000(_videostream.dwRate); // if we have a sync atom ??? if(info.nbSync) { // Mark keyframes for(int i=0;i<info.nbSync;i++) { int sync=info.Sync[i]; if(sync) sync--; _tracks[0].index[sync].intra=AVI_KEY_FRAME; } } else { // All frames are kf for(int i=0;i<_tracks[0].nbIndex;i++) { _tracks[0].index[i].intra=AVI_KEY_FRAME; } } // Now do the CTTS thing if(info.Ctts) { updateCtts(&info); } VDEO.index[0].intra=AVI_KEY_FRAME; } break; case TRACK_AUDIO: printf("Cur audio track :%u\n",nbAudioTrack); if(info.SzIndentical ==1 && (ADIO.encoding==WAV_LPCM || ADIO.encoding==WAV_PCM )) { printf("Overriding size %lu -> %lu\n", info.SzIndentical,info.SzIndentical*2*ADIO.channels); info.SzIndentical=info.SzIndentical*2*ADIO.channels; } r=indexify(&(_tracks[1+nbAudioTrack]),trackScale,&info,1,&nbo); printf("Indexed audio, nb blocks:%u\n",nbo); if(r) { nbo=_tracks[1+nbAudioTrack].nbIndex; if(nbo) _tracks[1+nbAudioTrack].nbIndex=nbo; else _tracks[1+nbAudioTrack].nbIndex=info.nbSz; printf("Indexed audio, nb blocks:%u (final)\n",_tracks[1+nbAudioTrack].nbIndex); _tracks[1+nbAudioTrack].scale=trackScale; nbAudioTrack++; } break; case TRACK_OTHER: r=1; break; } return r; }
/** \fn analyzeOneTrack \brief Grab info about the track (it is a recursive function !) */ uint8_t mkvHeader::analyzeOneTrack(void *head,uint32_t headlen) { entryDesc entry; memset(&entry,0,sizeof(entry)); /* Set some defaults value */ entry.chan=2; entryWalk( (ADM_ebml_file *)head,headlen,&entry); entry.dump(); if(entry.trackType==1 && !_isvideopresent) { _isvideopresent=1; if(entry.defaultDuration) { _tracks[0]._defaultFrameDuration=entry.defaultDuration; double inv=entry.defaultDuration; // in us inv=1/inv; inv*=1000.; inv*=1000.; inv*=1000.; _videostream.dwScale=1000; _videostream.dwRate=(uint32_t)inv; }else { printf("[MKV] No duration, assuming 25 fps\n"); _videostream.dwScale=1000; _videostream.dwRate=25000; } _mainaviheader.dwMicroSecPerFrame=(uint32_t)floor(50);; _videostream.fccType=fourCC::get((uint8_t *)"vids"); _video_bih.biBitCount=24; _videostream.dwInitialFrames= 0; _videostream.dwStart= 0; _video_bih.biWidth=_mainaviheader.dwWidth=entry.w; _video_bih.biHeight=_mainaviheader.dwHeight=entry.h; _videostream.fccHandler=_video_bih.biCompression=entry.fcc; // if it is vfw... if(fourCC::check(entry.fcc,(uint8_t *)"VFWX") && entry.extraData && entry.extraDataLen>=sizeof(ADM_BITMAPINFOHEADER)) { printf("VFW compatibility mode\n"); memcpy(& _video_bih,entry.extraData,sizeof(ADM_BITMAPINFOHEADER)); delete [] _tracks[0].extraData; if(entry.extraDataLen>sizeof(ADM_BITMAPINFOHEADER)) { int l=entry.extraDataLen-sizeof(ADM_BITMAPINFOHEADER); _tracks[0].extraData=new uint8_t[l]; _tracks[0].extraDataLen=l; memcpy(_tracks[0].extraData,entry.extraData +sizeof(ADM_BITMAPINFOHEADER),l); printf("VFW Header+%d bytes of extradata\n",l); mixDump(_tracks[0].extraData,l); printf("\n"); } delete [] entry.extraData; entry.extraData=NULL; entry.extraDataLen=0; _videostream.fccHandler=_video_bih.biCompression; _mainaviheader.dwWidth= _video_bih.biWidth; _mainaviheader.dwHeight= _video_bih.biHeight; } else // not VFWX { _tracks[0].extraData=entry.extraData; _tracks[0].extraDataLen=entry.extraDataLen; } _tracks[0].streamIndex=entry.trackNo; uint32_t hdr=entry.headerRepeatSize; if(hdr) { _tracks[0].headerRepeatSize=entry.headerRepeatSize; memcpy(_tracks[0].headerRepeat,entry.headerRepeat,hdr); printf("video has %d bytes of repeated headers\n",hdr); } return 1; } if(entry.trackType==2 && _nbAudioTrack<ADM_MKV_MAX_TRACKS) { uint32_t streamIndex; mkvTrak *t=&(_tracks[1+_nbAudioTrack]); t->wavHeader.encoding=entry.fcc; t->wavHeader.channels=entry.chan; t->wavHeader.frequency=entry.fq; t->wavHeader.bitspersample=16; t->wavHeader.byterate=(128000)>>3; //FIXME t->streamIndex=entry.trackNo; t->extraData=entry.extraData; t->extraDataLen=entry.extraDataLen; if(entry.defaultDuration) t->_defaultFrameDuration=entry.defaultDuration; else t->_defaultFrameDuration=0; uint32_t hdr=entry.headerRepeatSize; if(hdr) { t->headerRepeatSize=entry.headerRepeatSize; memcpy(t->headerRepeat,entry.headerRepeat,hdr); } _nbAudioTrack++; return 1; }
uint8_t dmxHeader::open(char *name) { FILE *file; uint32_t w=720,h=576,fps=0; uint8_t type,progressif; char realname[1024]; uint32_t dummy; uint32_t vPid,vTsId; char string[MAX_LINE+1]; //,str[1024];; uint8_t interlac=0; int multi; printf("\n opening d2v file : %s\n",name); file=fopen(name,"rt"); if(!file) { printf("\n Error !!\n"); return 0; } fgets(string,MAX_LINE,file); // File header if(strncmp(string,"ADMX",4)) { fclose(file); printf("This is not a mpeg index G2\n"); return 0; } fgets(string,MAX_LINE,file); sscanf(string,"Type : %c\n",&type); // ES for now fgets(string,MAX_LINE,file); // sscanf(string,"File : %s\n",realname); char *start; start=strstr(string,":"); ADM_assert(start); strcpy(realname,start+2); int l=strlen(realname)-1; while(l&&(realname[l]==0x0a || realname[l]==0x0d)) { realname[l]=0; l--; } fgets (string, MAX_LINE, file); sscanf(string,"Append : %d\n",&multi); fgets(string,MAX_LINE,file); sscanf(string,"Image : %c\n",&progressif); // Progressive if(progressif=='I') _fieldEncoded=1; fgets(string,MAX_LINE,file); sscanf(string,"Picture : %u x %u %u fps\n",&w,&h,&fps); // width... fgets(string,MAX_LINE,file); sscanf(string,"Nb Gop : %u \n",&_nbGop); // width... fgets(string,MAX_LINE,file); sscanf(string,"Nb Images: %u \n",&_nbFrames); // width... fgets(string,MAX_LINE,file); //fscanf(string,"Nb Audio : %u\n",0); fgets(string,MAX_LINE,file); //fprintf(out,"Main aud : %u\n",preferedAudio); fgets(string,MAX_LINE,file); sscanf(string,"Streams : V%X:%X \n",&vTsId,&vPid); printf("For file :%s\n",realname); printf("Pic :%dx%d, %d fps\n",w,h,fps); printf("#Gop :%lu\n",_nbGop); printf("#Img :%lu\n",_nbFrames); switch(type) { case 'M': { MPEG_TRACK track; track.pid=vTsId; track.pes=vPid; demuxer=new dmx_demuxerMSDVR(1,&track,0); break; } case 'T' : { MPEG_TRACK track; track.pid=vTsId; track.pes=vPid; demuxer=new dmx_demuxerTS(1,&track,0); break; } case 'P': { MPEG_TRACK track; track.pid=0; track.pes=vPid; demuxer=new dmx_demuxerPS(1,&track,multi); break; } case 'E': demuxer=new dmx_demuxerES(); break; default: ADM_assert(0); } if(!demuxer->open(realname)) { printf("\n cannot open mpeg >%s<\n",realname); delete demuxer; demuxer=NULL; fclose(file); return 0; } _index=new dmxIndex[_nbFrames+1]; if(!_index) { GUI_Error_HIG(_("Out of memory"), NULL); ADM_assert(0); } memset(_index,0,_nbFrames*sizeof(dmxIndex)); // -------------- Read the file (video)--------------------- uint32_t read=0; uint32_t currentImage=0; uint32_t gop,imageStart,imageNb; uint64_t abs,rel; uint8_t imgtype; uint32_t imgsize; uint64_t imgrel,imgabs; char *str,*needle; DIA_working *work=new DIA_working("Opening mpeg.."); while(read<_nbGop) { if(!fgets(string,MAX_LINE,file)) break; if(string[0]!='V') continue; //printf("%s\n",string); // # NGop NImg nbImg Pos rel type:size type:size sscanf(string,"V %u %u %u ",&gop,&imageStart,&imageNb); ADM_assert(read==gop); if(currentImage!=imageStart) { printf("At gop :%u read:%u, expected image %u, got %u,imagenb:%u\n",gop,read,currentImage,imageStart,imageNb); printf("String :%s\n",string); ADM_assert(0); } // now split the image needle=strstr(string,":"); ADM_assert(needle); needle--; // for(uint32_t i=currentImage;i<currentImage+imageNb;i++) { str=strstr(needle,":"); if(!str) { printf("****** Error reading index, index damaged ?****\n"); printf("Gop: %d/%d\n",read,_nbGop); printf("Img: %d/%d/%d\n",i,i-currentImage,imageNb); printf("Str:%s\n",string); printf("****** Error reading index, index damaged ?****\n"); ADM_assert(0); } str--; #ifdef CYG_MANGLING sscanf(str,"%c:%I64x,%I64x,%x",&imgtype,&imgabs,&imgrel,&imgsize); #else sscanf(str,"%c:%llx,%llx,%x",&imgtype,&imgabs,&imgrel,&imgsize); #endif if(i>=_nbFrames) { printf("Max frame exceeded :%d/%d\n",i,_nbFrames); ADM_assert(i<_nbFrames); } _index[i].type=imgtype; _index[i].size=imgsize; _index[i].absolute=imgabs; _index[i].relative=imgrel; str[1]=' '; // remove : } currentImage+=imageNb; read++; work->update( read,_nbGop) ; } delete work; fclose(file); if(!_nbFrames) { printf("No image!\n"); return 0; } // Drop the last P/B frames as we won't be able to decode them // (last frame must be an I frame for decodeGop to work) uint32_t dropped=0; for(uint32_t y=_nbFrames-1;y>0;y--) { if(_index[y].type!='B') break; _nbFrames--; dropped++; } printf("Dropping %d last B/P frames\n",dropped); printf(" Creating start sequence (%llu)..\n",_index[0].absolute); // uint32_t scancode=0; uint32_t count=0,found=0; uint32_t firstPic=_index[0].size; uint8_t *tmp=new uint8_t[firstPic]; demuxer->setPos(_index[0].absolute, _index[0].relative); demuxer->read(tmp,firstPic); _extraDataLen=0; _extraData=NULL; // lookup up gop start while(count<firstPic) { scancode<<=8; scancode+=tmp[count]; count++; if(scancode==0x000001b8 || scancode==0x00000100) { found=1; break; } } if(found && count>4) { _extraDataLen=count-4; _extraData=new uint8_t[_extraDataLen]; memcpy(_extraData,tmp,_extraDataLen); mixDump(tmp,50); printf("\n"); printf("Image :%d, seqLen : %u seq %x %x %x %x\n", firstPic, _extraDataLen, _extraData[0], _extraData[1], _extraData[2], _extraData[3]); } else { printf("Mmm cound not find a gop start.....\n"); } delete [] tmp; demuxer->setPos(_index[0].absolute, _index[0].relative); if(_fieldEncoded) { printf("This is field encoded...\n"); mergeFields(); } _isaudiopresent=0; _isvideopresent=1; _videostream.dwScale=1000; _videostream.dwRate=fps; _mainaviheader.dwMicroSecPerFrame=(uint32_t)floor(50);; _videostream.fccType=fourCC::get((uint8_t *)"vids"); _video_bih.biBitCount=24; _videostream.fccHandler=_video_bih.biCompression=fourCC::get((uint8_t *)"MPEG");; _videostream.dwInitialFrames= 0; _videostream.dwStart= 0; _video_bih.biWidth=_mainaviheader.dwWidth=w ; _video_bih.biHeight=_mainaviheader.dwHeight=h; _lastFrame=0xffffffff; _videostream.dwLength= _mainaviheader.dwTotalFrames=_nbFrames; // Dump(); // switch DTS->PTS if(!renumber()) { GUI_Error_HIG(_("MPEG renumbering error"), NULL); return 0; } //Dump(); if(type=='P' || type=='T' || type=='M') { // We have potentially some audio // Try to get it dmxAudioStream *tmp; tmp=new dmxAudioStream; if(!tmp->open(name)) delete tmp; else { _audioStream=tmp; } } printf("Mpeg index file successfully read\n"); return 1; }
/** \fn analyzeOneTrack \brief Grab info about the track (it is a recursive function !) */ uint8_t mkvHeader::analyzeOneTrack(void *head,uint32_t headlen) { entryDesc entry; memset(&entry,0,sizeof(entry)); /* Set some defaults value */ entry.chan=1; entryWalk( (ADM_ebml_file *)head,headlen,&entry); entry.dump(); //***************** First video track ***************** if(entry.trackType==1 && !_isvideopresent) { _isvideopresent=1; if(entry.defaultDuration) { _tracks[0]._defaultFrameDuration=entry.defaultDuration; double inv=entry.defaultDuration; // in us inv=1/inv; inv*=1000.; inv*=1000.; inv*=1000.; _videostream.dwScale=1000; _videostream.dwRate=(uint32_t)inv; }else { printf("[MKV] No duration, assuming 25 fps\n"); _videostream.dwScale=1000; _videostream.dwRate=25000; _tracks[0]._defaultFrameDuration=25000; } _mainaviheader.dwMicroSecPerFrame=(uint32_t)floor(50);; _videostream.fccType=fourCC::get((uint8_t *)"vids"); _video_bih.biBitCount=24; _videostream.dwInitialFrames= 0; _videostream.dwStart= 0; _video_bih.biWidth=_mainaviheader.dwWidth=entry.w; _video_bih.biHeight=_mainaviheader.dwHeight=entry.h; _videostream.fccHandler=_video_bih.biCompression=entry.fcc; // if it is vfw... if(fourCC::check(entry.fcc,(uint8_t *)"VFWX") && entry.extraData && entry.extraDataLen>=sizeof(ADM_BITMAPINFOHEADER)) { ADM_info("VFW compatibility header, data=%d bytes\n",(int)entry.extraDataLen); memcpy(& _video_bih,entry.extraData,sizeof(ADM_BITMAPINFOHEADER)); _videostream.fccHandler=_video_bih.biCompression; _mainaviheader.dwWidth= _video_bih.biWidth; _mainaviheader.dwHeight= _video_bih.biHeight; if(entry.extraDataLen>sizeof(ADM_BITMAPINFOHEADER)) { int l=entry.extraDataLen-sizeof(ADM_BITMAPINFOHEADER); _tracks[0].extraData=new uint8_t[l]; _tracks[0].extraDataLen=l; memcpy(_tracks[0].extraData,entry.extraData +sizeof(ADM_BITMAPINFOHEADER),l); ADM_info("VFW Header+%d bytes of extradata\n",l); mixDump(_tracks[0].extraData,l); printf("\n"); } delete [] entry.extraData; entry.extraData=NULL; entry.extraDataLen=0; } else { _tracks[0].extraData=entry.extraData; _tracks[0].extraDataLen=entry.extraDataLen; } _tracks[0].streamIndex=entry.trackNo; uint32_t hdr=entry.headerRepeatSize; if(hdr) { _tracks[0].headerRepeatSize=entry.headerRepeatSize; memcpy(_tracks[0].headerRepeat,entry.headerRepeat,hdr); ADM_info("video has %d bytes of repeated headers\n",hdr); } return 1; } //***************** Audio tracks ***************** if(entry.trackType==2 && _nbAudioTrack<ADM_MKV_MAX_TRACKS) { uint32_t streamIndex; mkvTrak *t=&(_tracks[1+_nbAudioTrack]); // MS/ACM : ACMX if(0x100001==entry.fcc) { int l=entry.extraDataLen; int wavSize=sizeof(WAVHeader); ADM_info("Found ACM compatibility header (%d / %d)\n",l,wavSize); if(l>=wavSize) // we need at least a wavheader { mixDump(entry.extraData,l); printf("\n"); memcpy(&(t->wavHeader),entry.extraData,wavSize); ADM_info("Encoding : %d\n",t->wavHeader.encoding); int x=l-wavSize; if(x>0) // If we have more than a wavheader, it is extradata { t->extraData=new uint8_t[x]; t->extraDataLen=x; memcpy(t->extraData,entry.extraData+wavSize,x); } delete [] entry.extraData; t->streamIndex=entry.trackNo; if(entry.defaultDuration) t->_defaultFrameDuration=entry.defaultDuration; else t->_defaultFrameDuration=0; // In ACM mode we should not have the stripped header stuff.. _nbAudioTrack++; return 1; } } t->wavHeader.encoding=entry.fcc; t->wavHeader.channels=entry.chan; t->wavHeader.frequency=entry.fq; t->wavHeader.bitspersample=16; t->wavHeader.byterate=(128000)>>3; //FIXME t->streamIndex=entry.trackNo; t->extraData=entry.extraData; t->extraDataLen=entry.extraDataLen; if(entry.defaultDuration) t->_defaultFrameDuration=entry.defaultDuration; else t->_defaultFrameDuration=0; uint32_t hdr=entry.headerRepeatSize; if(hdr) { t->headerRepeatSize=entry.headerRepeatSize; memcpy(t->headerRepeat,entry.headerRepeat,hdr); } _nbAudioTrack++; return 1; }
void OpenDMLHeader::Dump( void ) { #define X_DUMP(x) printf(#x":\t\t:%ld\n",_mainaviheader.x); X_DUMP(dwStreams); X_DUMP(dwMicroSecPerFrame) ; X_DUMP(dwMaxBytesPerSec); X_DUMP(dwPaddingGranularity); X_DUMP(dwFlags); X_DUMP(dwTotalFrames); X_DUMP(dwInitialFrames); X_DUMP(dwWidth); X_DUMP(dwHeight); printf("\n"); #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%ld",_videostream.x); printf( "video stream attached:\n" ); printf( "______________________\n" ); printf(" Extra Data : %ld",_videoExtraLen); if(_videoExtraLen) { mixDump( _videoExtraData, _videoExtraLen); } printf("\n fccType :"); fourCC::print(_videostream.fccType); printf("\n fccHandler :"); fourCC::print(_videostream.fccHandler); X_DUMP(dwFlags); X_DUMP(dwInitialFrames); X_DUMP(dwRate); X_DUMP(dwStart); X_DUMP(dwSampleSize); X_DUMP(dwScale); X_DUMP(dwLength); X_DUMP(dwQuality); X_DUMP(dwSampleSize); printf("\n"); #undef X_DUMP #define X_DUMP(x) printf(#x":\t\t:%ld\n",(long int)_video_bih.x); X_DUMP( biSize); X_DUMP( biWidth); X_DUMP( biHeight); X_DUMP( biBitCount); X_DUMP( biCompression);fourCC::print(_video_bih.biCompression);printf("\n"); X_DUMP( biSizeImage); X_DUMP( biXPelsPerMeter); X_DUMP( biYPelsPerMeter); X_DUMP( biClrUsed); /***************************************************************** Dump infos about all audio tracks found ******************************************************************/ for(int i=0;i<_nbAudioTracks;i++) { #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%ld",_audioTracks[i].avistream->x); printf( "\naudio stream attached:\n" ); printf( "______________________\n" ); printf("\n fccType :"); fourCC::print(_audioTracks[i].avistream->fccType); printf("\n fccHandler :"); fourCC::print(_audioTracks[i].avistream->fccHandler); printf("\n fccHandler :0x%lx", _audioTracks[i].avistream->fccHandler); X_DUMP(dwFlags); X_DUMP(dwInitialFrames); X_DUMP(dwRate); X_DUMP(dwScale); X_DUMP(dwStart); X_DUMP(dwLength); X_DUMP(dwSuggestedBufferSize); X_DUMP(dwQuality); X_DUMP(dwSampleSize); #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%lu",_audioTracks[i].wavHeader->x); X_DUMP(encoding); X_DUMP(channels); /* 1 = mono, 2 = stereo */ X_DUMP(frequency); /* One of 11025, 22050, or 44100 Hz */ X_DUMP(byterate); /* Average bytes per second */ X_DUMP(blockalign); /* Bytes per sample block */ X_DUMP(bitspersample); /* One of 8, 12, 16, or 4 for ADPCM */ printf(" Extra Data : %ld\n",_audioTracks[i].extraDataLen); if(_audioTracks[i].extraDataLen) { mixDump( _audioTracks[i].extraData, _audioTracks[i].extraDataLen); } printf("\n"); } }
void mixDump_c(uint8_t * ptr, uint32_t len) { mixDump(ptr,len); }
ADM_AudiocoderLavcodec::ADM_AudiocoderLavcodec(uint32_t fourcc,WAVHeader *info,uint32_t l,uint8_t *d) : ADM_Audiocodec(fourcc,*info) { ADM_info(" [ADM_AD_LAV] Using decoder for type 0x%x\n",info->encoding); ADM_info(" [ADM_AD_LAV] #of channels %d\n",info->channels); _tail=_head=0; channels=info->channels; _blockalign=0; _frame=av_frame_alloc(); AVCodecID codecID = AV_CODEC_ID_NONE; outputFrequency=info->frequency; switch(fourcc) { case WAV_WMAPRO: codecID = AV_CODEC_ID_WMAPRO; break; case WAV_WMA: codecID = AV_CODEC_ID_WMAV2; break; case WAV_QDM2: codecID = AV_CODEC_ID_QDM2; break; case WAV_AMV_ADPCM: codecID = AV_CODEC_ID_ADPCM_IMA_AMV; _blockalign=1; break; case WAV_NELLYMOSER: codecID = AV_CODEC_ID_NELLYMOSER; _blockalign=1; break; case WAV_DTS: codecID = AV_CODEC_ID_DTS; _blockalign = 1; break; case WAV_FLAC: codecID = AV_CODEC_ID_FLAC; _blockalign = 1; break; case WAV_MP3: codecID = AV_CODEC_ID_MP3; _blockalign = 1; break; case WAV_MP2: codecID = AV_CODEC_ID_MP2; _blockalign = 1; break; case WAV_AC3: codecID = AV_CODEC_ID_AC3; _blockalign = 1; break; case WAV_EAC3: codecID = AV_CODEC_ID_EAC3; _blockalign = 1; break; case WAV_OGG_VORBIS: codecID = AV_CODEC_ID_VORBIS; _blockalign = 1; break; case WAV_AAC: case 0x706D: codecID = AV_CODEC_ID_AAC; _blockalign = 1; break; default: ADM_assert(0); } AVCodec *codec=avcodec_find_decoder(codecID); if(!codec) {ADM_assert(0);} _context=avcodec_alloc_context3(codec); ADM_assert(_context); // Fills in some values... _context->codec_type=AVMEDIA_TYPE_AUDIO; _context->sample_rate = info->frequency; _context->channels = info->channels; _context->block_align = info->blockalign; _context->bit_rate = info->byterate*8; _context->sample_fmt=AV_SAMPLE_FMT_FLT; _context->request_sample_fmt=AV_SAMPLE_FMT_FLT; if(fourcc==WAV_OGG_VORBIS) { // Need to translate from adm to xiph int xiphLen=(int)l+(l/255)+4+5; uint8_t *xiph=new uint8_t[xiphLen]; xiphLen=ADMXiph::admExtraData2xiph(l,d,xiph); _context->extradata=xiph; _context->extradata_size=xiphLen; }else { _context->extradata=(uint8_t *)d; _context->extradata_size=(int)l; } if (!_blockalign) { _blockalign = _context->block_align; } ADM_info("[ADM_AD_LAV] Using %d bytes of extra header data, %d channels\n", _context->extradata_size,_context->channels); mixDump((uint8_t *)_context->extradata,_context->extradata_size); ADM_info("\n"); if (avcodec_open2(_context, codec, NULL) < 0) { ADM_warning("[audioCodec] Cannot use float, retrying with floatp \n"); _context->sample_fmt=AV_SAMPLE_FMT_FLTP; _context->request_sample_fmt=AV_SAMPLE_FMT_FLTP; if (avcodec_open2(_context, codec, NULL) < 0) { ADM_warning("[audioCodec] floatp failed also. Crashing.. \n"); ADM_assert(0); } ADM_info("Decoder created using floatp..\n"); } switch(_context->sample_fmt) { case AV_SAMPLE_FMT_FLT: outputFlavor=asFloat; ADM_info("Decoder created using float..\n"); break; case AV_SAMPLE_FMT_FLTP: outputFlavor=asFloatPlanar; ADM_info("Decoder created using float planar...\n"); break; case AV_SAMPLE_FMT_S32P: outputFlavor=asS32Planar; ADM_info("Decoder created using s32 planar...\n"); break; case AV_SAMPLE_FMT_S32: outputFlavor=asS32; ADM_info("Decoder created using s32 ...\n"); break; default: ADM_info("Decoder created using ??? %d...\n",_context->sample_fmt); ADM_assert(0); break; } if(!_blockalign) { if(_context->block_align) { _blockalign=_context->block_align; } else { ADM_info("[ADM_ad_lav] : no blockalign taking 378\n"); _blockalign=378; } } ADM_info("[ADM_ad_lav] init successful (blockalign %d), channels=%d\n",info->blockalign,_context->channels); if(_context->sample_rate!=outputFrequency) { ADM_warning("Output frequency does not match input frequency (SBR ?) : %d / %d\n", _context->sample_rate,outputFrequency); outputFrequency=_context->sample_rate; } }
/* Extract width & height from vol header passed as arg */ uint8_t extractMpeg4Info(uint8_t *data,uint32_t dataSize,uint32_t *w,uint32_t *h,uint32_t *time_inc) { // Search startcode uint8_t b; uint32_t idx=0; uint32_t mw,mh; uint32_t timeVal; //mixDump(data,dataSize); //printf("\n"); while(1) { uint32_t startcode=0xffffffff; while(dataSize>2) { startcode=(startcode<<8)+data[idx]; idx++; dataSize--; if((startcode&0xffffff)==1) break; } if(dataSize>2) { //printf("Startcodec:%x\n",data[idx]); if((data[idx]&0xF0)==0x20) //VOL start { dataSize--; idx++; #if 0 printf("VOL Header:\n"); if(dataSize<16) { mixDump(data+idx,dataSize); printf("\n"); } else { mixDump(data+idx,16); printf("\n"); } #endif // Here we go ! GetBitContext s; init_get_bits( &s,data+idx, dataSize*8); // skip_bits1(&s); // Random access skip_bits(&s,8); // Obj type indication if(get_bits(&s,1)) // VO od { skip_bits(&s,4); // Ver skip_bits(&s,3); // Priority } if(get_bits(&s,4)==15) // custom A/R { skip_bits(&s,8); skip_bits(&s,8); } if(get_bits(&s,1)) // Vol control param { skip_bits(&s,2); //Chroma skip_bits(&s,1); // Low delay if(get_bits(&s,1)) // VBV Info { skip_bits(&s,16); skip_bits(&s,16); skip_bits(&s,16); skip_bits(&s,15); skip_bits(&s,16); } } skip_bits(&s,2); // Shape skip_bits(&s,1); // Marker timeVal=get_bits(&s,16); // Time increment *time_inc = av_log2(timeVal - 1) + 1; if (*time_inc < 1) *time_inc = 1; skip_bits(&s,1); // Marker if(get_bits(&s,1)) // Fixed vop rate, compute how much bits needed { get_bits(&s, *time_inc); } skip_bits(&s,1); // Marker mw=get_bits(&s,13); skip_bits(&s,1); // Marker mh=get_bits(&s,13); // /Here we go //printf("%d x %d \n",mw,mh); *h=mh; *w=mw; return 1;; // Free get bits ? // WTF ? } continue; } else { printf("No more startcode\n"); // Free get bits ? return 0; } } return 0; }
/** \fn addFile \brief Load or append a file. The file type is determined automatically and the ad-hoc video decoder is spawned @param name: filename @param mode: 0 open, 1 append @param forcedType : if !=Unknown_FileType, it enables to force the file type @return 1 on success, 0 on failure */ uint8_t ADM_Composer::addFile (const char *name, uint8_t mode,fileType forcedType) { uint8_t ret = 0; aviInfo info; WAVHeader * _wavinfo; // aviHeader * tmp; fileType type = forcedType; UNUSED_ARG(mode); _haveMarkers=0; // by default no markers are present if (_nb_video == (max_videos - 1)) { max_videos += MAX_VIDEO; printf("extending max_videos: %i\n", max_videos); _VIDEOS *vid = new _VIDEOS[max_videos]; memset(vid, 0, sizeof(_VIDEOS) * max_videos); memcpy(vid, _videos, sizeof(_VIDEOS) * (max_videos - MAX_VIDEO)); delete _videos; _videos = vid; } if (_nb_segment == max_seg - 1) extendSegmentBuffer(); ADM_assert (_nb_segment < max_seg); ADM_assert (_nb_video < max_videos); // Autodetect file type ? if(Unknown_FileType==type) { if (!identify (name, &type)) return 0; } #define OPEN_AS(x,y) case x:\ _videos[_nb_video]._aviheader=new y; \ ret = _videos[_nb_video]._aviheader->open(name); \ break; switch (type) { case VCodec_FileType: loadVideoCodecConf(name); return ADM_IGN; // we do it but it wil fail, no problem with that break; OPEN_AS (Mp4_FileType, mp4Header); OPEN_AS (H263_FileType, h263Header); case ASF_FileType: _videos[_nb_video]._aviheader=new asfHeader; ret = _videos[_nb_video]._aviheader->open(name); if(!ret) { delete _videos[_nb_video]._aviheader; printf("Trying mpeg\n"); goto thisIsMpeg; } break; OPEN_AS (NewMpeg_FileType,dmxHeader); // For AVI we first try top open it as openDML case AVI_FileType: _videos[_nb_video]._aviheader=new OpenDMLHeader; ret = _videos[_nb_video]._aviheader->open(name); break; case Nuppel_FileType: { // look if the idx exists char *tmpname = (char*)ADM_alloc(strlen(name)+strlen(".idx")+1); ADM_assert(tmpname); sprintf(tmpname,"%s.idx",name); if(addFile(tmpname)) { return 1; // Memleak ? } ADM_dealloc(tmpname); // open .nuv file _videos[_nb_video]._aviheader=new nuvHeader; ret = _videos[_nb_video]._aviheader->open(name); // we store the native .nuv file in the edl // the next load of the edl will open .idx instead break; } OPEN_AS (BMP_FileType, picHeader); OPEN_AS (Matroska_FileType, mkvHeader); OPEN_AS (FLV_FileType, flvHeader); OPEN_AS (AvsProxy_FileType, avsHeader); OPEN_AS (_3GPP_FileType, MP4Header); OPEN_AS (Ogg_FileType, oggHeader); OPEN_AS (AMV_FileType, amvHeader); case Mpeg_FileType: thisIsMpeg: // look if the idx exists char tmpname[256]; ADM_assert(strlen(name)+5<256); strcpy(tmpname,name); strcat(tmpname,".idx"); if(ADM_fileExist(tmpname)) { return addFile(tmpname); } /* check for "Read-only file system" */ { int fd = ADM_open(tmpname,O_CREAT|O_EXCL|O_WRONLY,S_IRUSR|S_IWUSR); if( fd >= 0 ) { close(fd); unlink(tmpname); printf("Filesystem is writable\n"); }else if( errno == EROFS ){ char *tmpdir = getenv("TMPDIR"); #ifdef __WIN32 printf("Filesystem is not writable, looking for somewhere else\n"); if( !tmpdir ) tmpdir = "c:"; snprintf(tmpname,256,"%s%s.idx",tmpdir,strrchr(name,'\\')); #else if( !tmpdir ) tmpdir = "/tmp"; snprintf(tmpname,256,"%s%s.idx",tmpdir,strrchr(name,'/')); #endif tmpname[255] = 0; printf("Storing index in %s\n",tmpname); if(ADM_fileExist(tmpname)) { printf("Index present, loading it\n"); return addFile(tmpname); } } } if(tryIndexing(name,tmpname)) { return addFile (tmpname); } return 0; break; case WorkBench_FileType: return loadWorbench(name); #if 0 case Script_FileType: return parseScript(name); #endif case ECMAScript_FileType: printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n"); printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n"); printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n"); return 0; default: if (type == Unknown_FileType) { printf ("\n not identified ...\n"); } else GUI_Error_HIG(QT_TR_NOOP("File type identified but no loader support detected..."), QT_TR_NOOP("May be related to an old index file.")); return 0; } // check opening was successful if (ret == 0) { char str[512+1]; snprintf(str,512,QT_TR_NOOP("Attempt to open %s failed!"), name); str[512] = '\0'; GUI_Error_HIG(str,NULL); delete _videos[_nb_video]._aviheader; return 0; } /* check for resolution */ if( _nb_video ){ /* append operation */ aviInfo info0, infox; _videos[ 0 ]._aviheader->getVideoInfo (&info0); _videos[_nb_video]._aviheader->getVideoInfo (&infox); if(info0.width != infox.width || info0.height != infox.height) { GUI_Error_HIG(QT_TR_NOOP("Video dimensions don't match."), QT_TR_NOOP("You cannot mix different video dimensions yet. Using the partial video filter later will not work around this problem. The workaround is:\n\n1) \"Resize\" / \"Add Border\" / \"Crop\" each stream to the same resolution\n2) Concatenate them together")); delete _videos[_nb_video]._aviheader; return 0; } } // else update info _videos[_nb_video]._aviheader->getVideoInfo (&info); _videos[_nb_video]._aviheader->setMyName (name); // Printf some info about extradata { uint32_t l=0; uint8_t *d=NULL; _videos[_nb_video]._aviheader->getExtraHeaderData(&l,&d); if(l && d) { printf("The video codec has some extradata (%d bytes)\n",l); mixDump(d,l); printf("\n"); } } // 1st if it is our first video we update postproc if(!_nb_video) { uint32_t type,value; if(!prefs->get(DEFAULT_POSTPROC_TYPE,&type)) type=3; if(!prefs->get(DEFAULT_POSTPROC_VALUE,&value)) value=3; deletePostProc(&_pp ); initPostProc(&_pp,info.width,info.height); _pp.postProcType=type; _pp.postProcStrength=value; _pp.forcedQuant=0; updatePostProc(&_pp); if(_imageBuffer) delete _imageBuffer; _imageBuffer=new ADMImage(info.width,info.height); _imageBuffer->_qSize= ((info.width+15)>>4)*((info.height+15)>>4); _imageBuffer->quant=new uint8_t[_imageBuffer->_qSize]; _imageBuffer->_qStride=(info.width+15)>>4; }
void OpenDMLHeader::Dump( void ) { #define X_DUMP(x) printf(#x":\t\t:%ld\n",_mainaviheader.x); X_DUMP(dwStreams); X_DUMP(dwMicroSecPerFrame) ; X_DUMP(dwMaxBytesPerSec); X_DUMP(dwPaddingGranularity); X_DUMP(dwFlags); X_DUMP(dwTotalFrames); X_DUMP(dwInitialFrames); X_DUMP(dwWidth); X_DUMP(dwHeight); printf("\n"); #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%ld",_videostream.x); printf( "video stream attached:\n" ); printf( "______________________\n" ); printf(" Extra Data : %ld",_videoExtraLen); if(_videoExtraLen) { mixDump( _videoExtraData, _videoExtraLen); } printf("\n fccType :"); fourCC::print(_videostream.fccType); printf("\n fccHandler :"); fourCC::print(_videostream.fccHandler); X_DUMP(dwFlags); X_DUMP(dwInitialFrames); X_DUMP(dwRate); X_DUMP(dwStart); X_DUMP(dwSampleSize); X_DUMP(dwScale); X_DUMP(dwLength); X_DUMP(dwQuality); X_DUMP(dwSampleSize); printf("\n"); #undef X_DUMP #define X_DUMP(x) printf(#x":\t\t:%ld\n",(long int)_video_bih.x); X_DUMP( biSize); X_DUMP( biWidth); X_DUMP( biHeight); X_DUMP( biBitCount); X_DUMP( biCompression);fourCC::print(_video_bih.biCompression);printf("\n"); X_DUMP( biSizeImage); X_DUMP( biXPelsPerMeter); X_DUMP( biYPelsPerMeter); X_DUMP( biClrUsed); if(_isaudiopresent) { #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%ld",_audiostream.x); printf( "\naudio stream attached:\n" ); printf( "______________________\n" ); printf("\n fccType :"); fourCC::print(_audiostream.fccType); printf("\n fccHandler :"); fourCC::print(_audiostream.fccHandler); printf("\n fccHandler :0x%lx", _audiostream.fccHandler); X_DUMP(dwFlags); X_DUMP(dwInitialFrames); X_DUMP(dwRate); X_DUMP(dwScale); X_DUMP(dwStart); X_DUMP(dwLength); X_DUMP(dwSuggestedBufferSize); X_DUMP(dwQuality); X_DUMP(dwSampleSize); #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%lu",_wavHeader.x); X_DUMP(encoding); X_DUMP(channels); /* 1 = mono, 2 = stereo */ X_DUMP(frequency); /* One of 11025, 22050, or 44100 Hz */ X_DUMP(byterate); /* Average bytes per second */ X_DUMP(blockalign); /* Bytes per sample block */ X_DUMP(bitspersample); /* One of 8, 12, 16, or 4 for ADPCM */ printf(" Extra Data : %ld\n",_audioExtraLen); if(_audioExtraLen) { mixDump( _audioExtraData, _audioExtraLen); } printf("\n"); if(_wavHeader.encoding==WAV_MP3 && _audiostream.dwScale==1152) { GUI_Alert("This looks like MP3 vbr.\n Use audio->build time map"); } } }
void OpenDMLHeader::Dump( void ) { printf( "Main header\n" ); printf( "______________________\n" ); #define X_DUMP(x) printf(#x":\t\t:%ld\n",_mainaviheader.x); X_DUMP(dwStreams); X_DUMP(dwMicroSecPerFrame) ; X_DUMP(dwMaxBytesPerSec); X_DUMP(dwPaddingGranularity); X_DUMP(dwFlags); X_DUMP(dwTotalFrames); X_DUMP(dwInitialFrames); X_DUMP(dwWidth); X_DUMP(dwHeight); printf("\n"); #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%ld",_videostream.x); printf( "video stream attached:\n" ); printf( "______________________\n" ); printf(" Extra Data : %ld",_videoExtraLen); if(_videoExtraLen) { mixDump( _videoExtraData, _videoExtraLen); } printf("\n fccType :"); fourCC::print(_videostream.fccType); printf("\n fccHandler :"); fourCC::print(_videostream.fccHandler); X_DUMP(dwFlags); X_DUMP(dwInitialFrames); X_DUMP(dwRate); X_DUMP(dwStart); X_DUMP(dwSampleSize); X_DUMP(dwScale); X_DUMP(dwLength); X_DUMP(dwQuality); X_DUMP(dwSampleSize); printf("\n"); printBih(&_video_bih); /***************************************************************** Dump infos about all audio tracks found ******************************************************************/ for(int i=0;i<_nbAudioTracks;i++) { #undef X_DUMP #define X_DUMP(x) printf("\n "#x":\t\t:%ld",_audioTracks[i].avistream->x); printf( "\naudio stream attached:\n" ); printf( "______________________\n" ); printf("\n fccType :"); fourCC::print(_audioTracks[i].avistream->fccType); printf("\n fccHandler :"); fourCC::print(_audioTracks[i].avistream->fccHandler); printf("\n fccHandler :0x%lx", _audioTracks[i].avistream->fccHandler); X_DUMP(dwFlags); X_DUMP(dwInitialFrames); X_DUMP(dwRate); X_DUMP(dwScale); X_DUMP(dwStart); X_DUMP(dwLength); X_DUMP(dwSuggestedBufferSize); X_DUMP(dwQuality); X_DUMP(dwSampleSize); #undef X_DUMP printWavHeader(_audioTracks[i].wavHeader); printf(" Extra Data : %ld\n",_audioTracks[i].extraDataLen); if(_audioTracks[i].extraDataLen) { mixDump( _audioTracks[i].extraData, _audioTracks[i].extraDataLen); } printf("\n"); } }
/** \fn addFile \brief Load or append a file. The file type is determined automatically and the ad-hoc video decoder is spawned @param name: filename @return 1 on success, 0 on failure */ bool ADM_Composer::addFile (const char *name) { uint8_t ret = 0; aviInfo info; uint32_t magic; _VIDEOS video; if(!strcmp(name, AVS_PROXY_DUMMY_FILE)) magic=0; else { FILE *f=ADM_fopen(name,"r"); uint8_t buffer[4]; if(!f) return 0; fread(buffer,4,1,f); fclose(f); magic=(buffer[3]<<24)+(buffer[2]<<16)+(buffer[1]<<8)+(buffer[0]); } // First find the demuxer.... video._aviheader=ADM_demuxerSpawn(magic,name); if(!video._aviheader) { char str[512+1]; snprintf(str,512,QT_TR_NOOP("Cannot find a demuxer for %s"), name); str[512] = '\0'; GUI_Error_HIG(str,NULL); return false; } ret = video._aviheader->open(name); // check opening was successful if (ret == 0) { char str[512+1]; snprintf(str,512,QT_TR_NOOP("Attempt to open %s failed!"), name); str[512] = '\0'; GUI_Error_HIG(str,NULL); video._aviheader=NULL; return false; } /* check for resolution */ if( _segments.getNbRefVideos()) { /* append operation */ aviInfo info0, infox; _segments.getRefVideo(0)->_aviheader->getVideoInfo (&info0); video._aviheader->getVideoInfo (&infox); if( info0.width != infox.width || info0.height != infox.height ) { char str[512+1]; str[0] = '\0'; if( info0.width != infox.width ) strcpy(str,"width"); if( info0.height != infox.height ) snprintf(str+strlen(str),512-strlen(str), "%sheight%sdifferent between first and this video stream", (strlen(str)?" and ":""), (strlen(str)?" are ":" is ") ); str[512] = '\0'; GUI_Error_HIG(str,QT_TR_NOOP("You cannot mix different video dimensions yet. Using the partial video filter later, will not work around this problem. The workaround is:\n1.) \"resize\" / \"add border\" / \"crop\" each stream to the same resolution\n2.) concatinate them together")); delete video._aviheader; return false; } } // else update info video._aviheader->getVideoInfo (&info); video._aviheader->setMyName (name); // Printf some info about extradata uint32_t l=0; uint8_t *d=NULL; video._aviheader->getExtraHeaderData(&l,&d); if(l && d) { printf("[Editor]The video codec has some extradata (%d bytes)\n",l); mixDump(d,l); printf("\n"); } // 1st if it is our first video we update postproc if(!_segments.getNbRefVideos()) { uint32_t type=0,value=0; #if 0 if(!prefs->get(DEFAULT_POSTPROC_TYPE,&type)) type=3; if(!prefs->get(DEFAULT_POSTPROC_VALUE,&value)) value=3; #endif if(_pp) delete _pp; _pp=new ADM_PP(info.width,info.height); _pp->postProcType=type; _pp->postProcStrength=value; _pp->forcedQuant=0; _pp->update(); if(_imageBuffer) { if(_imageBuffer->quant) delete [] _imageBuffer->quant; _imageBuffer->quant=NULL; delete _imageBuffer; _imageBuffer=NULL; } _imageBuffer=new ADMImageDefault(info.width,info.height); _imageBuffer->_qSize= ((info.width+15)>>4)*((info.height+15)>>4); _imageBuffer->quant=new uint8_t[_imageBuffer->_qSize]; memset(_imageBuffer->quant,0,_imageBuffer->_qSize); _imageBuffer->_qStride=(info.width+15)>>4; // We also clear the filter queue... ADM_info("Clearing video filters\n"); ADM_vf_clearFilters(); }