uint8_t     OneTrack::run(uint16_t twofirst,uint8_t *data,uint32_t size,uint32_t usableSize,uint64_t pts)
{
uint32_t padding;
    
    if(!runCode) // new line
    {
        currentPTS=pts;
        runCode=twofirst-usableSize;
        addLine(pts,index);
#if 0
        {
        uint16_t hh,mm,ss,ms;
        uint32_t timestamp;

              timestamp=pts/90;
              ms2time(timestamp,&hh,&mm,&ss,&ms);
              printf("Line : %03u  at %02d:%02d:%02d \n",nbLines,hh,mm,ss);
        }
#endif
        addData(data,size);
        if(runCode<0) runCode=0;
        return 1; 
    }
    if(currentPTS==ADM_NO_PTS && pts!=ADM_NO_PTS)
        currentPTS=lines[nbLines-1].pts=pts;
    runCode-=usableSize;
    if(runCode<0)
    {
         printf("Overrun %d\n",runCode);
         runCode=0;
    }
    addData(data,size);
    return 1;
    
} 
/// convert frame number and fps to hour/mn/sec/ms
void  frame2time(	uint32_t frame, uint32_t fps, uint16_t * hh, uint16_t * mm,
	 			uint16_t * ss, uint16_t * ms)
{
    UNUSED_ARG(fps);
    uint32_t len2;
    len2 = video_body->getTime(frame);
    ms2time(len2,hh,mm,ss,ms);
}
void show_info(char *p){
   UNUSED_ARG(p);
   uint32_t war,har;
   const char *s;
   
   if (avifileinfo)
    {
		
   printf("Video\n");
   printf("   Video Size: %u x %u\n", avifileinfo->width, avifileinfo->height);
   printf("   Frame Rate: %2.3f fps\n", (float)avifileinfo->fps1000/1000.F);
   printf("   Number of frames: %d frames\n", avifileinfo->nb_frames);
   printf("   Codec FourCC: %s\n", fourCC::tostring(avifileinfo->fcc));
   if(avifileinfo->nb_frames){
     uint16_t hh, mm, ss, ms;
      frame2time(avifileinfo->nb_frames, avifileinfo->fps1000,&hh, &mm, &ss, &ms);
      printf("   Duration: %02d:%02d:%02d.%03d\n", hh, mm, ss, ms);
   }else{
      printf("   Duration: 00:00:00.000\n");
   }
   war=video_body->getPARWidth();
   har=video_body->getPARHeight();
   getAspectRatioFromAR(war,har, &s);
   printf("   Aspect Ratio: %s (%u:%u)\n", s,war,har);

   printf("Audio\n");
   if( wavinfo )
    {
      printf("   Codec: %s\n",getStrFromAudioCodec(wavinfo->encoding));     
      printf("   Mode: ");
      switch( wavinfo->channels ){
         case 1:  printf("MONO\n"); break;
         case 2:  printf("STEREO\n"); break;
         default: printf("????\n"); break;
      }
      printf("   BitRate: %u Bps / %u kbps\n", wavinfo->byterate, wavinfo->byterate*8/1000);
      printf("   Frequency: %u Hz\n", wavinfo->frequency);
      { double du = video_body->getAudioLength();
        uint16_t hh, mm, ss, ms;
         du*=1000;
         du/=wavinfo->byterate;
         ms2time((uint32_t)floor(du), &hh, &mm, &ss, &ms);
         printf("   Duration: %02d:%02d:%02d.%03d (%lu MBytes)\n", hh, mm, ss, ms, video_body->getAudioLength()>>20);
      }
   }else{
      printf("   Codec: NONE\n");
      printf("   Mode: NONE\n");
      printf("   BitRate: NONE\n");
      printf("   Frequency: NONE\n");
      printf("   Duration: NONE\n");
    }
   }
/// convert frame number and fps to hour/mn/sec/ms
void  frame2time(	uint32_t frame, uint32_t fps, uint16_t * hh, uint16_t * mm,
                                uint16_t * ss, uint16_t * ms)
{
    UNUSED_ARG(fps);
double d;
    uint32_t len2;
    d=frame;
    d=d/fps;
    d*=1000000.;
    
    len2 = (uint32_t)(d); //video_body->getTime(frame);
    ms2time(len2,hh,mm,ss,ms);
}
Exemple #5
0
/**
 * \fn          setMe
 * \brief       construct UI to display editable timestamp
 * @param dialog
 * @param opaque
 * @param line
 */
void diaElemTimeStamp::setMe(void *dialog, void *opaque,uint32_t line)
{
  myTimeWidget *myTWidget = new myTimeWidget;
  myTWidget->hours=new QSpinBox((QWidget *)dialog);
  myTWidget->minutes=new QSpinBox((QWidget *)dialog);
  myTWidget->seconds=new QSpinBox((QWidget *)dialog);
  myTWidget->mseconds=new QSpinBox((QWidget *)dialog);
  myWidget=(void *)myTWidget; 
  
  myTWidget->minutes->setRange(0,59);
  myTWidget->seconds->setRange(0,59);
  myTWidget->mseconds->setRange(0,999);
  
  QLabel *textSemiColumn=new QLabel( "h:");
  QLabel *textSemiColumn2=new QLabel( "m:");
  QLabel *textComma=new QLabel( "s,");
  
  QGridLayout *layout=(QGridLayout*) opaque;
  QHBoxLayout *hboxLayout = new QHBoxLayout();
  
  uint32_t ms=*(uint32_t *)param;
  // split time in ms into hh/mm/ss
  uint32_t hh,mm,ss,msec;
  ms2time(ms,&hh,&mm,&ss,&msec);
  myTWidget->hours->setValue(hh);
  myTWidget->minutes->setValue(mm);
  myTWidget->seconds->setValue(ss);
  myTWidget->mseconds->setValue(msec);
 
 QLabel *text=new QLabel( QString::fromUtf8(this->paramTitle),(QWidget *)dialog);
 text->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
// text->setBuddy(box);

 QSpacerItem *spacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

 hboxLayout->addWidget(myTWidget->hours);
 hboxLayout->addWidget(textSemiColumn);
 
 hboxLayout->addWidget(myTWidget->minutes);
 hboxLayout->addWidget(textSemiColumn2);
 
 hboxLayout->addWidget(myTWidget->seconds);
 hboxLayout->addWidget(textComma);
 hboxLayout->addWidget(myTWidget->mseconds);
 
 hboxLayout->addItem(spacer);

 layout->addWidget(text,line,0);
 layout->addLayout(hboxLayout,line,1);
 
}
Exemple #6
0
/**
 * \fn DIA_gotoTime
 * \brief Popup a display to enter hour/minutes/seconds/ms
 * @param hh
 * @param mm
 * @param ss
 * @param ms
 * @return 
 */
uint8_t DIA_gotoTime(uint32_t *hh, uint32_t *mm, uint32_t *ss,uint32_t *ms)
{
uint32_t v=(*hh)*3600*1000+(*mm)*60*1000+(*ss)*1000+*ms;
uint32_t max=(uint32_t)(video_body->getVideoDuration()/1000);

diaElemTimeStamp eh(&v,QT_TRANSLATE_NOOP("adm","TimeStamp:"),0,max);
diaElem *allWidgets[]={&eh};

  if(!diaFactoryRun(QT_TRANSLATE_NOOP("adm","Go to Time"),1,allWidgets)) return 0;

//
ms2time(v,hh,mm,ss,ms);
return 1;

}
static const char *ADMus2Time(uint64_t ams)
{
static char buffer[256];
uint32_t ms=(uint32_t)(ams/1000);
    uint32_t hh,mm,ss,mms;
    if(ams==ADM_NO_PTS)
        sprintf(buffer,"xx:xx:xx.xxx");
    else    
    {
        ms2time(ms,&hh,&mm,&ss,&mms);
        sprintf(buffer,"%01" PRIu32":%02" PRIu32":%02" PRIu32".%03" PRIu32,hh,mm,ss,mms);
    }
    return buffer;

}
uint8_t DIA_workingQt4::update(uint32_t percent)
{
		#define GUI_UPDATE_RATE 1000

        UI_purge();

        if(!_priv) return 1;
        if(!percent) return 0;
        if(percent==lastper)
        {

            return 0;
        }

        elapsed=_clock.getElapsedMS();

        if(elapsed<_nextUpdate) 
        {
          return 0;
        }

        _nextUpdate=elapsed+1000;
        lastper=percent;

		uint32_t hh,mm,ss,mms;
		char string[9];

		ms2time(elapsed,&hh,&mm,&ss,&mms);
		sprintf(string,"%02d:%02d:%02d",hh,mm,ss);

        workWindow *wind=(workWindow *)_priv; ADM_assert(wind);
        
        if(percent>=1)
        {
            double totalTime=(100*elapsed)/percent;
            double remaining=totalTime-elapsed;
            if(remaining<0)
                remaining=0;
            uint32_t remainingMs=(uint32_t)remaining;
            wind->ui->labelTimeLeft->setText(ms2timedisplay(remainingMs));
        }
        
        
        wind->ui->labelElapsed->setText(string);
        wind->ui->progressBar->setValue(percent);
       
        return 0;
}
Exemple #9
0
QVariant
MediaTableModel::data ( const QModelIndex & index,
                    int role ) const
{
    if ( !index.isValid() )
        return QVariant ();

    else if ( role == Qt::FontRole ){
        int row = index.row();
        QFont font;
        if ( row == core->currentPosition() ){
            font.setBold( true );
            return QVariant ( font );
        }
    }

    else if ( role == Qt::TextAlignmentRole ) {
        int col = index.column();
        QString key = keys [ col ];
        if ( ( key == "timesplayed" ) || ( key == "tracknr" )
            || (key == "duration"))
            return QVariant ( Qt::AlignCenter );
        else
            return QVariant ();
    }

    if ( (role != Qt::DisplayRole) && (role != Qt::ToolTipRole) )
        return QVariant ();

    int row = index.row();
    int col = index.column();

    QString key = keys[ col ];

    if ( key == "duration" ){
        int ms = core->value(row, key).toInt();
        QString time = ms2time( ms );
        return QVariant ( time );
    }

    return core->value( row, key);
}
uint8_t       DIA_progressIndexing::update(uint32_t done,uint32_t total, uint32_t nbImage, uint32_t hh, uint32_t mm, uint32_t ss)
{
        uint32_t tim;
	#define  GUI_UPDATE_RATE 1000

	tim=clock.getElapsedMS();
	if(tim>_nextUpdate)
	{
        char string[256];
        double f;
        	uint32_t   tom,zhh,zmm,zss,zmms;

		_nextUpdate=tim+GUI_UPDATE_RATE;
        sprintf(string,"%02d:%02d:%02d",hh,mm,ss);
        dialog->setTime(string);
        

        sprintf(string,QT_TRANSLATE_NOOP("indexing","# Images :%0"PRIu32),nbImage);
        dialog->setImage(string);

        f=done;
        f/=total;

        dialog->setPercent(f);

        /* compute ETL */
       // Do a simple relation between % and time
        // Elapsed time =total time*percent
        if(f<0.01) return 1;
        f=tim/f;
        // Tom is total time
        tom=(uint32_t)floor(f);
        if(tim>tom) return 1;
        tom=tom-tim;
        ms2time(tom,&zhh,&zmm,&zss,&zmms);
        sprintf(string,QT_TRANSLATE_NOOP("indexing","Time Left :%02d:%02d:%02d"),zhh,zmm,zss);
        dialog->setETA(string);
        UI_purge();
        }
        return 1;
}
uint8_t       DIA_progressIndexing::update(uint32_t done,uint32_t total, uint32_t nbImage, uint32_t hh, uint32_t mm, uint32_t ss)
{
        uint32_t tim;
	#define  GUI_UPDATE_RATE 1000

	tim=clock.getElapsedMS();
	if(tim>_nextUpdate)
	{
        char string[256];
        double f;
        	uint32_t   tom,zhh,zmm,zss;

		_nextUpdate=tim+GUI_UPDATE_RATE;
        sprintf(string,"%02d:%02d:%02d",hh,mm,ss);
        gtk_label_set_text(GTK_LABEL(WID(labelTime)),string);

        sprintf(string,"%0lu",nbImage);
        gtk_label_set_text(GTK_LABEL(WID(labelNbImage)),string);

        f=done;
        f/=total;

        gtk_progress_set_percentage(GTK_PROGRESS(WID(progressbar1)),(gfloat)f);

        /* compute ETL */
       // Do a simple relation between % and time
        // Elapsed time =total time*percent
        if(f<0.01) return 1;
        f=tim/f;
        // Tom is total time
        tom=(uint32_t)floor(f);
        if(tim>tom) return 1;
        tom=tom-tim;
        ms2time(tom,&zhh,&zmm,&zss);
        sprintf(string,"%02d:%02d:%02d",zhh,zmm,zss);
        gtk_label_set_text(GTK_LABEL(WID(label6)),string);
        	UI_purge();
	}
        return 1;
}
uint8_t DIA_working::update(uint32_t percent)
{
		#define GUI_UPDATE_RATE 1000

        UI_purge();

        if(!_priv) return 1;
        if(!percent) return 0;
        if(percent==lastper)
        {

            return 0;
        }

        elapsed=_clock.getElapsedMS();

        if(elapsed<_nextUpdate) 
        {
          return 0;
        }

        _nextUpdate=elapsed+1000;
        lastper=percent;

		uint32_t hh,mm,ss;
		char string[9];

		ms2time(elapsed,&hh,&mm,&ss);
		sprintf(string,"%02d:%02d:%02d",hh,mm,ss);

        workWindow *wind=(workWindow *)_priv; ADM_assert(wind);
        wind->ui.labelTimeLeft->setText(ms2timedisplay((uint32_t) floor(((elapsed * 100.) / percent) - elapsed)));
		wind->ui.labelElapsed->setText(string);
        wind->ui.progressBar->setValue(percent);
       
        return 0;
}
uint8_t     OneTrack::dump(uint32_t number,FILE *fdIdx, FILE *fdSub,uint32_t *out)
{
    uint16_t hh,mm,ss,ms;
    uint32_t timestamp;
    uint32_t original,position;
    original=ftello(fdSub); // Current position, we start from here
      
    if(!index) return 1;
  
    fwrite(base,index,1,fdSub); // Append our datas
    
    
    fprintf(fdIdx,"# English\n");
    fprintf(fdIdx,"id: %c%c, index: %d\n",language[0],language[1],number);
    fprintf(fdIdx,"# Decomment next line to activate alternative name in DirectVobSub / Windows Media Player 6.x\n");
    fprintf(fdIdx,"# alt: English\n");
    fprintf(fdIdx,"# Vob/Cell ID: 1, 1 (PTS: 0)\n");
    (*out)++;
    for(int i=0;i<nbLines;i++) // We shift PTS & position by 1 to workaround the display bug
    {   
        if(lines[i].pts!=ADM_NO_PTS)
        {     
            timestamp=(uint32_t)floor(lines[i].pts/90.);
            ms2time(timestamp,&hh,&mm,&ss,&ms);
            position=lines[i].start;
            //printf("Stream :%d position :%x offset:%x total:%x\n",i,position,original,original+position);
            position+=original;          
            fprintf(fdIdx,"timestamp: %02d:%02d:%02d:%03d, filepos: %08x\n",hh,mm,ss,ms,position); 
        }
        else
        {
                printf("Sub %d, skipped line at %d\n",number,i);
        }
    }
    return 1;
}
uint8_t       DIA_progressIndexing::update(uint32_t done,uint32_t total, uint32_t nbImage, uint32_t hh, uint32_t mm, uint32_t ss)
{
        uint32_t tim;
	#define  GUI_UPDATE_RATE 1000

	tim=clock.getElapsedMS();
	if(tim>_nextUpdate)
	{
        double f;
        	uint32_t   tom,zhh,zmm,zss;

		_nextUpdate=tim+GUI_UPDATE_RATE;
        dialog->setTime(QString(QApplication::translate("IndexDialog", "%1:%2:%3").arg(hh, 2, 10, QLatin1Char('0')).arg(mm, 2, 10, QLatin1Char('0')).arg(ss, 2, 10, QLatin1Char('0'))));
		dialog->setImage(QString(QApplication::translate("IndexDialog", "# Images: %1")).arg(nbImage));

        f=done;
        f/=total;

        dialog->setPercent(f);

        /* compute ETL */
       // Do a simple relation between % and time
        // Elapsed time =total time*percent
        if(f<0.01) return 1;
        f=tim/f;
        // Tom is total time
        tom=(uint32_t)floor(f);
        if(tim>tom) return 1;
        tom=tom-tim;
        ms2time(tom,&zhh,&zmm,&zss);

        dialog->setETA(QString(QApplication::translate("IndexDialog", "Time Left: %1:%2:%3")).arg(zhh, 2, 10, QLatin1Char('0')).arg(zmm, 2, 10, QLatin1Char('0')).arg(zss, 2, 10, QLatin1Char('0')));
        UI_purge();
        }
        return 1;
}
void DIA_properties( void )
{

 char text[80];
 uint16_t hh, mm, ss, ms;
 GtkWidget *dialog;
 uint8_t gmc, qpel,vop;
 uint32_t info=0;
 const char *yesno[2]={QT_TR_NOOP("No"),QT_TR_NOOP("Yes")};
 uint32_t war,har;

    if (playing)
        return;
  
    text[0] = 0;
    if (!avifileinfo)
        return;
  
        // Fetch info
        info=video_body->getSpecificMpeg4Info();
        vop=!!(info & ADM_VOP_ON);
        qpel=!!(info & ADM_QPEL_ON);
        gmc=!!(info & ADM_GMC_ON);
        
        dialog = create_dialog1();

        gtk_register_dialog(dialog);

        sprintf(text, QT_TR_NOOP("%lu x %lu"), avifileinfo->width,avifileinfo->height);
        FILL_ENTRY(label_size);

        sprintf(text, QT_TR_NOOP("%2.3f fps"), (float) avifileinfo->fps1000 / 1000.F);
        FILL_ENTRY(label_fps);

        sprintf(text, QT_TR_NOOP("%ld frames"), avifileinfo->nb_frames);
        FILL_ENTRY(label_number);

        sprintf(text, "%s", fourCC::tostring(avifileinfo->fcc));
        FILL_ENTRY(label_videofourcc);

        if (avifileinfo->nb_frames)
          {
                frame2time(avifileinfo->nb_frames, avifileinfo->fps1000,
                          &hh, &mm, &ss, &ms);
                sprintf(text, QT_TR_NOOP("%02d:%02d:%02d.%03d"), hh, mm, ss, ms);
                FILL_ENTRY(label_duration);	
  
          }
        // Fill in vop, gmc & qpel
        SET_YES(labelPacked,vop);
        SET_YES(labelGMC,gmc);
        SET_YES(labelQP,qpel);
        // Aspect ratio 
        const char *s;
        war=video_body->getPARWidth();
        har=video_body->getPARHeight();
        getAspectRatioFromAR(war,har, &s);
        sprintf(text, QT_TR_NOOP("%s (%u:%u)"), s,war,har);
        FILL_ENTRY(labelAspectRatio);	
        // Now audio
        WAVHeader *wavinfo=NULL;
        if (currentaudiostream) wavinfo=currentaudiostream->getInfo();
          if(wavinfo)
          {
              
              switch (wavinfo->channels)
                {
                case 1:
                    sprintf(text, QT_TR_NOOP("Mono"));
                    break;
                case 2:
                    sprintf(text, QT_TR_NOOP("Stereo"));
                    break;
                default:
                    sprintf(text, "%d",wavinfo->channels);
                    break;
                }
                FILL_ENTRY(label1_audiomode);
              
                sprintf(text, QT_TR_NOOP("%lu Hz"), wavinfo->frequency);
                FILL_ENTRY(label_fq);
                sprintf(text, QT_TR_NOOP("%lu Bps / %lu kbps"), wavinfo->byterate,      wavinfo->byterate * 8 / 1000);
                FILL_ENTRY(label_bitrate);
                sprintf(text, "%s", getStrFromAudioCodec(wavinfo->encoding));
                FILL_ENTRY(label1_audiofourcc);
                // Duration in seconds too
                if(currentaudiostream && wavinfo->byterate>1)
                {
                        uint32_t l=currentaudiostream->getLength();
                        double du;
                        du=l;
                        du*=1000;
                        du/=wavinfo->byterate;
                        ms2time((uint32_t)floor(du), &hh, &mm, &ss, &ms);
                        sprintf(text, QT_TR_NOOP("%02d:%02d:%02d.%03d"), hh, mm, ss, ms);
						FILL_ENTRY(label_audioduration);

						sprintf(text, QT_TR_NOOP("%.2f MB"), l / 1048576.F);
						FILL_ENTRY(labelFileSize);
                }                
                SET_YES(labelVbr, currentaudiostream->isVBR());
        } else
          {
			  DISABLE_WIDGET(frame2);
          }
  
        gtk_dialog_run(GTK_DIALOG(dialog));	
        gtk_unregister_dialog(dialog);
        gtk_widget_destroy(dialog);
}
void DIA_encoding::setFrame(uint32_t nb,uint32_t total)
{
	uint32_t tim;
#define  ETA_SAMPLE_PERIOD 60000 //Use last n millis to calculate ETA
#define  GUI_UPDATE_RATE 500  
  static uint32_t _lastnb=0;

	   ADM_assert(dialog);
     	   //
           //	nb/total=timestart/totaltime -> total time =timestart*total/nb
           //
           //
    
           if(nb < _lastnb || _lastnb == 0) // restart ?
           {
             _lastnb = nb;
                                       
					clock.reset();
		_lastTime=clock.getElapsedMS();
       					_lastFrame=0;
       					_fps_average=0;

                _nextUpdate = _lastTime + GUI_UPDATE_RATE;
                _nextSampleStartTime=_lastTime + ETA_SAMPLE_PERIOD;
                _nextSampleStartFrame=0;
                                        if(tray)
                                                tray->setPercent(0);
					  UI_purge();
					  return;
	  }
             _lastnb = nb;

	tim=clock.getElapsedMS();
	//   printf("%lu / %lu\n",tim,_lastTime);
	   if(_lastTime > tim) return;
	   if( tim < _nextUpdate) return ; 
     _nextUpdate = tim+GUI_UPDATE_RATE;

	sprintf(string,"%lu/%lu",nb,total);
	gtk_label_set_text(GTK_LABEL(WID(label_frame)),string);

	   	// compute fps
		uint32_t deltaFrame, deltaTime;
		deltaTime=tim-_lastTime;
		deltaFrame=nb-_lastFrame;

			sprintf(string,"%lu",(uint32_t)( deltaFrame*1000.0 / deltaTime ));
   			gtk_label_set_text(GTK_LABEL(WID(label_fps)),string);
                        



		uint32_t   hh,mm,ss;

          double framesLeft=(total-nb);
					ms2time((uint32_t)floor(0.5+deltaTime*framesLeft/deltaFrame),&hh,&mm,&ss);
					sprintf(string,"%02d:%02d:%02d",hh,mm,ss);
					gtk_label_set_text(GTK_LABEL(WID(label_eta)),string);

           // Check if we should move on to the next sample period
          if (tim >= _nextSampleStartTime + ETA_SAMPLE_PERIOD ) {
            _lastTime=_nextSampleStartTime;
            _lastFrame=_nextSampleStartFrame;
            _nextSampleStartTime=tim;
            _nextSampleStartFrame=0;
          } else if (tim >= _nextSampleStartTime && _nextSampleStartFrame == 0 ) {
            // Store current point for use later as the next sample period.
            //
            _nextSampleStartTime=tim;
            _nextSampleStartFrame=nb;
          }
		// update progress bar
		 float f=nb;
		 f=f/total;
                if(tray)
                        tray->setPercent((int)(f*100.));
		gtk_progress_set_percentage(GTK_PROGRESS(WID(progressbar1)),(gfloat)f);

		sprintf(string,"Done : %02d%%",(int)(100*f));
                if(isQuiet()) printf("[Encoding]%s\n",string);
		   gtk_progress_bar_set_text       (GTK_PROGRESS_BAR(WID(progressbar1)), string);
		

	   	UI_purge();

}
//**********************************************
uint8_t ADM_vob2vobsub(char *nameVob, char *nameVobSub, char *nameIfo)
{
   dmx_demuxerPS *demuxer=NULL;
   DIA_working *working=NULL;
   MPEG_TRACK track;
   FILE *indexFile=NULL;
   FILE *indexSub=NULL;
   uint32_t palette[16],width,height;
   uint64_t abs,rel,size,pts;
   int blockSize;
   uint8_t *data,stream;
   char *subname;
   double percent;
   uint32_t packetLen,usedLen,read;
   OneTrack allIndex[MAX_LANGUAGE];
   char language[MAX_LANGUAGE*4];
#ifdef  TEST_V2V  
   nameIfo="d:/Crime/VTS_01_0.IFO";
   nameVobSub="toto.idx";
#endif
   
        printf("v2v: Ifo:%s Vob:%s Vsub:%s\n",nameIfo,nameVob,nameVobSub);

   memset(language,0,sizeof(language));
   memset(palette,0,sizeof(uint32_t)*16);
   if(!vobsub_parse_ifo(nameIfo,palette,&width,&height,language))
   {
     GUI_Error_HIG(QT_TR_NOOP("Ifo error"),QT_TR_NOOP("Error reading ifo file, aborting."));   
        return 0;
   } 
   printf("Ifo: %d x %d\n",width,height);                 
   
   indexFile=fopen(nameVobSub,"wt");
   if(!indexFile)
   {
     GUI_Error_HIG(QT_TR_NOOP("Cannot write .idx"),NULL);              
        return 0;
    }
   subname=ADM_strdup(nameVobSub);
   size=strlen(subname);
   subname[size-3]='s';
   subname[size-2]='u';
   subname[size-1]='b';
   indexSub=fopen(subname,"wb");
   ADM_dealloc(subname);
    if(!indexSub)
    {
        fclose(indexFile);
        GUI_Error_HIG(QT_TR_NOOP("Cannot write .sub"),NULL);
        return 0;
    }
   for(int i=0;i<MAX_LANGUAGE;i++)
   {
         allIndex[i].setLang(language+i*3);  
   }
   track.pes=0x20;
   track.pid=track.pes;
   demuxer=new  dmx_demuxerPS(1,&track,1);
   if(!demuxer->open(nameVob))
   {
     GUI_Error_HIG(QT_TR_NOOP("Problem opening the mpeg files"),NULL);
        delete demuxer;
        fclose(indexFile);
        fclose(indexSub);
        return 0;   
   }
   
   
   size=demuxer->getSize();
   
    int display=0;
    
   dumpHeader(indexFile,0,width,height,palette);
   working=new DIA_working(QT_TR_NOOP("Generating VobSub file"));
   
   //*** Main Loop ***
   uint32_t startPts=0,lastPts=0;
   uint16_t hh,mm,ss,ms;
   uint32_t timestamp;
   while(1)
   {
       if(!demuxer->forceRefill(&stream)) goto _abt;
       demuxer->getPos(&abs,&rel);
       display++;
       if(display>20)
       {
        working->update(abs>>10,size>>10);
        display=0;
       }
#ifdef TEST_V2V       
       //if(abs>200*1024*1024) break;
#endif       
       if(stream>=0x20 && stream<0x20+MAX_LANGUAGE)
       {
            demuxer->getPacketInfo(&data,&packetLen,&usedLen,&pts);
            if(pts!=ADM_NO_PTS)
            {
                        // Wrap around ?
                        if(lastPts)
                        {
                                if(pts<lastPts)
                                {
                                        if(lastPts-pts>MIN_WRAP_VALUE)
                                        {
                                                
                                                printf("Wrapping at %u ",lastPts);
                                                startPts+=lastPts;
                                                timestamp=startPts/90;
                                                ms2time(timestamp,&hh,&mm,&ss,&ms);
                                                printf("%02d:%02d:%02d \n",hh,mm,ss);
                                        }
                                }
                        }

                        lastPts=pts;
                        pts+=startPts;
            }
#if 0
            if(pts!=ADM_NO_PTS)
            {
              timestamp=pts/90;
              ms2time(timestamp,&hh,&mm,&ss,&ms);
              printf("%02d:%02d:%02d \n",hh,mm,ss);
            }
#endif
            blockSize=demuxer->read16i();
            allIndex[stream-0x20].run(blockSize,data,packetLen,usedLen, pts)  ;
       }
    }
void DIA_encoding::updateUI(void)
{
uint32_t tim;

	   ADM_assert(dialog);
     	   //
           //	nb/total=timestart/totaltime -> total time =timestart*total/nb
           //
           //
          if(!_lastnb) return;
          
          tim=clock.getElapsedMS();
          if(_lastTime > tim) return;
          if( tim < _nextUpdate) return ; 
          _nextUpdate = tim+GUI_UPDATE_RATE;
  
          sprintf(string,"%lu",_lastnb);
          gtk_label_set_text(GTK_LABEL(WID(label_frame)),string);

		  sprintf(string,"%lu",_total);
		  gtk_label_set_text(GTK_LABEL(WID(label_totalframe)),string);

          // Average bitrate  on the last second
          uint32_t sum=0,aquant=0,gsum;
          for(int i=0;i<_roundup;i++)
          {
            sum+=_bitrate[i].size;
            aquant+=_bitrate[i].quant;
          }
          
          aquant/=_roundup;

          sum=(sum*8)/1000;

          // Now compute global average bitrate
          float whole=_videoSize,second;
            second=_lastnb;
            second/=_fps1000;
            second*=1000;
           
          whole/=second;
          whole/=1000;
          whole*=8;
      
          gsum=(uint32_t)whole;

          setBitrate(sum,gsum);
          setQuantIn(aquant);

          // compute fps
          uint32_t deltaFrame, deltaTime;
          deltaTime=tim-_lastTime;
          deltaFrame=_lastnb-_lastFrame;

          _fps_average    =(float)( deltaFrame*1000.0F / deltaTime ); 

          sprintf(string,"%.2f",_fps_average);
          gtk_label_set_text(GTK_LABEL(WID(label_fps)),string);
  
          uint32_t   hh,mm,ss;
  
            double framesLeft=(_total-_lastnb);

			ms2time(tim,&hh,&mm,&ss);
			sprintf(string,"%02d:%02d:%02d",hh,mm,ss);
			gtk_label_set_text(GTK_LABEL(WID(label_elapsed)),string);

			gtk_label_set_text(GTK_LABEL(WID(label_eta)), ms2timedisplay((uint32_t) floor(0.5 + deltaTime * framesLeft / deltaFrame)));
 
           // Check if we should move on to the next sample period
          if (tim >= _nextSampleStartTime + ETA_SAMPLE_PERIOD ) {
            _lastTime=_nextSampleStartTime;
            _lastFrame=_nextSampleStartFrame;
            _nextSampleStartTime=tim;
            _nextSampleStartFrame=0;
          } else if (tim >= _nextSampleStartTime && _nextSampleStartFrame == 0 ) {
            // Store current point for use later as the next sample period.
            //
            _nextSampleStartTime=tim;
            _nextSampleStartFrame=_lastnb;
          }
          // update progress bar
            float f=_lastnb;
            f=f/_total;
          if(tray)
                  tray->setPercent((int)(f*100.));
          gtk_progress_set_percentage(GTK_PROGRESS(WID(progressbar1)),(gfloat)f);

          sprintf(string,QT_TR_NOOP("%d%%"),(int)(100*f));
          
          if(isQuiet()) printf("[Encoding]%s\n",string);
              gtk_progress_bar_set_text       (GTK_PROGRESS_BAR(WID(progressbar1)), string);
          
        _totalSize=_audioSize+_videoSize;
        setSize(_totalSize>>20);
        setAudioSizeIn((_audioSize>>20));
        setVideoSizeIn((_videoSize>>20));
        UI_purge();

}
void DIA_encoding::setFrame(uint32_t nb,uint32_t total)
{
	uint32_t tim;

	   assert(dialog);
	   sprintf(string,"%lu/%lu",nb,total);
  	   gtk_label_set_text(GTK_LABEL(WID(label_frame)),string);
     	   //
           //	nb/total=timestart/totaltime -> total time =timestart*total/nb
           //
           //

           if(nb==0) // restart ?
           {
					clock.reset();
       					_lastTime=clock.getElapsedMS();;
       					_lastFrame=0;
       					_fps_average=0;
					  UI_purge();
					  return;
	  }

           tim=clock.getElapsedMS();;
	//   printf("%lu / %lu\n",tim,_lastTime);
	   if(_lastTime > tim) return;
	   if( tim-_lastTime < 1000) return ; // refresh every 3  seconds

           if(tim)
           {
	   	double d;
		uint32_t fps;

	   	// compute fps
		uint32_t deltaFrame, deltaTime;
		deltaTime=tim-_lastTime;
		deltaFrame=nb-_lastFrame;
		if(deltaTime>500)
		{
			d=deltaTime;
			d=1/d;
			d*=deltaFrame;
			d*=1000.;
			fps=(uint32_t)floor(d);
			sprintf(string,"%lu",fps);
   			gtk_label_set_text(GTK_LABEL(WID(label_fps)),string);

		}


	   	uint32_t sectogo,secdone;
		uint32_t   hh,mm,ss;

	  				secdone = tim;
			 	  	d = secdone;
	  				d /= nb;
       					d*=total;
	  				d -= secdone;
					_lastTime=tim;
					tim=(uint32_t)floor(d);
					ms2time(tim,&hh,&mm,&ss);
					sprintf(string,"%02d:%02d:%02d",hh,mm,ss);
					gtk_label_set_text(GTK_LABEL(WID(label_eta)),string);

              }

		// update progress bar
		 float f=nb;
		 f=f/total;
		gtk_progress_set_percentage(GTK_PROGRESS(WID(progressbar1)),(gfloat)f);

		_lastFrame=nb;

	   	UI_purge();

}
void DIA_encoding::updateUI(void)
{
uint32_t   tim;
uint32_t   hh,mm,ss;
uint32_t   cur,max;
uint32_t   percent;
          //
           //	nb/total=timestart/totaltime -> total time =timestart*total/nb
           //
           //
          if(!_lastnb) return;
          
          tim=clock.getElapsedMS();
          if(_lastTime > tim) return;
          if( tim < _nextUpdate) return ; 
          _nextUpdate = tim+GUI_UPDATE_RATE;
          // Average bitrate  on the last second
          uint32_t sum=0,aquant=0,gsum;
          for(int i=0;i<_roundup;i++)
          {
            sum+=_bitrate[i].size;
            aquant+=_bitrate[i].quant;
          }
          
          aquant/=_roundup;

          sum=(sum*8)/1000;

          // Now compute global average bitrate
          float whole=_videoSize,second;
            second=_lastnb;
            second/=_fps1000;
            second*=1000;
           
          whole/=second;
          whole/=1000;
          whole*=8;
      
          gsum=(uint32_t)whole;

          setBitrate(sum,gsum);
          setQuantIn(aquant);

          // compute fps
          uint32_t deltaFrame, deltaTime;
          deltaTime=tim-_lastTime;
          deltaFrame=_lastnb-_lastFrame;

          _fps_average    =(uint32_t)( deltaFrame*1000.0 / deltaTime ); 
  
  
            double framesLeft=(_total-_lastnb);
            ms2time((uint32_t)floor(0.5+deltaTime*framesLeft/deltaFrame),&hh,&mm,&ss);
  
           // Check if we should move on to the next sample period
          if (tim >= _nextSampleStartTime + ETA_SAMPLE_PERIOD ) {
            _lastTime=_nextSampleStartTime;
            _lastFrame=_nextSampleStartFrame;
            _nextSampleStartTime=tim;
            _nextSampleStartFrame=0;
          } else if (tim >= _nextSampleStartTime && _nextSampleStartFrame == 0 ) {
            // Store current point for use later as the next sample period.
            //
            _nextSampleStartTime=tim;
            _nextSampleStartFrame=_lastnb;
          }
          // update progress bar
            float f=_lastnb;
            f=f/_total;
            percent=(int)(100*f);
        
            _totalSize=_audioSize+_videoSize;
          setSize(_totalSize>>20);
          setAudioSizeIn((_audioSize>>20));
          setVideoSizeIn((_videoSize>>20));

          fprintf(stderr,"Done:%u%% Frames: %u/%u ETA: %02u:%02u:%02u\r",percent,_lastnb,_total,hh,mm,ss);

}
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++
        Main
   +++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
uint8_t ADM_ocr_engine( void)
{
// 
    uint32_t nbSub=0;
    FILE *out=NULL;
    head.next=NULL;
    ADMVideoVobSub *vobsub=NULL;
    uint32_t startTime,endTime;
    uint32_t w,h,oldw=0,oldh=0;
    uint32_t oldbitmapw=0;
    uint32_t oldbitmaph=0;
    uint32_t first,last;
    uint32_t seqNum;
    char     text[1024];
    lang_index=0;
    nbGlyphs=0;
    ReplyType reply;
    
// Create UI && prepare callback
    
    dialog=DIA_ocr();
    gtk_register_dialog(dialog);
#define ASSOCIATE(x,y)   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y)
    ASSOCIATE(buttonStart,actionGo);
    ASSOCIATE(buttonOk,   actionAccept);
    ASSOCIATE(buttonSkip,     actionSkip);
    ASSOCIATE(buttonSkipAll,     actionSkipAll);
    ASSOCIATE(buttonIgnore,   actionIgnore);
    ASSOCIATE(buttonCalibrate,   actionCalibrate);
    
    ASSOCIATE(buttonGlyphLoad,   actionLoadGlyph);
    ASSOCIATE(buttonGlyphSave,   actionSaveGlyph);
    
    ASSOCIATE(buttonVobsub,   actionLoadVob);
    ASSOCIATE(buttonSrt,   actionSaveSub);
   
    gtk_widget_show(dialog);
//  disable
    
    mainDisplay=WID(drawingareaBitmap);
    smallDisplay=WID(drawingareaSmall);
    
    CONNECT(drawingareaBitmap,expose_event,gui_draw);
    CONNECT(drawingareaSmall,expose_event,gui_draw_small);

    CONNECT(entry,activate,cb_accept);
_again:    
    reply=setup();
    if(reply==ReplyClose) goto endIt;
    
    printf("Go go go\n");
    
    // Everything ready go go go 
         
    redraw_x=redraw_y=0;
    GTK_PURGE;
//  Time to go
    // Inactivate frame1=glyph    frame2=in/out  buttonStart
    gtk_widget_set_sensitive(WID(buttonStart),0);
    gtk_widget_set_sensitive(WID(frameGlyph),0);
    gtk_widget_set_sensitive(WID(frameLoad),0);
    gtk_widget_set_sensitive(WID(frameBitmap),1);

    gtk_widget_set_sensitive(WID(buttonStart),0);
   
  
   char *fileout;
   fileout=(char *)gtk_label_get_text(GTK_LABEL(WID(labelSrt)));
   if(!fileout)
    {
      GUI_Error_HIG(_("Incorrect output file"), NULL);
        goto _again;
    }
    out=fopen(fileout,"wb");
    if(!out)
    {
      GUI_Error_HIG(_("Output file error"), _("Could not open \"%s\" for writing."), fileout);
        goto _again;
    }
     
    vobsub=new ADMVideoVobSub(subparam.subname,subparam.index);
    nbSub=vobsub->getNbImage();
   
    if(!nbSub)
    {
      GUI_Error_HIG(_("Problem loading sub"), NULL);
        delete vobsub;
        vobsub=NULL;
        goto _again;
     }
    seqNum=1;   // Sub number in srt file
    oldw=oldh=0;

    //******************    
    // Load all bitmaps
    //******************
    for(uint32_t i=0;i<nbSub;i++)
    {
            first=last=0;
            bitmap=vobsub->getBitmap(i,&startTime, &endTime,&first,&last);
            ADM_assert(last>=first);
            
            // something ?
            if(!bitmap) continue;
            if(first==last) continue;

            // If the bitmap size changed or does not exist yet...
            if(!workArea || oldbitmapw!=bitmap->_width || oldbitmaph!=bitmap->_height)
            {
              if(workArea) 
              {
                delete [] workArea;
                workArea=NULL; 
              }
              // Workarea is actually bigger than what we use
              workArea=new uint8_t[bitmap->_width*(bitmap->_height)];
              memset(workArea,0,bitmap->_width*(bitmap->_height));
            }
            oldbitmaph=bitmap->_height;
            oldbitmapw=bitmap->_width;
           // 
           w=bitmap->_width;
           h=last-first+1;
           redraw_x=w;
           redraw_y=h;
           //**
           
           // Build
againPlease:
           mergeBitmap(bitmap->_bitmap+first*w, workArea, bitmap->_alphaMask+first*w,  w,   h);
           if(oldw!=w || oldh !=h)
           {                
                GTK_PURGE;  // Force redaw
           }
           // Merge
             GTK_PURGE;
             gui_draw();
             GTK_PURGE; 
             // OCR
              reply=ocrBitmap(workArea,w,h);
              if(reply==ReplyClose) goto endIt;
              if(reply==ReplyCalibrate)
                {
                        //
                        //printf("TADA!!!!\n");
                        int val;
#if 0
                         val=minAlpha;
                        if(DIA_GetIntegerValue(&val, 3, 7, "Minimum alpha value", "Enter new minimum alpha"))
                        {
                                minAlpha=val;

                        }
#endif
                        val=minThreshold;
                        if(DIA_GetIntegerValue(&val, 0x30, 0x80, "Minimum pixel value", "Enter new minimum pixel"))
                        {
                                minThreshold=val;

                        }
                        goto againPlease;
                }
             
             //
             gtk_label_set_text(GTK_LABEL(WID(labelText)),decodedString);
             fprintf(out,"%d\n",seqNum++);
             uint16_t hh,mm,ss,ms;
             ms2time(startTime, &hh, &mm, &ss, &ms);
             fprintf(out,"%02d:%02d:%02d,%03d --> ",hh,mm,ss,ms);
             ms2time(endTime, &hh, &mm, &ss, &ms);
             fprintf(out,"%02d:%02d:%02d,%03d\n",hh,mm,ss,ms);
             fprintf(out,"%s\n\n",decodedString);
             //             
             oldw=w;
             oldh=h;
             // Update infos
             sprintf(text,"%03d/%03d",i+1,nbSub);
             gtk_label_set_text(GTK_LABEL(WID(labelNbLines)),text);
             sprintf(text,"%03d",nbGlyphs);
             gtk_label_set_text(GTK_LABEL(WID(labelNbGlyphs)),text);
    }

endIt:
    // Final round
    gtk_widget_set_sensitive(WID(frameGlyph),1);
    gtk_widget_set_sensitive(WID(frameLoad),0);
    gtk_widget_set_sensitive(WID(buttonStart),0);  
    gtk_widget_set_sensitive(WID(frameBitmap),0);
   // gtk_widget_set_sensitive(WID(Current_Glyph),0); 
    
    if(nbGlyphs && actionSaveGlyph==gtk_dialog_run(GTK_DIALOG(dialog)))
        saveGlyph();
    if(vobsub)
        delete vobsub;
    vobsub=NULL;
    if(out) 
        fclose(out);
    out=NULL;
    gtk_unregister_dialog(dialog);
    gtk_widget_destroy(dialog);
    if(head.next)
        destroyGlyphTree(&head);
    head.next=NULL;
    return 1;

}