/** \fn getTimeCode \brief Retrieve the timeinc value from the bitstream given. timebits is the #of bits to code it (in vol header) */ uint8_t getTimeCode(ADMBitstream *stream,uint32_t timebits,uint32_t *timeval) { uint32_t off=0; uint32_t globalOff=0; uint8_t code; uint32_t modulo,time_inc,vopcoded,vopType; uint8_t *begin,*end; begin=stream->data; end=stream->data+stream->len; while(begin<end-3) { if( ADM_findMpegStartCode(begin, end,&code,&off)) { if(code==0xb6) { /* Get more info */ if( extractVopInfo(begin+off, end-begin-off, timebits,&vopType,&modulo, timeval,&vopcoded)) { aprintf(" frame found: vopType:%x modulo:%d time_inc:%d vopcoded:%d\n",vopType,modulo,time_inc,vopcoded); return 1; } return 0; } begin+=off; } else return 0; } return 0; }
//************************************************ uint8_t lookupSeqEnd(ADMBitstream *bitstream,uint32_t *position) { uint8_t *ptr=bitstream->data,*end,code; uint32_t len=bitstream->len,offset; end=ptr+len; while(ADM_findMpegStartCode(ptr, end,&code,&offset)) { if(code==SEQ_END_CODE) { *position=ptr-bitstream->data+offset-4; return 1; } ptr+=offset; } return 0; }
//_____________________________________________________ // Update the user data field that is used to // detect in windows world if it is packed or not //_____________________________________________________ void updateUserData(uint8_t *start, uint32_t len) { // lookup startcode uint32_t sync,off,rlen; uint8_t code; uint8_t *end=start+len; while(ADM_findMpegStartCode(start, end,&code,&off)) { // update start+=off; rlen=end-start; if(code!=0xb2 || rlen<4) continue; printf("User data found\n"); // looks ok ? if(!strncmp((char *)start,"DivX",4)) { // start+=4; rlen-=4; // skip "DivX" // looks for a p while not null // if there isnt we will reach a new startcode // and it will stop while((*start!='p') && rlen) { if(!*start) { rlen=0; break; } rlen--; start++; } if(!rlen) { printf("Unpacketizer:packed marker not found!\n"); } else *start='n'; // remove 'p' return; } } }
void updateUserData(uint8_t *start, uint32_t len) { // lookup startcode uint32_t sync,off,rlen; uint8_t code; uint8_t *end=start+len; while(ADM_findMpegStartCode(start, end,&code,&off)) { // update start+=off; rlen=end-start; if(code!=0xb2 || rlen<4) continue; printf("User data found\n"); // looks ok ? if(!strncmp((char *)start,"DivX",4) && start[7]=='b'&& rlen>=14) { memcpy(start,signature,4+3+4+1+1+1); // 14 } } }
/** \fn detectPs \brief returns true if the file seems to be mpeg PS */ bool detectPs(const char *file) { uint32_t bufferSize; uint32_t nbPacket,nbMatch=0; FILE *f=ADM_fopen(file,"rb"); if(!f) return false; uint8_t *buffer = new uint8_t[PROBE_SIZE]; bufferSize=fread(buffer,1,PROBE_SIZE,f); fclose(f); nbPacket=bufferSize/2300; uint8_t *head,*tail; head=buffer; tail=buffer+bufferSize; uint8_t code; uint32_t offset; bool r = false; // Is it a Seq Start ? if(!buffer[0] && !buffer[1] && buffer[2]==1 && buffer[3]==0xba) { printf("Starts with SEQUENCE_START, probably MpegPS\n"); delete[] buffer; return true; } while(ADM_findMpegStartCode(head,tail,&code,&offset)) { head+=offset; if(code==0xE0) nbMatch++; } printf(" match :%d / %d (probeSize:%d)\n",nbMatch,nbPacket,bufferSize); if (nbMatch * 10 > nbPacket * 2) { r = true; } delete[] buffer; return r; }