int open_log_file(void) { g_log_file = qfopen(LOG_FILE, "a+"); if (g_log_file == NULL) { ERROR_MSG("Can't open log file: %s %s.", LOG_FILE); return 1; } /* time stamp start of log */ time_t start_time = time(NULL); char logtime_string[32]; /* write date */ if (start_time != (time_t)-1) { char *c = ctime(&start_time); if (c != NULL) { strlcpy(logtime_string, c, sizeof(logtime_string)); logtime_string[strlen(logtime_string)-1] = '\0'; // string from ctime includes return } } qfprintf(g_log_file, "---[ Start @ %s ]---\n", logtime_string); qfprintf(g_log_file, "---[ Target: %s ]---\n", command_line_file); return 0; }
void filterSaveScriptJS(FILE *f) { for(int i=1;i<nb_active_filter;i++) { VF_FILTERS tag=videofilters[i].tag; qfprintf(f,"app.video.addFilter("); for(unsigned int j=0;j<allfilters.size();j++) { if(tag==allfilters[j].tag) { qfprintf(f,"\"%s\"",allfilters[j].filtername); break; } } // get args CONFcouple *couple; char *arg,*value,*filtered=NULL; if(videofilters[i].filter->getCoupledConf( &couple)) { for(int j=0;j<couple->getNumber();j++) { couple->getEntry(j, &arg,&value); // Filter out backslash filtered=ADM_escape((ADM_filename *)value); qfprintf(f,",\"%s=%s\"",arg,filtered); if(filtered) delete [] filtered ; filtered=NULL; } delete couple; } qfprintf(f,");\n"); } }
int close_log_file(void) { if (g_log_file != NULL) { time_t start_time = time(NULL); char logtime_string[32]; /* write date */ if (start_time != (time_t)-1) { char *c = ctime(&start_time); if (c != NULL) { strlcpy(logtime_string, c, sizeof(logtime_string)); logtime_string[strlen(logtime_string)-1] = '\0'; // string from ctime includes return } } qfprintf(g_log_file, "---[ End @ %s ]---\n", logtime_string); qfprintf(g_log_file, "---[ Target: %s ]---\n\n", command_line_file); qfclose(g_log_file); } return 0; }
void filterSaveScriptJS(FILE *f) { for(int i=1;i<nb_active_filter;i++) { VF_FILTERS tag=videofilters[i].tag; qfprintf(f,"app.video.addFilter("); for(unsigned int j=0;j<nb_video_filter;j++) { if(tag==allfilters[j].tag) { qfprintf(f,"\"%s\"",allfilters[j].filtername); break; } } // get args CONFcouple *couple; char *arg,*value; if(videofilters[i].filter->getCoupledConf( &couple)) { for(int j=0;j<couple->getNumber();j++) { couple->getEntry(j, &arg,&value); qfprintf(f,",\"%s=%s\"",arg,value); } delete couple; } qfprintf(f,");\n"); } }
static int refput(ushort index) { if(!LoadOpis(index, CONSTANT_Utf8, NULL)) return(0); qfprintf(myFile, rfmt, index); return(utfstr(index, NULL)); }
//---------------------------------------------------------------------- static size_t wrtutf(void) { *set_output_ptr(bufbeg) = '\0'; qfprintf(myFile, "%s", bufbeg); if(!prompt()) return(0); return(maxpos - 1); }
//---------------------------------------------------------------------- static uchar prompt(void) { if(ferror(myFile)) return(0); if(no_prompt) return((uchar)!feof(myFile)); if(qfputc('\n', myFile) == EOF) return(0); qfprintf(myFile, "%*c", curpos, ' '); return(1); }
// Display a graph edge. bool idaapi cfunc_graph_t::print_edge(FILE *fp, int i, int j) { qfprintf(fp, "edge: { sourcename: \"%d\" targetname: \"%d\" ", i, j); const char *label = NULL; const citem_t *a = items[i]; const citem_t *b = items[j]; if ( a->is_expr() ) // For expressions, add labels to the edges { cexpr_t *e = (cexpr_t *)a; if ( e->x == b ) label = "x"; if ( e->y == b ) label = "y"; if ( e->z == b ) label = "z"; } if ( label != NULL ) qfprintf(fp, "label: \"%s\" ", label); qfprintf(fp, "}\n"); return true; }
//-------------------------------------------------------------------------- void groupman_t::emit_sgl( FILE *fp, psupergroup_listp_t sgl) { for (supergroup_listp_t::iterator it=sgl->begin(); it != sgl->end(); ++it) { psupergroup_t sg = *it; // Write ID if (!sg->id.empty()) qfprintf(fp, "%s:%s;", STR_ID, sg->id.c_str()); // Write Name if (!sg->name.empty()) qfprintf(fp, "%s:%s;", STR_GROUP_NAME, sg->name.c_str()); size_t group_count = sg->groups.size(); if (group_count > 0) { qfprintf(fp, "%s:", STR_NODESET); nodegroup_list_t &ngl = sg->groups; for (nodegroup_list_t::iterator it = ngl.begin(); it != ngl.end(); ++it) { pnodegroup_t ng = *it; qfprintf(fp, "("); size_t c = ng->size(); for (nodegroup_t::iterator it = ng->begin(); it != ng->end(); ++it) { nodedef_t *nd = *it; qfprintf(fp, "%d : %a : %a", nd->nid, nd->start, nd->end); if (--c != 0) qfprintf(fp, ", "); } qfprintf(fp, ")"); if (--group_count != 0) qfprintf(fp, ", "); } } qfprintf(fp, "\n"); } }
//---------------------------------------------------------------------- static int utfstr(ushort index, const ConstOpis *) { register int i; init_output_buffer(bufbeg, bufsize); i = fmtString(index, maxpos -= curpos, fmt_string, wrtutf); term_output_buffer(); maxpos += curpos; if(i < 0) return(0); qfprintf(myFile, "%s\n", bufbeg); return(++i); }
/*--------------------------------------------------------------------*/ uint32_t quantstat[32]; /* 0-31 ; 0 and 1 are unused */ void print_quant_stat (const char *n) { char *str = (char *) ADM_alloc (strlen (n) + 4); unsigned int i = 2, sum = 0, total = 0; FILE *fd; ADM_assert (str); strcpy (str, n); strcat (str, ".qs"); if ((fd = qfopen (str, "wb"))) { for (; i < 32; i++) { qfprintf (fd, "Quant % 2u: % 7u times\n", i, quantstat[i]); sum += i * quantstat[i]; total += quantstat[i]; } qfprintf (fd, "\nQuant over all: %2.2f\n", (float) sum / (float) total); qfclose (fd); } ADM_dealloc (str); }
//-------------------------------------------------------------------------- bool groupman_t::emit( const char *filename, const char *additional_sections) { FILE *fp = qfopen(filename, "w"); if (fp == NULL) return false; qfprintf(fp, "--%s\n", STR_PATHINFO); emit_sgl(fp, &path_sgl); qfprintf(fp, "--%s\n", STR_SIMILARINFO); emit_sgl(fp, &similar_sgl); // Emit additional sections if (additional_sections != NULL) qfprintf(fp, "%s\n", additional_sections); qfclose(fp); return true; }
/** \fn writeSystem \brief Write system part of index file */ bool TsIndexer::writeSystem(const char *filename,bool append) { qfprintf(index,"PSD1\n"); qfprintf(index,"[System]\n"); qfprintf(index,"Version=%d\n",ADM_INDEX_FILE_VERSION); qfprintf(index,"Type=T\n"); qfprintf(index,"File=%s\n",filename); qfprintf(index,"Append=%d\n",append); return true; }
//---------------------------------------------------------------------- static int outnum(ushort type, const ConstOpis *co) { char str[40]; op_t x; x.value = co->value; x.addr = co->value2; #ifdef __EA64__ x.value = make_ulonglong((uint32)x.value, (uint32)x.addr); #endif x.type = o_imm; x.dtyp = (uchar)(type - 3); x.offb = 0; init_output_buffer(str, sizeof(str)); OutValue(x, OOF_NUMBER | OOF_SIGNED | OOFW_IMM); term_output_buffer(); tag_remove(str, str, 0); qfprintf(myFile, "value = %s\n", str); return(1); }
//---------------------------------------------------------------------- static int outref(ushort count, const ConstOpis *co) { static const char typ[] = " Descriptor", nam[] = " Name"; switch(count) { case 3: qfprintf(myFile, ind_fmt, "Class", co->_class); qfprintf(myFile, ind_fmt, " ref", co->_name); qfprintf(myFile, ind_fmt, typ, co->_dscr); qfprintf(myFile, ind_fmt, nam, co->_subnam); break; case 2: qfprintf(myFile, ind_fmt, &typ[1], co->_name); qfprintf(myFile, ind_fmt, nam, co->_class); break; case 1: qfprintf(myFile, ind_fmt, "Index", co->_name); break; } qfputc('\n', myFile); return(1); }
// Print the node color. void idaapi cfunc_graph_t::print_node_attributes(FILE *fp, int n) { bgcolor_t c = get_node_color(n); if ( c != DEFCOLOR ) qfprintf(fp, " color: %s", get_color_name(c)); }
/** \fn runVC1 \brief Index VC1 stream */ bool TsIndexer::runVC1(const char *file,ADM_TS_TRACK *videoTrac) { uint32_t temporal_ref,val; uint8_t buffer[50*1024]; bool seq_found=false; TSVideo video; indexerData data; dmxPacketInfo info; beginConsuming=0; listOfUnits.clear(); if(!videoTrac) return false; if(videoTrac[0].trackType!=ADM_TS_VC1) { printf("[Ts Indexer] Only VC1 video supported\n"); return false; } video.pid=videoTrac[0].trackPid; memset(&data,0,sizeof(data)); data.picStructure=pictureFrame; string indexName=string(file); indexName=indexName+string(".idx2"); index=qfopen(indexName,"wt"); if(!index) { printf("[PsIndex] Cannot create %s\n",indexName.c_str()); return false; } writeSystem(file,false); pkt=new tsPacketLinearTracker(videoTrac->trackPid, audioTracks); FP_TYPE append=FP_APPEND; pkt->open(file,append); data.pkt=pkt; fullSize=pkt->getSize(); int startCode; decodingImage=false; #define likely(x) x #define unlikely(x) x while(1) { startCode=pkt->findStartCode(); if(!pkt->stillOk()) break; switch(startCode) { case 0x0f: // sequence start if(seq_found) { pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); addUnit(data,unitTypeSps,thisUnit,4); decodingImage=false; break; } // Verify it is high/advanced profile { int seqSize=0; tsGetBits bits(pkt); if(!bits.peekBits(1)) continue; // simple/main profile if(!decodeVC1Seq(bits,video)) continue; seqSize=bits.getConsumed(); video.extraDataLength=seqSize+4+1; memcpy(video.extraData+4,bits.data,seqSize); // Add info so that ffmpeg is happy video.extraData[0]=0; video.extraData[1]=0; video.extraData[2]=1; video.extraData[3]=0xf; video.extraData[seqSize+4+0]=0; seq_found=1; // Hi Profile printf("[VC1] Found seq start with %d x %d video\n",(int)video.w,(int)video.h); printf("[VC1] FPS : %d\n",(int)video.fps); printf("[VC1] sequence header is %d bytes\n",(int)seqSize); writeVideo(&video,ADM_TS_VC1); writeAudio(); qfprintf(index,"[Data]"); pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); addUnit(data,unitTypeSps,thisUnit,seqSize+4); decodingImage=false; continue; } break; case 0x0D: // Picture start { int type; uint8_t buffer[4]; uint32_t fType,sType; if(!seq_found) { continue; printf("[TsIndexer]No sequence start yet, skipping..\n"); } pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); tsGetBits bits(pkt); if(!decodeVC1Pic(bits,fType,sType)) continue; thisUnit.imageType=fType; updatePicStructure(video,sType); addUnit(data,unitTypePic,thisUnit,4); decodingImage=true; data.nbPics++; } break; default: break; } } printf("\n"); // Mark(&data,&info,2); qfprintf(index,"\n[End]\n"); qfprintf(index,"\n# Found %"PRIu32" images \n",data.nbPics); // Size qfprintf(index,"# Found %"PRIu32" frame pictures\n",video.frameCount); // Size qfprintf(index,"# Found %"PRIu32" field pictures\n",video.fieldCount); // Size qfclose(index); index=NULL; audioTracks=NULL; delete pkt; pkt=NULL; return 1; }
/** \fn writeVideo \brief Write Video section of index file */ bool TsIndexer::writeVideo(TSVideo *video,ADM_TS_TRACK_TYPE trkType) { qfprintf(index,"[Video]\n"); qfprintf(index,"Width=%d\n",video->w); qfprintf(index,"Height=%d\n",video->h); qfprintf(index,"Fps=%d\n",video->fps); qfprintf(index,"Interlaced=%d\n",video->interlaced); qfprintf(index,"AR=%d\n",video->ar); qfprintf(index,"Pid=%d\n",video->pid); if(video->extraDataLength) { qfprintf(index,"ExtraData=%d ",video->extraDataLength); for(int i=0;i<video->extraDataLength;i++) qfprintf(index," %02x",video->extraData[i]); qfprintf(index,"\n"); } switch(trkType) { case ADM_TS_MPEG2: qfprintf(index,"VideoCodec=Mpeg2\n");break;; case ADM_TS_H264: qfprintf(index,"VideoCodec=H264\n");break; case ADM_TS_VC1: qfprintf(index,"VideoCodec=VC1\n");break; default: printf("[TsIndexer] Unsupported video codec\n");return false; } return true; }
//---------------------------------------------------------------------- int32 gen_map_file(FILE *fp) { static const char frm[] = "Map format\n\n" "<~W~idth:D:3:::> [72-%D], 0 - unlimited \n" " Printing\n" "<~A~ll:R> Included constant types\n" "<~U~nused :R>> <Utf~8~:C>\n" " Sorting by<~C~lass:C>\n" "<~T~ype:R><~R~eferences:C>\n" "<U~n~sorted:R>><Na~m~eAndType :C>\n" " Number in pool<Num~b~ers:C>\n" "<~D~ecimal :R><~S~tring:C>>\n" "<~H~ex:R>>\n\n" "<~O~ut Utf8 string without encoding :C>\n" "<~I~nclude loader problem messages :C>>\n\n"; static const struct { ushort mask; ushort skip; char name[8]; int (*proc)(ushort index, const ConstOpis *); ushort arg; }defr[MAX_CONSTANT_TYPE] = { {0x01, 0, "Utf8 ", utfstr, 0}, {0x00, 0, "", NULL, 0}, // unicode {0x10, 4, "Integer", outnum, 3 + dt_dword}, {0x10, 4, "Float ", outnum, 3 + dt_float}, {0x10, 8, "Long ", outnum, 3 + dt_qword}, {0x10, 8, "Double ", outnum, 3 + dt_double}, {0x02, 2, "Class ", outref, 1}, {0x20, 2, "String ", outref, 1}, {0x04, 4, "Fld_ref", outref, 3}, {0x04, 4, "Met_ref", outref, 3}, {0x04, 4, "Int_ref", outref, 3}, {0x08, 4, "nam&typ", outref, 2} }; #define STR_MIN_RESERVED 32 char str[MAXSTR]; uchar tflag; int32 width, pos, numstr = 0; uint32 save_flags = idpflags; ushort curbit = 1; short unus = 1, unsort = 1, hexnum = 0, typemask = 0x3F, encinc = 2; ConstOpis opis; register ushort i, j; static char lft_fmt[] = "%08lX %5u%c %s "; if(!(idpflags & IDF_ENCODING)) ++encinc; // |= 1 uFlag = decflag(); // Decimal OutValue width = 80; bufsize = pos = sizeof(str)-32; if(!AskUsingForm_c(frm, &width, &pos, &unus, &unsort, &typemask, &hexnum, &encinc)) return(0); if(encinc & 2) unus = 0; // from error - all idpflags &= ~IDF_ENCODING; if(!(encinc & 1)) idpflags |= IDF_ENCODING; #if (MAXSTR-STR_MIN_RESERVED) <= 72 #error #endif no_prompt = 0; if(width < 72) { if(width) width = 72; else { no_prompt = 0; set_max: width = sizeof(str)-STR_MIN_RESERVED; } } else if(width > (MAXSTR-STR_MIN_RESERVED)) goto set_max; if(!typemask) typemask = 0x3F; if(hexnum) { lft_fmt[7] = ind_fmt[5] = rfmt[17] = '4'; lft_fmt[8] = ind_fmt[6] = rfmt[18] = 'X'; curpos = 8 + 1 + 4 + 1 + 1 + 0 + 1; } else { lft_fmt[7] = ind_fmt[5] = rfmt[17] = '5'; lft_fmt[8] = ind_fmt[6] = rfmt[18] = 'u'; curpos = 8 + 1 + 5 + 1 + 1 + 0 + 1; } if(unsort) { curpos += 7; curbit = typemask; } maxpos = width; bufbeg = str; myFile = fp; do { while(!(typemask & curbit)) curbit <<= 1; for(tflag = (uchar)unsort, pos = 10, i = 1; i <= curClass.maxCPindex; i++) { if(!LoadOpis(i, 0, &opis) || opis.type == CONSTANT_Unicode) DESTROYED("map::CP"); j = opis.type - 1; DEB_ASSERT((j >= MAX_CONSTANT_TYPE), "map:type"); if((!unus || !(opis.flag & _REF)) && (curbit & defr[j].mask)) { if(!numstr) { static const char fmh[]= "This file generated by IDA"; for(int k = (maxpos - sizeof(fmh)) / 2; k; k--) qfputc(' ', fp); char dname[MAXSTR]; if(ConstantNode.supstr(CNS_SOURCE, dname, sizeof(dname)) < 0) DESTROYED("map:srcname"); qfprintf(fp, "%s\n\n" " Constant Pool for \"%s\"\n\n" " offset #(%s)\n", fmh, dname, hexnum ? "hex" : "dec"); numstr = 5; } if(!tflag) { qfprintf(fp, "\n-----CONSTANT-%s-----\n", (defr[j].arg < 3) ? defr[j].name : ((defr[j].arg == 3) ? "(program references)" : "(numeric values)")); ++tflag; numstr += 2; } qfprintf(fp, lft_fmt, pos, i, (opis.flag & _REF) ? ' ' : '*', (unsort || defr[j].arg >= 3) ? defr[j].name : ""); { register int n = defr[j].proc(defr[j].arg ? defr[j].arg : i, &opis); if(n <= 0) goto do_eof; numstr += n; } if(unus && unsort && opis.type >= CONSTANT_Class) { numstr += refput(opis._name); if(opis.type > CONSTANT_String) { if(opis.type == CONSTANT_NameAndType) numstr += refput(opis._class); else { numstr += refput(opis._subnam); numstr += refput(opis._dscr); } } } if(feof(fp) || ferror(fp)) goto do_eof; } ++pos; switch(j = defr[j].skip) { case 0: // Utf8 / Unicode pos += opis._Ssize + 2; break; case 8: // Long / Double DEB_ASSERT((i == curClass.maxCPindex), "map:CPend"); ++i; default: pos += j; break; } } }while((typemask ^= curbit) != 0); if(numstr) { // if error print before - header problems! qfprintf(fp, "\nEnd of map\n"); numstr += 2; if((encinc & 2) && curClass.msgNode) { qfprintf(fp, "\nLoader problem messages\n\n"); int32 slen = print_loader_messages(str, NULL); if(slen == -1) goto do_eof; numstr += slen + 5; qfprintf(fp, "\nEnd of messages\n"); } if(feof(fp) || ferror(fp)) { do_eof: numstr = EOF; } } myFile = NULL; idpflags = save_flags; return(numstr); }
/** \fn writeAudio \brief Write audio headers */ bool TsIndexer::writeAudio(void) { if(!audioTracks) return false; qfprintf(index,"[Audio]\n"); qfprintf(index,"Tracks=%d\n",audioTracks->size()); for(int i=0;i<audioTracks->size();i++) { char head[30]; tsAudioTrackInfo *t=&(*audioTracks)[i]; sprintf(head,"Track%1d",i); qfprintf(index,"%s.pid=%x\n",head,t->esId); qfprintf(index,"%s.codec=%d\n",head,t->wav.encoding); qfprintf(index,"%s.fq=%d\n",head,t->wav.frequency); qfprintf(index,"%s.chan=%d\n",head,t->wav.channels); qfprintf(index,"%s.br=%d\n",head,t->wav.byterate); qfprintf(index,"%s.muxing=%d\n",head,t->mux); qfprintf(index,"%s.language=%s\n",head,t->language.c_str()); if(t->extraDataLen) { qfprintf(index,"%s.extraData=%d",head,t->extraDataLen); uint8_t *p=t->extraData; for(int i=0;i<t->extraDataLen;i++) qfprintf(index," %02x",p[i]); qfprintf(index,"\n"); } } return true; }
void idaapi run(int arg) { char buf[MAXSTR]; char cmt[MAXSTR]; char *valid_cmt = NULL; char ext[0x20]; FILE *f = NULL; short checkboxes = OPTION_NAMES | OPTION_COMMENTS; sval_t bank = 1; // default bool first = true; bool hasName = false; flags_t flags; ea_t ea = 0x0; if( AskUsingForm_c( madnes_options, &checkboxes, &bank ) != 1 || checkboxes == 0 ) return; // prepare filename for namelist (.nl) file get_input_file_path( buf, sizeof( buf ) ); qsnprintf( ext, sizeof( ext ),".%X.nl",--bank ); qstrncat( buf, ext, sizeof( buf )-strlen( buf ) ); // (always) create file f = qfopen( buf, "w" ); if( f == NULL ) { warning( "%s could not be created!", buf ); return; } msg( "Writing to file %s..", buf ); while( ea <= 0xFFFF ) { hasName = false; // get flags if( isCode( getFlags( ea ) ) ) flags = getFlags( ea ); else flags = getFlags( get_item_head( ea ) ); // if user either chose to export names or anynames if( ( ( checkboxes & OPTION_NAMES ) && has_name( flags ) ) || ( ( checkboxes & OPTION_ANYNAME ) && has_any_name( flags ) ) ) { // if current item is code or if current item is head of item if( isCode( flags ) || ea==get_item_head( ea ) ) { // get name get_name( ea, ea, buf, sizeof( buf ) ); // write to file qfprintf( f, "$%04X#%s#", ea, buf ); } else // if not code or not head of item (must be an array) { // get name of item start get_name( get_item_head( ea ), get_item_head( ea ), buf, sizeof( buf ) ); // calc displacement, write to file (example: "password+$04") qfprintf( f, "$%04X#%s+$%X#", ea, buf, ea-get_item_head( ea ) ); } hasName = true; } // if user chose to export cross references if( checkboxes & OPTION_XREFS ) { xrefblk_t xb; first = true; // cycle through all xrefs except ordinary flow xrefs for ( bool ok=xb.first_to( ea, XREF_FAR/*XREF_ALL*/); ok; ok=xb.next_to() ) { if( first ) // if first xref { if( !hasName ) // if this location hasn't a name yet, add symbol stub { qfprintf( f, "$%04X##", ea ); hasName = true; } qfprintf( f, "XREFS:\n\\"); // append XREFS first = false; } qfprintf( f, " $%04X\n\\", xb.from ); } } // if user chose to export comments if( checkboxes & OPTION_COMMENTS ) { if( has_cmt( flags ) ) // if current item has comment { // get comment // workaround for get_any_indeted_cmt() // -> unresolved external symbol "char * __stdcall get_any_indented_cmt(unsigned long,unsigned char *)" (?get_any_indented_cmt@@YGPADKPAE@Z) if( get_cmt( ea, false, cmt, sizeof( cmt ) ) == -1 ) get_cmt( ea, true, cmt, sizeof( cmt ) ); // validate comment (replace invalid chars, add room for additional chars) valid_cmt = validate_comment( cmt ); if( valid_cmt != NULL ) { if( !hasName ) { qfprintf( f, "$%04X##", ea ); // add symbol stub if no name yet hasName = true; } qfprintf( f, "%s", valid_cmt ); // write comment to file qfree( valid_cmt ); } } } if( hasName) qfprintf( f, "\n" ); ea++; // get name of each byte } qfclose( f ); msg( "done.\n" ); }
/** \fn dumpUnits */ bool TsIndexer::dumpUnits(indexerData &data,uint64_t nextConsumed,const dmxPacketInfo *nextPacket) { // if it contain a SPS or a intra/idr, we start a new line bool mustFlush=false; int n=listOfUnits.size(); int picIndex=0; H264Unit *unit=&(listOfUnits[0]); pictureStructure pictStruct=pictureFrame; // if I, IDR or SPS we start a new line for(int i=0;i<n;i++) { switch(listOfUnits[i].unitType) { case unitTypeSps: mustFlush=true;;break; case unitTypePic: picIndex=i; if(listOfUnits[i].imageType==1 || listOfUnits[i].imageType==4) mustFlush=true; break; case unitTypeSei: pictStruct=listOfUnits[i].imageStructure; break; default: ADM_assert(0); break; } } dmxPacketInfo *pic=&(listOfUnits[picIndex].packetInfo); dmxPacketInfo *p=&(unit->packetInfo); H264Unit *picUnit=&(listOfUnits[picIndex]); if(mustFlush) { if(audioTracks) { qfprintf(index,"\nAudio bf:%08"PRIx64" ",nextPacket->startAt); packetTSStats *s; uint32_t na; pkt->getStats(&na,&s); ADM_assert(na==audioTracks->size()); for(int i=0;i<na;i++) { packetTSStats *current=s+i; qfprintf(index,"Pes:%x:%08"PRIx64":%"PRIi32":%"PRId64" ", current->pid,current->startAt,current->startSize,current->startDts); } } data.beginPts=pic->pts; data.beginDts=pic->dts; // start a new line qfprintf(index,"\nVideo at:%08"PRIx64":%04"PRIx32" Pts:%08"PRId64":%08"PRId64" ", p->startAt,p->offset-unit->overRead,pic->pts,pic->dts); } int64_t deltaPts,deltaDts; if(data.beginPts==-1 || pic->pts==-1) deltaPts=-1; else deltaPts=pic->pts-data.beginPts; if(data.beginDts==-1 || pic->dts==-1) deltaDts=-1; else deltaDts=pic->dts-data.beginDts; qfprintf(index," %c%c",Type[picUnit->imageType],Structure[pictStruct&3]); int32_t delta=(int32_t)(nextConsumed-beginConsuming); qfprintf(index,":%06"PRIx32,delta); qfprintf(index,":%"PRId64":%"PRId64,deltaPts,deltaDts); beginConsuming=nextConsumed; listOfUnits.clear(); return true; }
void IDAP_run(int arg) { FILE *f, *f2; char *filename = construct_output_filename(".import_allocs.txt"); f = qfopen(filename, "wb"); char *filename2 = construct_output_filename(".import_allocs_wrappers.txt"); f2 = qfopen(filename2, "wb"); //r0 allocators funcMalloc.push_back(TFuncMalloc(" ExAllocatePoolWithQuota", 2)); funcMalloc.push_back(TFuncMalloc(" __imp__ExAllocatePoolWithQuota@8", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc(" ExAllocatePoolWithQuotaTag", 2)); funcMalloc.push_back(TFuncMalloc(" __imp__ExAllocatePoolWithQuotaTag@12", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("ExAllocatePoolWithTag", 2)); funcMalloc.push_back(TFuncMalloc("__imp__ExAllocatePoolWithTag@12", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("ExAllocatePoolWithTagPriority", 2)); funcMalloc.push_back(TFuncMalloc("__imp__ExAllocatePoolWithTagPriority@16", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("IoAllocateMdl", 2)); funcMalloc.push_back(TFuncMalloc("__imp__IoAllocateMdl@20", 2));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("RtlAllocateHeap", 3)); funcMalloc.push_back(TFuncMalloc("__imp__RtlAllocateHeap", 3));//ntoskrnl.exe funcMalloc.push_back(TFuncMalloc("EngAllocMem", 2)); funcMalloc.push_back(TFuncMalloc("__imp__EngAllocMem", 2));//win32k.sys funcMalloc.push_back(TFuncMalloc("__imp__EngAllocMem@12", 2));//win32k.sys //type pointer to size!!! //funcMalloc.push_back(TFuncMalloc("ZwAllocateVirtualMemory", 4)); //funcMalloc.push_back(TFuncMalloc("__imp__ZwAllocateVirtualMemory@24", 4));//ntoskrnl.exe //funcMalloc.push_back(TFuncMalloc("NtAllocateVirtualMemory", 4)); //funcMalloc.push_back(TFuncMalloc("__imp__NtAllocateVirtualMemory@24", 4));//ntoskrnl.exe //funcMalloc.push_back(TFuncMalloc("RtlReAllocateHeap", 4)); //funcMalloc.push_back(TFuncMalloc("HeapAlloc", 3)); //r3 allocators funcMalloc.push_back(TFuncMalloc("GlobalAlloc", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("HeapAlloc", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__HeapAlloc@12", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__HeapReAlloc@16", 4));//kernel32.dll funcMalloc.push_back(TFuncMalloc("HeapReAlloc", 4));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__LocalAlloc@8", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("LocalAlloc", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__LocalReAlloc@12", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("LocalReAlloc", 3));//kernel32.dll funcMalloc.push_back(TFuncMalloc("VirtualAlloc", 2)); funcMalloc.push_back(TFuncMalloc("__imp__VirtualAlloc@16", 2));//kernel32.dll funcMalloc.push_back(TFuncMalloc("__imp__MpHeapAlloc", 3));//msdart.dll export funcMalloc.push_back(TFuncMalloc("__imp__MpHeapReAlloc", 3));//msdart.dll export funcMalloc.push_back(TFuncMalloc("__imp__GdipAlloc@4", 1));//gdiplus.dll export //funcMalloc.push_back(TFuncMalloc("GpMalloc", 1));//gdiplus.dll funcMalloc.push_back(TFuncMalloc("__imp__malloc", 1));//msvcrt.dll funcMalloc.push_back(TFuncMalloc("_malloc", 1));//msvcrt.dll, the same as __imp__malloc funcMalloc.push_back(TFuncMalloc("__imp__realloc", 2));//msvcrt.dll funcMalloc.push_back(TFuncMalloc("_realloc", 2));//msvcrt.dll //funcMalloc.push_back(TFuncMalloc("_alloca", 1)); //funcMalloc.push_back(TFuncMalloc("_malloca", 1)); uint i = 0, j = funcMalloc.size(); msg("standart funcMalloc.size() = %d\n", funcMalloc.size()); for(; i< funcMalloc.size(); i++){ find_alloc_calls_ex(f, funcMalloc[i]); pretty_printing_ex(f, funcMalloc[i]); if(Malloc_calls.size() > 0 ) Malloc_calls.clear(); qfprintf(f,"\n\n"); qflush( f ); } qfclose( f ); j = funcMalloc_wrappers.size(); msg("standart funcMalloc_wrappers.size() = %d\n", j); //TODO: add level property i = 0; while( i < j){ find_alloc_calls_warreps_ex(f2, funcMalloc_wrappers[i]); msg("[%d].funcMalloc.size() = %d\n", i, funcMalloc_wrappers.size()); msg("[%d].Malloc_calls.size() = %d\n", i, Malloc_calls.size()); pretty_printing_ex(f2, funcMalloc_wrappers[i]); if(Malloc_calls.size() > 0 ) Malloc_calls.clear(); j = funcMalloc_wrappers.size(); i++; qflush( f2 ); } qfclose( f2 ); return ; }
void pretty_printing_ex(FILE* f, TFuncMallocWrapper func) { func_t *callee_func; qstring name_of_malloc_callee_function; int func_name_set = 0; for(int i = 0; i < Malloc_calls.size(); i++){ //qfprintf(f,"%s ----> %s xref: at %a \n", func.alloc_func_name, func.ancestor, Malloc_calls[i].address); qfprintf(f,"\r\n"); callee_func = get_func(Malloc_calls[i].address); func_name_set = 0; if(callee_func){ func_name_set = 1; get_short_name(&name_of_malloc_callee_function, callee_func->startEA); //generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); //tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); } if(func_name_set) qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, name_of_malloc_callee_function.c_str()); else qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, "CISSRT_undefined_function"); //qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function"); if(Malloc_calls[i].type == CONSTVALUE){ qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value); } else if(Malloc_calls[i].type == VARVALUE){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); else qfprintf(f,"Type: VAR, last modif lost :("); //qfprintf(f,"last modif: %s\n", instr_clean); } else if(Malloc_calls[i].type == VARVALUEVULN){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); else qfprintf(f,"Type: VAR, last modif lost :("); } else if(Malloc_calls[i].type == UNDEFINED){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); //qfprintf(f,"Type:var bytes, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, instr_clean);//shouldnt be here else qfprintf(f,"Type: UNDEFINED, last modif lost :("); } } }
void pretty_printing_ex(FILE* f, TFuncMalloc func) { func_t *callee_func; qstring name_of_malloc_callee_function; int func_name_set = 0; for(int i = 0; i < Malloc_calls.size(); i++){ qfprintf(f,"\r\n"); callee_func = get_func(Malloc_calls[i].address); func_name_set = 0; if(callee_func){ func_name_set = 1; get_short_name(&name_of_malloc_callee_function, callee_func->startEA); //generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); //tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); } if(func_name_set) qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, name_of_malloc_callee_function.c_str()); else qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function"); if(Malloc_calls[i].type == CONSTVALUE){ qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value); } if(Malloc_calls[i].type == VARVALUE){ char buffer[MAXSTR]; //char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer); else qfprintf(f,"Type: VAR, last modif lost :( \n"); //qfprintf(f,"last modif: \n", instr_clean); } if(Malloc_calls[i].type == VARVALUEVULN){ char buffer[MAXSTR]; //char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, Possible Integer Overflow %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer); else qfprintf(f,"Type: VAR, last modif lost :( \n");//shouldnt be here } if(Malloc_calls[i].type == UNDEFINED){ char buffer[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, buffer);//shouldnt be here else qfprintf(f,"Type: UNDEFINED, last modif lost :("); } } }
/** \fn runH264 \brief Index H264 stream */ bool TsIndexer::runH264(const char *file,ADM_TS_TRACK *videoTrac) { bool seq_found=false; bool firstSps=true; TSVideo video; indexerData data; dmxPacketInfo tmpInfo; TS_PESpacket SEI_nal(0); bool result=false; bool bAppend=false; beginConsuming=0; listOfUnits.clear(); printf("Starting H264 indexer\n"); if(!videoTrac) return false; if(videoTrac[0].trackType!=ADM_TS_H264) { printf("[Ts Indexer] Only H264 video supported\n"); return false; } video.pid=videoTrac[0].trackPid; memset(&data,0,sizeof(data)); data.picStructure=pictureFrame; string indexName=string(file); indexName=indexName+string(".idx2"); index=qfopen(indexName,(const char*)"wt"); if(!index) { printf("[PsIndex] Cannot create %s\n",indexName.c_str()); return false; } pkt=new tsPacketLinearTracker(videoTrac->trackPid, audioTracks); FP_TYPE append=FP_DONT_APPEND; if(true==ADM_probeSequencedFile(file)) { if(true==GUI_Question("There are several files with sequential file names. Should they be all loaded ?")) bAppend=true; } if(bAppend==true) append=FP_APPEND; writeSystem(file,bAppend); pkt->open(file,append); data.pkt=pkt; fullSize=pkt->getSize(); gui=createProcessing("Indexing",pkt->getSize()); int lastRefIdc=0; bool keepRunning=true; //****************** // 1 search SPS //****************** while(keepRunning) { int startCode=pkt->findStartCode(); if(startCode&0x80) continue; // Marker missing startCode&=0x1f; if(startCode!=NAL_SPS) continue; // Got SPS! uint32_t xA,xR; // Get info pkt->getInfo(&tmpInfo); // Read just enough... { SEI_nal.empty(); uint32_t code=0xffff+0xffff0000; while(((code&0xffffff)!=1) && pkt->stillOk()) { uint8_t r=pkt->readi8(); code=(code<<8)+r; SEI_nal.pushByte(r); } if(!pkt->stillOk()) break;; pkt->seek(tmpInfo.startAt,tmpInfo.offset-5); if (extractSPSInfo(SEI_nal.payload, SEI_nal.payloadSize-4,&spsInfo)) { ADM_info("[TsIndexer] Found video %"PRIu32"x%"PRIu32", fps=%"PRIu32"\n",video.w,video.h,video.fps); ADM_info("[TsIndexer] SPS says %"PRIu32"x%"PRIu32"\n",spsInfo.width,spsInfo.height); seq_found=1; video.w=spsInfo.width; video.h=spsInfo.height; video.fps=spsInfo.fps1000; xA=spsInfo.darNum; xR=spsInfo.darDen; writeVideo(&video,ADM_TS_H264); writeAudio(); qfprintf(index,"[Data]"); // Rewind break; }; } } if(!seq_found) goto the_end; decodingImage=false; //****************** // 2 Index //****************** bool fourBytes; while(keepRunning) { fourBytes=false; int startCode=pkt->findStartCode2(fourBytes); resume: if(!pkt->stillOk()) break; int startCodeLength=4; if(fourBytes==true) startCodeLength++; // 1:0 2:Nal ref idc 5:Nal Type if(startCode&0x80) { printf("[Ts] Nal Marker missing:%x\n",startCode); continue; // Marker missing } int fullStartCode=startCode; int ref=(startCode>>5)&3; startCode&=0x1f; // Ignore nal ref IDR aprintf("[%02x] Nal :0x%x,ref=%d,lastRef=%d at : %d \n",fullStartCode,startCode,ref,lastRefIdc,pkt->getConsumed()-beginConsuming); // Ignore multiple chunk of the same pic if((startCode==NAL_NON_IDR || startCode==NAL_IDR)&&decodingImage ) { aprintf("Still capturing, ignore\n"); continue; } switch(startCode) { case NAL_AU_DELIMITER: { aprintf("AU DELIMITER\n"); decodingImage = false; } break; case NAL_SEI: { // Load the whole NAL SEI_nal.empty(); uint32_t code=0xffff+0xffff0000; while(((0xffffff&code)!=1) && pkt->stillOk()) { uint8_t r=pkt->readi8(); code=(code<<8)+r; SEI_nal.pushByte(r); } if(!pkt->stillOk()) goto resume; aprintf("[SEI] Nal size :%d\n",SEI_nal.payloadSize); if(SEI_nal.payloadSize>=7) decodeSEI(SEI_nal.payloadSize-4, SEI_nal.payload,&(thisUnit.recoveryCount),&(thisUnit.imageStructure)); else printf("[SEI] Too short size+4=%d\n",*(SEI_nal.payload)); startCode=pkt->readi8(); decodingImage=false; pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); if(!addUnit(data,unitTypeSei,thisUnit,startCodeLength+SEI_nal.payloadSize+1)) keepRunning=false; fourBytes=true; goto resume; } break; case NAL_SPS: decodingImage=false; pkt->getInfo(&thisUnit.packetInfo); if(firstSps) { pkt->setConsumed(startCodeLength); // reset consume counter firstSps=false; } thisUnit.consumedSoFar=pkt->getConsumed(); if(!addUnit(data,unitTypeSps,thisUnit,startCodeLength)) keepRunning=false; break; case NAL_IDR: case NAL_NON_IDR: { #define NON_IDR_PRE_READ 8 aprintf("Pic start last ref:%d cur ref:%d nb=%d\n",lastRefIdc,ref,data.nbPics); lastRefIdc=ref; uint8_t bufr[NON_IDR_PRE_READ+4]; uint8_t header[NON_IDR_PRE_READ+4]; pkt->read(NON_IDR_PRE_READ,bufr); // unescape... ADM_unescapeH264(NON_IDR_PRE_READ,bufr,header); // getBits bits(NON_IDR_PRE_READ,header); int first_mb_in_slice,slice_type; first_mb_in_slice= bits.getUEG(); slice_type= bits.getUEG31(); if(slice_type>9) { printf("[TsIndexer] Bad slice type\n"); } if(slice_type>4) slice_type-=5; switch(slice_type) { case 0 : thisUnit.imageType=2;break; // P case 1 : thisUnit.imageType=3;break; // B case 2 : thisUnit.imageType=1;break; // I default : thisUnit.imageType=2;break; // SP/SI } if(startCode==NAL_IDR) thisUnit.imageType=4; // IDR aprintf("[>>>>>>>>] Pic Type %"PRIu32" Recovery %"PRIu32"\n",thisUnit.imageType,recoveryCount); if(thisUnit.imageType==1 && !thisUnit.recoveryCount) thisUnit.imageType=4; //I + Recovery=0 = IDR! data.nbPics++; decodingImage=true; pkt->getInfo(&thisUnit.packetInfo); thisUnit.consumedSoFar=pkt->getConsumed(); if(!addUnit(data,unitTypePic,thisUnit,startCodeLength+NON_IDR_PRE_READ)) keepRunning=false; // reset to default thisUnit.imageStructure=pictureFrame; thisUnit.recoveryCount=0xff; pkt->invalidatePtsDts(); } break; default: break; } } // End while result=true; the_end: printf("\n"); qfprintf(index,"\n[End]\n"); qfclose(index); index=NULL; audioTracks=NULL; delete pkt; pkt=NULL; return result; }
/*______________________________________________ Save the project as a script ______________________________________________*/ uint8_t ADM_Composer::saveAsScript (const char *name, const char *outputname) { const char *truefalse[]={"false","true"}; printf("\n **Saving script project **\n"); char * tmp; if (!_nb_segment) return 1; FILE * fd; if( !(fd = qfopen (name, "wt")) ){ fprintf(stderr,"\ncan't open script file \"%s\" for writing: %u (%s)\n", name, errno, strerror(errno)); return 0; } // Save source and segment //______________________________________________ qfprintf( fd,"//AD <- Needed to identify"); qfprintf (fd, "//\n"); qfprintf (fd, "//--automatically built--\n"); qfprintf (fd, "//--Project: %s\n\n",name); qfprintf (fd, "var app = new Avidemux();\n"); qfprintf (fd,"\n//** Video **\n"); qfprintf (fd,"// %02ld videos source \n", _nb_video); char *nm; uint32_t vop=!!(video_body->getSpecificMpeg4Info()&ADM_VOP_ON); for (uint32_t i = 0; i < _nb_video; i++) { nm=cleanupPath(_videos[i]._aviheader->getMyName() ); if(vop) { qfprintf(fd,"app.forceUnpack();\n"); } if(!i) { qfprintf (fd, "app.load(\"%s\");\n", nm); } else { qfprintf (fd, "app.append(\"%s\");\n", nm); } ADM_dealloc(nm); } qfprintf (fd,"//%02ld segments\n", _nb_segment); qfprintf (fd,"app.clearSegments();\n"); for (uint32_t i = 0; i < _nb_segment; i++) { uint32_t src,start,nb; src=_segments[i]._reference; start=_segments[i]._start_frame; nb=_segments[i]._nb_frames; qfprintf (fd, "app.addSegment(%lu,%lu,%lu);\n",src,start,nb); } // Markers // qfprintf(fd,"app.markerA=%d;\n",frameStart); qfprintf(fd,"app.markerB=%d;\n",frameEnd); // Reordering : Warning works only for video with one source video if(video_body->isReordered(0) && !vop) { qfprintf(fd,"app.rebuildIndex();\n"); } // postproc //___________________________ uint32_t pptype, ppstrength,ppswap; video_body->getPostProc( &pptype, &ppstrength, &ppswap); qfprintf(fd,"\n//** Postproc **\n"); qfprintf(fd,"app.video.setPostProc(%d,%d,%d);\n",pptype,ppstrength,ppswap); // fps if( avifileinfo ){ aviInfo info; video_body->getVideoInfo(&info); qfprintf(fd,"\napp.video.setFps1000(%u);\n",info.fps1000); } // Filter //___________________________ qfprintf(fd,"\n//** Filters **\n"); filterSaveScriptJS(fd); // Video codec //___________________________ uint8_t *extraData ; uint32_t extraDataSize; char *pth; qfprintf(fd,"\n//** Video Codec conf **\n"); videoCodecGetConf(&extraDataSize,&extraData); pth= cleanupPath(name ); qfprintf(fd,"app.video.codec(\"%s\",\"%s\",\"",videoCodecGetName(),videoCodecGetMode()); ADM_dealloc(pth); // Now deal with extra data qfprintf(fd,"%d ",extraDataSize); if(extraDataSize) { for(int i=0;i<extraDataSize;i++) { qfprintf(fd,"%02x ",extraData[i]); } } qfprintf(fd,"\");\n"); // Audio Source //______________________________________________ // Audio //______________________________________________ uint32_t delay,bitrate; qfprintf(fd,"\n//** Audio **\n"); qfprintf(fd,"app.audio.reset();\n"); // External audio ? char *audioName; AudioSource source; source=getCurrentAudioSource(&audioName); if(!audioName) audioName=""; if(source!=AudioAvi) { char *nm=cleanupPath(audioName); qfprintf(fd,"app.audio.load(\"%s\",\"%s\");\n", audioSourceFromEnum(source),nm); ADM_dealloc(nm); } else { // Maybe not the 1st track int source; source=video_body->getCurrentAudioStreamNumber(0); if(source) qfprintf(fd,"app.audio.setTrack(%d);\n", source); } getAudioExtraConf(&bitrate,&extraDataSize,&extraData); qfprintf(fd,"app.audio.codec(\"%s\",%d,%d,\"", audioCodecGetName(),bitrate,extraDataSize); for(int i=0;i<extraDataSize;i++) { qfprintf(fd,"%02x ",extraData[i]); } qfprintf(fd,"\");\n"); //qfprintf(fd,"app.audio.process=%s;\n",truefalse[audioProcessMode()]); qfprintf(fd,"app.audio.normalizeMode=%d;\n",audioGetNormalizeMode()); qfprintf(fd,"app.audio.normalizeValue=%d;\n",audioGetNormalizeValue()); qfprintf(fd,"app.audio.delay=%d;\n",audioGetDelay()); qfprintf(fd,"app.audio.mixer(\"%s\");\n",getCurrentMixerString()); // VBR ? if(currentaudiostream) { uint32_t encoding=currentaudiostream->getInfo()->encoding; if(currentaudiostream->isVBR() && (encoding==WAV_MP3 || encoding==WAV_MP2)) { qfprintf(fd,"app.audio.scanVBR();\n"); } } // Change fps ? switch(audioGetFpsConv()) { case FILMCONV_NONE: ;break; case FILMCONV_PAL2FILM: qfprintf(fd,"app.audio.pal2film=true;\n");break; case FILMCONV_FILM2PAL: qfprintf(fd,"app.audio.film2pal=true;\n");break; default:ADM_assert(0); } // Resampling switch(audioGetResampling()) { case RESAMPLING_NONE: ;break; case RESAMPLING_CUSTOM: qfprintf(fd,"app.audio.resample=%u;\n",audioGetResample());break; default:ADM_assert(0); } if (audioGetDrc()) qfprintf(fd,"app.audio.drc=true;\n"); // Mixer // container qfprintf(fd,"app.setContainer(\"%s\");\n",getCurrentContainerAsString()); if(outputname) { char *o=cleanupPath(outputname); qfprintf(fd,"setSuccess(app.save(\"%s\"));\n",o); ADM_dealloc(o); } else { qfprintf(fd,"setSuccess(%d);\n",1); } qfprintf(fd,"//app.Exit();\n"); qfprintf(fd,"\n//End of script\n"); // All done qfclose (fd); return 1; }
/** \fn dmx_indexer \brief Create index file @param mpeg Name of the file to index @param file Name of the index file to create @param preferedAudio Default audio track @param nbTracks # of tracks, including video @param tracks track descriptor @return 1 on success, 0 on failure The incoming file can be mpeg PS/TS/ES or ASF. The payload can be mostly mpeg2, with some work done to support later mpeg4/H264 in TS mostly */ uint8_t dmx_indexer(const char *mpeg,const char *file,uint32_t preferedAudio,uint8_t autosync,uint32_t nbTracks,MPEG_TRACK *tracks) { DIA_progressIndexing *work; dmx_demuxer *demuxer; char *realname=PathCanonize(mpeg); FILE *out; DMX_TYPE mpegType; uint8_t mpegTypeChar; uint32_t multi=0; dmx_payloadType payloadType=DMX_PAYLOAD_MPEG2; mpegType=dmxIdentify(realname); if(mpegType==DMX_MPG_UNKNOWN) { delete [] realname; return 0; } switch(mpegType) { case DMX_MPG_MSDVR: { dmx_demuxerMSDVR *dmx; dmx=new dmx_demuxerMSDVR(nbTracks,tracks,0); demuxer=dmx; mpegTypeChar='M'; break; } case DMX_MPG_TS: case DMX_MPG_TS2: { dmx_demuxerTS *dmx; dmx=new dmx_demuxerTS(nbTracks,tracks,0,mpegType); demuxer=dmx; switch(mpegType) { case DMX_MPG_TS :mpegTypeChar='T';break; case DMX_MPG_TS2 :mpegTypeChar='S';break; default: ADM_assert(0); } switch(tracks[0].streamType) { case ADM_STREAM_H264: payloadType=DMX_PAYLOAD_H264;break; case ADM_STREAM_MPEG4: payloadType=DMX_PAYLOAD_MPEG4;break; case ADM_STREAM_MPEG_VIDEO: payloadType=DMX_PAYLOAD_MPEG2;break; default: ADM_assert(0); } break; } case DMX_MPG_ES: demuxer=new dmx_demuxerES; mpegTypeChar='E'; break; case DMX_MPG_H264_ES: payloadType=DMX_PAYLOAD_H264; demuxer=new dmx_demuxerES; mpegTypeChar='E'; break; case DMX_MPG_PS: { dmx_demuxerPS *dmx; fileParser *fp; FP_TYPE type=FP_PROBE; fp=new fileParser; fp->open(realname,&type); delete fp; if(type==FP_APPEND) { if(GUI_Question(QT_TR_NOOP("There is several mpeg file, append them ?"))) multi=1; } dmx=new dmx_demuxerPS(nbTracks,tracks,multi); demuxer=dmx; mpegTypeChar='P'; } break; default : ADM_assert(0); } demuxer->open(realname); out=qfopen(file,"wt"); if(!out) { printf("\n Error : cannot open index !"); delete demuxer; delete [] realname; return 0; } qfprintf(out,"ADMY0003\n"); qfprintf(out,"Type : %c\n",mpegTypeChar); // ES for now qfprintf(out,"File : %s\n",realname); qfprintf(out,"Append : %d\n",multi); qfprintf(out,"Image : %c\n",'P'); // Progressive qfprintf(out,"Picture : %04lu x %04lu %05lu fps\n",0,0,0); // width... qfprintf(out,"Payload : %c%c%c%c\n",'M','P','E','G'); // width... qfprintf(out,"Nb Gop : %08lu \n",0); // width... qfprintf(out,"Nb Images: %010lu \n",0); // width... qfprintf(out,"Nb Audio : %02lu\n",nbTracks-1); qfprintf(out,"Main aud : %02lu\n",preferedAudio); qfprintf(out,"Streams : "); for(int s=0;s<nbTracks;s++) { if(!s){ qfprintf(out,"V%04x:%04x ",tracks[0].pid,tracks[0].pes); }else{ qfprintf(out,"A%04x:%04x ",tracks[s].pid,tracks[s].pes); } } qfprintf(out,"\n"); qfprintf(out,"# NGop NImg nbImg type:abs:rel:size ...\n"); uint8_t grabbing=0,seq_found=0; uint32_t total_frame=0,val; uint32_t originalPriority = getpriority(PRIO_PROCESS, 0); uint32_t priorityLevel; prefs->get(PRIORITY_INDEXING,&priorityLevel); setpriority(PRIO_PROCESS, 0, ADM_getNiceValue(priorityLevel)); work=new DIA_progressIndexing(mpeg); printf("*********Indexing started (%d audio tracks)***********\n",nbTracks); dmx_runData run; memset(&run,0,sizeof(dmx_runData)); run.totalFileSize=demuxer->getSize(); run.demuxer=demuxer; run.work=work; run.nbTrack=nbTracks; run.fd=out; dmx_videoIndexer *idxer=NULL; switch(payloadType) { case DMX_PAYLOAD_MPEG2: { idxer=new dmx_videoIndexerMpeg2(&run); break; } case DMX_PAYLOAD_MPEG4:ADM_assert(0); case DMX_PAYLOAD_H264: idxer=new dmx_videoIndexerH264(&run); break; default: ADM_assert(0); } idxer->run(); idxer->cleanup(); delete idxer; idxer=NULL; printf("*********Indexing Ended (%d audio tracks)***********\n",nbTracks); switch(run.imageAR) { case 1: qfprintf(out,"# Video Aspect Ratio : %s\n", "1:1" );break; case 2: qfprintf(out,"# Video Aspect Ratio : %s\n", "4:3" );break; case 3: qfprintf(out,"# Video Aspect Ratio : %s\n", "16:9" );break; default: printf("imageAR=%u\n",run.imageAR); GUI_Error_HIG(QT_TR_NOOP("Can't determine aspect ratio"),NULL); } /* Now update......... */ fseeko(out,0,SEEK_SET); // Update if needed uint32_t compfps,delta=computeTimeDifference(&(run.firstStamp),&(run.lastStamp)); delta=delta/1000; // in second if(delta) { compfps= (1000*run.nbImage)/delta; // 3 Million images should be enough, no overflow } else { compfps=run.imageFPS; } // Detect film (i.e. NTSC with computed fps close to 24) if(run.imageFPS==29970 || run.imageFPS==30000) { if(compfps>23800 && compfps < 24200) run.imageFPS=23976; } // Detect interlaced vs progressive // If field encoded, the average fps is about twice as theoritical fps char type='P'; float err; err=run.imageFPS*2; err-=compfps; err*=100; err/=run.imageFPS*2; if(err<0) err=-err; printf("%lu :%lu / %lu , %f\n",run.imageFPS,run.imageFPS*2,compfps,err); if(err<10) { type='I'; printf("Seems to be field encoded\n"); } else { printf("Seems to be frame encoded\n"); } // Now dump the delta PTS // *****************Update header************* qfprintf(out,"ADMY0003\n"); qfprintf(out,"Type : %c\n",mpegTypeChar); // ES for now qfprintf(out,"File : %s\n",realname); qfprintf(out,"Append : %d\n",multi); qfprintf(out,"Image : %c\n",type); // Progressive qfprintf(out,"Picture : %04lu x %04lu %05lu fps\n",run.imageW,run.imageH,run.imageFPS); // width... switch(payloadType) { case DMX_PAYLOAD_MPEG2: qfprintf(out,"Payload : MPEG\n"); // MPEG,MP_4,H264 break; case DMX_PAYLOAD_MPEG4: qfprintf(out,"Payload : MP_4\n"); // MPEG,MP_4,H264 break; case DMX_PAYLOAD_H264: qfprintf(out,"Payload : H264\n"); // MPEG,MP_4,H264 break; default: ADM_assert(0); } qfprintf(out,"Nb Gop : %08lu \n",run.nbGop); // width... qfprintf(out,"Nb Images: %010lu \n",run.nbImage); // width... qfclose(out); delete work; printf("*********Indexing stopped***********\n"); printf("Found :%lu gop\n",run.nbGop); printf("Found :%lu image\n",run.nbImage); printf("Average fps :%lu /1000 fps\n",compfps); delete demuxer; delete [] realname; setpriority(PRIO_PROCESS, 0, originalPriority); return 1; }