/**
      \fn parseMvhd
      \brief Parse mvhd header
*/
void MP4Header::parseMvhd(void *ztom)
{
	adm_atom *tom = (adm_atom*)ztom;
	int version = tom->read();

	tom->skipBytes(3);	// flags

	if (version == 1)
		tom->skipBytes(16);
	else
		tom->skipBytes(8);

	int scale = tom->read32();
	uint64_t duration = (version == 1) ? tom->read64() : tom->read32();

	_videoScale = scale;

	printf("Warning: scale is not in ms %lu!\n", _videoScale);

	if (_videoScale)
	{
		duration = 1000 * duration; // In ms
		duration /= _videoScale;
	}
	else
		_videoScale = 1000;

	printf("Movie duration: %s\n", ms2timedisplay(duration));

	_movieDuration = duration;
}
Esempio n. 2
0
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;
}
/**
      \fn parseMvhd
      \brief Parse mvhd header
*/
void MP4Header::parseMvhd(void *ztom)
{
  adm_atom *tom=(adm_atom *)ztom;
  tom->skipBytes(12);
  uint32_t scale,duration=1000;
  
        scale=tom->read32();
        duration=tom->read32();
        _videoScale=scale;
        printf("Warning : scale is not in ms %lu !\n",_videoScale);
        if(_videoScale)
        {
                        duration=1000*duration; // In ms
                        duration/=_videoScale;
        }else
          _videoScale=1000;
        printf("Movie duration :%s\n",ms2timedisplay(duration));
        _movieDuration=duration;
}
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 ADM_Composer::getAudioPacket(uint8_t *dest, uint32_t *len, uint32_t *samples)
{
uint8_t r;	
uint32_t ref; 
_VIDEOS *currentVideo;
	currentVideo=&_videos[AUDIOSEG];
	
	if(_audioSample<_segments[_audioseg]._audio_duration)
	{
                if( !currentVideo->_audiostream)
                {
                        printf("No soundtrack");        
                        *len=0;
                        *samples=0;
                        return 0;
                }
		r=currentVideo->_audiostream->getPacket(dest,len,samples);
		if(r)
		{
			// ok we update the current sample count and go on
			_audioSample+=*samples;
			return r;		
		}
		// could not get the cound, rewind and retry
		printf("EditorPacket:Read failed; retrying (were at seg %u"   ,_audioseg);
                printf("sample %u\n",_audioSample); // FIXME use proper stuff
                printf("/ %d)\n",_segments[_audioseg]._audio_duration);
		if(_audioseg == (_nb_segment - 1))
		{		
			printf("EditorPacket : End of *last* stream\n");
			return 0;
		}
                // If we get here, it means we have less audio that it should   
                // In the current segment. Generally we repeat the segment
                // Except if the missing data is less than 20 ms, we will compensate later
                float drift;

                drift=(float)_segments[_audioseg]._audio_duration;
                drift-=(float)_audioSample;
                drift/=(float)currentVideo->_audiostream->getInfo()->frequency;
                drift*=1000.;
                printf("Seg :%u, Drop %3.3f ms\n",_audioseg,drift);
                if(drift>10.)
                {
                        printf("Drop too high, filling...\n");
                        currentVideo->_audiostream->goToTime(0);
                        r=currentVideo->_audiostream->getPacket(dest,len,samples);
                        if(r)
                        {
                                printf("Filled with data from beginning (%u bytes %u samples)\n",*len,*samples);
                                // read it again sam
                                _audioSample+=*samples;
                        }
                        return r;
                }
	}
	// We have to switch seg
	// We may have overshot a bit, but...
	
	// this is the end ?
	if(_audioseg == (_nb_segment - 1))
	{
		
		printf("EditorPacket : End of stream Segment :%u/%u \n",_audioseg,_nb_segment);
                printf("This sample : %u (%s) ",_audioSample,ms2timedisplay(1000*_audioSample/currentVideo->_audiostream->getInfo()->frequency));
                printf("total :%u (%s)\n" ,_segments[_audioseg]._audio_duration,ms2timedisplay(1000*_segments[_audioseg]._audio_duration/currentVideo->_audiostream->getInfo()->frequency));
		return 0;
	}
	// switch segment
	// We adjust the audiosample to avoid adding cumulative shift
        uint8_t ret;
        int64_t adjust=_audioSample-=_segments[_audioseg]._audio_duration;

        if(adjust>0) _audioSample=adjust;
	       else  _audioSample=0;
	_audioseg++;
	// Next audio seg has audio ?
        
	// Compute new start time
	uint32_t starttime;
	if(!_videos[AUDIOSEG]._audiostream)
        {
                printf("No soundtrack\n");
                *len=0;
                *samples=0;
               // _audioseg--; // Stay in a valid one to avoid crash later
                return 0;
        }
	starttime= _videos[AUDIOSEG]._aviheader->getTime (_segments[_audioseg]._start_frame);
	_videos[AUDIOSEG]._audiostream->goToTime(starttime);	
	; // Fresh start samuel
	printf("EditorPacket : switching to segment %lu\n",_audioseg);
	ret= getAudioPacket(dest, len, samples);
        if(adjust<0)
        {
                adjust=-adjust;
                if(adjust>_audioSample) _audioSample=0;
                else _audioSample-=adjust;
        }
        return ret;
}
/**
      \fn parseMdia
      \brief Parse mdia header
*/
uint8_t MP4Header::parseMdia(void *ztom,uint32_t *trackType,uint32_t w, uint32_t h)
{
  adm_atom *tom=(adm_atom *)ztom;
  ADMAtoms id;
  uint32_t container;
  uint32_t trackScale=_videoScale;
  uint32_t trackDuration;
  *trackType=TRACK_OTHER;
  uint8_t r=0;
  printf("<<Parsing Mdia>>\n");
  while(!tom->isDone())
  {
     adm_atom son(tom);
     if(!ADM_mp4SearchAtomName(son.getFCC(), &id,&container))
     {
       adm_printf(ADM_PRINT_DEBUG,"[MDIA]Found atom %s unknown\n",fourCC::tostringBE(son.getFCC()));
       son.skipAtom();
       continue;
     }
     switch(id)
     {
       case ADM_MP4_MDHD:  
       {
                uint32_t version=son.read(),duration;
                son.skipBytes(3); // flags + version
                son.skipBytes(4); // creation time
                son.skipBytes(4); // mod time
                if(version==1) son.skipBytes(8);
                trackScale=son.read32(); //
                adm_printf(ADM_PRINT_DEBUG,"MDHD,Trackscale in mdhd:%u\n",trackScale);
                if(!trackScale) trackScale=600; // default
                duration=son.read32();
                adm_printf(ADM_PRINT_DEBUG,"MDHD,duration in mdhd:%u (unscaled)\n",duration);
                duration=(uint32_t)((duration*1000.)/trackScale);
                adm_printf(ADM_PRINT_DEBUG,"MDHD,duration in mdhd:%u (scaled ms)\n",duration);
                trackDuration=duration;
                printf("MDHD,Track duration :%s, trackScale :%u\n",ms2timedisplay((1000*duration)/trackScale),trackScale);
                break;
       }
       case ADM_MP4_HDLR:  
       {
            uint32_t type;
            
                son.read32();
                son.read32();
                type=son.read32();
                printf("[HDLR]\n");
                switch(type)
                {	
                case MKFCCR('v','i','d','e')://'vide':
                        *trackType=TRACK_VIDEO;
                        printf("hdlr video found \n ");
                        _movieDuration=trackDuration;
                        _videoScale=trackScale;
                        break;
                case MKFCCR('s','o','u','n'): //'soun':
                        *trackType=TRACK_AUDIO;
                        printf("hdlr audio found \n ");
                        break;
                case MKFCCR('u','r','l',' ')://'url ':
                    {
                        int s;
                        son.read32();
                        son.read32();
                        son.read32();
                        s=son.read();
                        char str[s+1];
                        son.readPayload((uint8_t *)str,s);
                        str[s]=0;
                        printf("Url : <%s>\n",str);
                      }
                      break;
                 
                }
                break;
       } 
       case ADM_MP4_MINF:  
       {
            // We are only interested in stbl
            
            while(!son.isDone())
            {
              adm_atom grandson(&son);
              if(!ADM_mp4SearchAtomName(grandson.getFCC(), &id,&container))
              {
                adm_printf(ADM_PRINT_DEBUG,"[MINF]Found atom %s unknown\n",fourCC::tostringBE(son.getFCC()));
                grandson.skipAtom();
                continue;
              }
              if(id==ADM_MP4_STBL)
              {
                   if(! parseStbl(&grandson,*trackType, w, h,trackScale))
                   {
                      printf("STBL failed\n");
                      return 0; 
                   }
                   r=1;
              }
              grandson.skipAtom();
        }
       }
       break;
        default:
            adm_printf(ADM_PRINT_DEBUG,"** atom  NOT HANDLED [%s] \n",fourCC::tostringBE(son.getFCC()));
     }
     
     son.skipAtom();
  }
  return r;
}
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();

}