/** * \fn parseScript * @param engine * @param name * @param mode * @return */ bool parseScript(IScriptEngine *engine, const char *name, IScriptEngine::RunMode mode) { bool ret; char *longname = ADM_PathCanonize(name); if (playing) { return false; } ret = engine->runScriptFile(std::string(longname), IScriptEngine::Normal); A_Resync(); // total duration & stuff if (ret) { video_body->setProjectName(longname); } prefs->set_lastprojectfile(longname); UI_updateRecentProjectMenu(); // update main menu shift EditableAudioTrack *ed=video_body->getDefaultEditableAudioTrack(); if(ed) { UI_setAudioCodec(ed->encoderIndex); UI_setTimeShift(ed->audioEncodingConfig.shiftEnabled,ed->audioEncodingConfig.shiftInMs); } delete [] longname; return ret; }
/** \fn ADM_PathSplit \brief Split path into absolute path+name and extention i.e. /foo/bar/zee.avi -> /foo/bar/zee,avi. Copy are returned */ void ADM_PathSplit(const char *str, char **root, char **ext) { char *full; uint32_t l; full = ADM_PathCanonize(str); // Search the last l = strlen(full); l--; ADM_assert(l > 0); while (*(full + l) != '.' && l) l--; if (!l || l == (strlen(full) - 1)) { if (l == (strlen(full) - 1)) *(full + l) = 0; // remove trailing *ext = new char[2]; *root = full; strcpy(*ext, ""); return; } // else we do get an extension // starting at l+1 uint32_t suff; suff = strlen(full) - l - 1; *ext = new char[suff + 1]; strcpy(*ext, full + l + 1); *(full + l) = 0; *root = full; }
/** * \fn call_scriptEngine * @param scriptFile */ void call_scriptEngine(const char *scriptFile) { char *fullpath=ADM_PathCanonize(scriptFile); FILE *fd=ADM_fopen(fullpath,"r"); if(!fd) { if(errno == EACCES) { GUI_Error_HIG(QT_TRANSLATE_NOOP("adm", "Permission Error"), QT_TRANSLATE_NOOP("adm", "Cannot open script \"%s\"."), fullpath); } if(errno == ENOENT) { GUI_Error_HIG(QT_TRANSLATE_NOOP("adm", "File Error"), QT_TRANSLATE_NOOP("adm", "Script \"%s\" does not exist."), fullpath); } return; } std::vector<IScriptEngine*> engines = getScriptEngines(); std::string root,ext; ADM_PathSplit(std::string(fullpath),root,ext); if(engines.size() == 1) { A_parseScript(engines[0],fullpath); if(avifileinfo) { A_Rewind(); UI_setMarkers(video_body->getMarkerAPts(),video_body->getMarkerBPts()); } return; } for (int i = 0; i < engines.size(); i++) { if (!engines[i]->defaultFileExtension().compare(ext)) { A_parseScript(engines[i],fullpath); A_Rewind(); UI_setMarkers(video_body->getMarkerAPts(),video_body->getMarkerBPts()); return; } } ADM_warning("Unable to appropriate script engine for script file\n"); }
/** * \fn ADM_PathSplit * \brief std::string version of the above * @param in * @param root * @param ext */ void ADM_PathSplit(const std::string &in,std::string &root, std::string &ext) { char *full; std::string canonized; full = ADM_PathCanonize(in.c_str()); canonized=std::string(full); delete [] full;full=NULL; size_t pos=canonized.find_last_of("."); // no "." ? if(pos==std::string::npos) { root=canonized; ext=std::string(""); return; } // else split root=canonized.substr(0,pos); ext=canonized.substr(pos+1); }
/** \fn A_openAvi \brief Open (replace mode) a video */ int A_openAvi (const char *name) { uint8_t res; char *longname; uint32_t magic[4]; uint32_t id = 0; if (playing) return 0; /// check if name exists FILE *fd; fd = ADM_fopen(name, "rb"); if (!fd) { if (errno == EACCES) { GUI_Error_HIG(QT_TRANSLATE_NOOP("adm", "Permission error"), QT_TRANSLATE_NOOP("adm", "Cannot open \"%s\"."), name); } if (errno == ENOENT) { GUI_Error_HIG(QT_TRANSLATE_NOOP("adm", "File error"), QT_TRANSLATE_NOOP("adm", "\"%s\" does not exist."), name); } return 0; } if (4 == fread(magic, 4, 4, fd)) id = R32(magic[0]); fclose(fd); GUI_close(); // Cleanup // DIA_StartBusy (); /* ** we may get a relative path by cmdline */ longname = ADM_PathCanonize(name); // check if avisynth input is given if (fourCC::check(id, (uint8_t *) "ADAP")) res = video_body->addFile(AVS_PROXY_DUMMY_FILE); else res = video_body->addFile(longname); // DIA_StopBusy (); // forget last project file video_body->setProjectName(""); if (res != ADM_OK) // an error occured { delete[] longname; if (ADM_IGN == res) { return 0; } if (fourCC::check(id, (uint8_t *) "//AD")) { GUI_Error_HIG(QT_TRANSLATE_NOOP("adm", "Cannot open project using the video loader."), QT_TRANSLATE_NOOP("adm", "Try 'File' -> 'Load/Run Project...'")); } else { GUI_Error_HIG(QT_TRANSLATE_NOOP("adm", "Could not open the file"), NULL); } return 0; } { int i; FILE *fd = NULL; char magic[4]; /* check myself it is a project file (transparent detected and read ** by video_body->addFile (name); */ //#warning FIXME #if 0 if ((fd = ADM_fopen(longname, "rb"))) { if (fread(magic, 4, 1, fd) == 4) { /* remember a workbench file */ if (!strncmp(magic, "ADMW", 4)) { actual_workbench_file = ADM_strdup(longname); } } fclose(fd); } #endif /* remember any video or workbench file to "recent" */ prefs->set_lastfile(longname); UI_updateRecentMenu(); updateLoaded(); if (currentaudiostream) { uint32_t nbAudio; audioInfo *infos = NULL; if (video_body->getAudioStreamsInfo(admPreview::getCurrentPts() + 1, &nbAudio, &infos)) { if (nbAudio > 1) { // Multiple track warn user GUI_Info_HIG(ADM_LOG_INFO, QT_TRANSLATE_NOOP("adm", "Multiple Audio Tracks"), QT_TRANSLATE_NOOP("adm", "The file you just loaded contains several audio tracks.\n" "Go to Audio->MainTrack to select the active one.")); } } if (infos) delete [] infos; // Revert mixer to copy //setCurrentMixerFromString("NONE"); EditableAudioTrack *ed = video_body->getDefaultEditableAudioTrack(); if (ed) ed->audioEncodingConfig.audioFilterSetMixer(CHANNEL_INVALID); } for (i = strlen(longname); i >= 0; i--) { #ifdef _WIN32 if (longname[i] == '\\' || longname[i] == '/') #else if (longname[i] == '/') #endif { i++; break; } } UI_setTitle(longname + i); } delete[] longname; return 1; }
void GUI_FileSel(const char *label, SELFILE_CB cb, int rw,char **rname) { /* Create the selector */ GtkWidget *dialog; char *name = NULL; char *tmpname; gchar *selected_filename; uint8_t res; if (rname) *rname = NULL; if (rw) dialog = gtk_file_chooser_dialog_new ("Save", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); else dialog = gtk_file_chooser_dialog_new ("Open File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); initFileSelector(); setFilter(dialog); gtk_window_set_title (GTK_WINDOW(dialog), label); gtk_register_dialog(dialog); if (rw) res = prefs->get(LASTFILES_LASTDIR_WRITE,(char **)&tmpname); else res = prefs->get(LASTFILES_LASTDIR_READ,(char **)&tmpname); if (res) { DIR *dir; char *str = ADM_PathCanonize(tmpname); ADM_PathStripName(str); /* LASTDIR may have gone; then do nothing and use current dir instead (implied) */ if (dir = opendir(str)) { closedir(dir); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),(gchar *)str); } delete [] str; } ADM_dealloc(tmpname); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { selected_filename = (gchar *)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); #ifdef _WIN32 if (*(selected_filename + strlen(selected_filename) - 1) == '\\'){ #else if (*(selected_filename + strlen(selected_filename) - 1) == '/'){ #endif GUI_Error_HIG(QT_TR_NOOP("Cannot open directory as a file"), NULL); } else { name = ADM_strdup(selected_filename); char *str = ADM_PathCanonize(name); ADM_PathStripName(str); if (rw) prefs->set(LASTFILES_LASTDIR_WRITE, (char*)str); else prefs->set(LASTFILES_LASTDIR_READ, (char*)str); delete [] str; } } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); // CYB 2005.02.23 if (cb) { #warning fixme const char *leak=NULL; FileSel_ReadWrite(cb, rw, name, leak); ADM_dealloc(name); } else *rname = name; } /* Mean:It seems it is attached to the dialog & destroyed with it As it leads to crash if we don't recreate them each time....*/ void initFileSelector(void) { #define ADD_PAT(x,y) gtk_file_filter_add_pattern(x,"*."#y); filter_avi=gtk_file_filter_new(); gtk_file_filter_set_name(filter_avi, "AVI (*.avi)"); ADD_PAT(filter_avi, avi); ADD_PAT(filter_avi, AVI); filter_mpeg=gtk_file_filter_new(); gtk_file_filter_set_name(filter_mpeg, "MPEG (*.m*,*.vob)"); ADD_PAT(filter_mpeg, [mM][12][Vv]); ADD_PAT(filter_mpeg, [Mm][pP][gG]); ADD_PAT(filter_mpeg, [Vv][Oo][Bb]); ADD_PAT(filter_mpeg, ts); ADD_PAT(filter_mpeg, TS); filter_image = gtk_file_filter_new(); gtk_file_filter_set_name(filter_image, QT_TR_NOOP("Images")); ADD_PAT(filter_image, png); ADD_PAT(filter_image, bmp); ADD_PAT(filter_image, jpg); ADD_PAT(filter_image, PNG); ADD_PAT(filter_image, BMP); ADD_PAT(filter_image, JPG); filter_all = gtk_file_filter_new(); gtk_file_filter_set_name(filter_all, QT_TR_NOOP("All")); gtk_file_filter_add_pattern(filter_all, "*"); }
/** \fn FileSel_SelectDir(const char *title,char *target,uint32_t max, const char *source) \brief allow to select a directory @return 0 on failure, 1 on success @param title : window title @param target : where to copy the result (must be allocated by caller) @param max : Max # of bytes that target can hold @param source : where we start from */ uint8_t FileSel_SelectDir(const char *title, char *target, uint32_t max, const char *source) { GtkWidget *dialog; uint8_t ret = 0; gchar *selected_filename; gchar last; char *dupe = NULL, *tmpname = NULL; DIR *dir = NULL; dialog = gtk_file_chooser_dialog_new("Open File", NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); gtk_window_set_title(GTK_WINDOW(dialog), title); gtk_register_dialog(dialog); /* Set default dir if provided ..*/ if (source) { dupe = ADM_PathCanonize(source); ADM_PathStripName(dupe); if (dir = opendir(dupe)) { closedir(dir); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), (gchar*)source); } delete [] dupe; } else //use pref { if (prefs->get(LASTFILES_LASTDIR_READ, (char **)&tmpname)) { dupe = ADM_PathCanonize(tmpname); ADM_PathStripName(dupe); if (dir = opendir(dupe)) { closedir(dir); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), (gchar*)dupe); } delete [] dupe; } } if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { selected_filename = (gchar*)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); if (strlen(selected_filename)) /* Nothing selected */ { /* Check it is a dir ...*/ printf("<%s>\n", selected_filename); strncpy(target, selected_filename, max); target[max-1] = 0; ret = 1; } } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); return ret; }
/** \fn FileSel_SelectWrite(const char *title,char *target,uint32_t max, const char *source) \brief allow to select a file @return 0 on failure, 1 on success @param title : window title @param target : where to copy the result (must be allocated by caller) @param max : Max # of bytes that target can hold @param source : where we start from */ uint8_t FileSel_SelectWrite(const char *title, char *target, uint32_t max, const char *source) { GtkWidget *dialog; uint8_t ret = 0; gchar *selected_filename; gchar last; char *dupe = NULL, *tmpname = NULL; DIR *dir = NULL; dialog = gtk_file_chooser_dialog_new("Write to File", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); gtk_window_set_title(GTK_WINDOW(dialog), title); initFileSelector(); setFilter(dialog); gtk_register_dialog(dialog); if (source && *source) { #if 0 // well, this is what they say to do, but then you can't easily edit the // name... // the following sequence is per GTK docs for gtk_file_chooser_set_filename() if (access (source, W_OK) == 0) // if file exists gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),(gchar *)source); else // new file #endif { dupe = ADM_PathCanonize(source); ADM_PathStripName(dupe); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), (gchar*)dupe); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), (gchar*)(source + strlen(dupe))); delete [] dupe; } } else //use pref { if (prefs->get(LASTFILES_LASTDIR_WRITE,(char **)&tmpname)) { dupe = ADM_PathCanonize(tmpname); if (dir = opendir(dupe)) { closedir(dir); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), (gchar*)tmpname); } delete [] dupe; } } if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { selected_filename = (gchar*)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); if (strlen(selected_filename)) { last = selected_filename[strlen(selected_filename) - 1]; if (last == '/' || last =='\\') { GUI_Error_HIG(QT_TR_NOOP("Cannot open directory as a file"), NULL); return 0; } else { strncpy(target, (char*)selected_filename, max); // Finally we accept it :) ret = 1; } } } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); return ret; }
int preferences::set_lastfile(const char* file){ char *internal_file; if( ! file ){ fprintf(stderr,"Prefs: set_lastfile(NULL) called\n"); return RC_FAILED; } internal_file = ADM_PathCanonize(file); if( !internal_file ){ fprintf(stderr,"Prefs: set_lastfile(): PathCanonize() returns NULL\n"); return RC_FAILED; } #ifdef DEBUG_PREFS fprintf(stderr,"Prefs: set_lastfile(%s)\n",file); if( strcmp(file,internal_file) ) fprintf(stderr,"Prefs: set_lastfile(%s) (with appended current dir)\n",internal_file); PRT_LAFI("<= LASTFILES_",1,opt_defs[LASTFILES_FILE1].current_val); PRT_LAFI("<= LASTFILES_",2,opt_defs[LASTFILES_FILE2].current_val); PRT_LAFI("<= LASTFILES_",3,opt_defs[LASTFILES_FILE3].current_val); PRT_LAFI("<= LASTFILES_",4,opt_defs[LASTFILES_FILE4].current_val); #endif // change opt_defs array // // ToDo: // * a call with a file already in lastfiles will resort lastfiles with // the actual argument on top // * a call with a file new to lastfiles will drop LASTFILE_4, move all // one step down and add the file as LASTFILE_1 if( opt_defs[LASTFILES_FILE4].current_val && !strncmp(opt_defs[LASTFILES_FILE4].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE4].current_val)) ){ char *x = opt_defs[LASTFILES_FILE4].current_val; opt_defs[LASTFILES_FILE4].current_val = opt_defs[LASTFILES_FILE3].current_val; opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = x; }else if( opt_defs[LASTFILES_FILE3].current_val && !strncmp(opt_defs[LASTFILES_FILE3].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE3].current_val)) ){ char *x = opt_defs[LASTFILES_FILE3].current_val; opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = x; }else if( opt_defs[LASTFILES_FILE2].current_val && !strncmp(opt_defs[LASTFILES_FILE2].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE2].current_val)) ){ char *x = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = x; }else if( opt_defs[LASTFILES_FILE1].current_val && !strncmp(opt_defs[LASTFILES_FILE1].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE1].current_val)) ){ ; // nothing to do - always on top }else{ if( opt_defs[LASTFILES_FILE4].current_val ) ADM_dealloc(opt_defs[LASTFILES_FILE4].current_val); opt_defs[LASTFILES_FILE4].current_val = opt_defs[LASTFILES_FILE3].current_val; opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val; opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val; opt_defs[LASTFILES_FILE1].current_val = ADM_strdup(internal_file); } #ifdef USE_LIBXML2 // change the xmlDocument if( ! xdoc ){ // no .avidemuxrc file or not loaded yet load(); // try to load it if( ! xdoc ){ // really: no .avidemuxrc file save(); // generate one from internal defaults and actual changes if( xdoc ) erase_blank_nodes(xdoc->children); } } if( ! xdoc ){ fprintf(stderr,"Prefs: no xml document generated ny load() nor save()\n"); }else{ xmlNodePtr p; xmlNodePtr q; // we assume a valid xml document, but maybe an older version ADM_assert( xdoc->children ); p = xdoc->children; // ->avidemux (should be there) p = goto_node_with_create(p, "lastfiles"); // ->avidemux->lastfile q = goto_node_with_create(p, "file1"); // ->avidemux->lastfile->1 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE1].current_val?opt_defs[LASTFILES_FILE1].current_val:"")); q = goto_node_with_create(p, "file2"); // ->avidemux->lastfile->2 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE2].current_val?opt_defs[LASTFILES_FILE2].current_val:"")); q = goto_node_with_create(p, "file3"); // ->avidemux->lastfile->3 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE3].current_val?opt_defs[LASTFILES_FILE3].current_val:"")); q = goto_node_with_create(p, "file4"); // ->avidemux->lastfile->4 xmlNodeSetContent( q, (xmlChar*)(opt_defs[LASTFILES_FILE4].current_val?opt_defs[LASTFILES_FILE4].current_val:"")); save_xml_to_file(); } #endif #ifdef DEBUG_PREFS PRT_LAFI("=> LASTFILES_",1,opt_defs[LASTFILES_FILE1].current_val); PRT_LAFI("=> LASTFILES_",2,opt_defs[LASTFILES_FILE2].current_val); PRT_LAFI("=> LASTFILES_",3,opt_defs[LASTFILES_FILE3].current_val); PRT_LAFI("=> LASTFILES_",4,opt_defs[LASTFILES_FILE4].current_val); #endif delete[] internal_file; return RC_OK; }
/** \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=ADM_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; }