//___________________________________
uint8_t  A_SaveAudioNVideo(const char *name)
{
     uint32_t needSmart=0,fl;
     GenericAviSave	*nw=NULL;
     aviInfo info;
     uint8_t ret=0;

     video_body->getVideoInfo(&info);

     printf("\n video process mode : %d",videoProcessMode());
     if (!videoProcessMode())
     {
          if(video_body->isMultiSeg()) needSmart=1;
                  video_body->getFlags(frameStart,&fl);
          if(!(fl&AVI_KEY_FRAME)) needSmart=1;

          if(needSmart) printf("\n probably need smart copy mode\n");
      
          if( !isMpeg4Compatible(  info.fcc)
                && !isMSMpeg4Compatible(info.fcc))
             {
                    printf("\n not encodable, cancelling smart mode\n");
                    needSmart=0;
               }


               int value=video_body->getEnv(ENV_EDITOR_SMART);
               nw=NULL;
               if(needSmart)
               {
                  if(value)
                  {
                     nw=new   GenericAviSaveSmart(3);
                  }
                  else
                  {
                    if(GUI_Question(QT_TR_NOOP("You may need smart copy.\n Enable it ?")))
                    {
                        value=4;
                        if( ! GUI_getIntegerValue(&value, 2, 31, "_Q factor (set 4):"))
                                      return 0;
                        nw=new   GenericAviSaveSmart(value);
                    }
                }
               }
              if(!nw)
                    nw=new   GenericAviSaveCopy;
               
       }
       else
       {

              printf("\n Process mode\n");
              nw=new   GenericAviSaveProcess;
        }
     ret=nw->saveAvi(name);
     delete nw;

return ret;
}
uint8_t prepareDualPass(uint8_t *buffer,char *TwoPassLogFile,DIA_encoding *encoding_gui,Encoder *_encode,uint32_t total)
{
      uint32_t len, flag;
      FILE *tmp;
      uint8_t reuse=0;
      ADMBitstream bitstream;

        aprintf("\n** Dual pass encoding**\n");

        if((tmp=fopen(TwoPassLogFile,"rt")))
        {
                fclose(tmp);
                if(GUI_Question(_("\n Reuse the existing log-file ?")))
                {
                        reuse=1;
                }
        }
        
        if(!reuse)
        {
        
                encoding_gui->setPhasis ("1st Pass");
                aprintf("**Pass 1:%lu\n",total);
                _encode->startPass1 ();
                bitstream.data=buffer;
                for (uint32_t cf = 0; cf < total; cf++)
                {
                        encoding_gui->setFrame (cf, total);
                        if (!encoding_gui->isAlive())
                        {
                                abt:
                                    GUI_Error_HIG (_("Aborting"), NULL);
                                return 0;
                        }
                        bitstream.cleanup(cf);
                        if (!_encode->encode (cf,&bitstream))// &len, buffer, &flag))
                        {
                                printf("\n Encoding of frame %lu failed !\n",cf);
                                return 0;
                        }
                        encoding_gui->setQuant(bitstream.out_quantizer);
                        encoding_gui->feedFrame(bitstream.len);                
                }
                encoding_gui->reset();
                aprintf("**Pass 1:done\n");
        }// End of reuse

        if(!_encode->startPass2 ())
        {
                printf("Pass2 ignition failed\n");
                return 0;
        }
        encoding_gui->setPhasis ("2nd Pass");
        return 1;
}
int A_Save( char *name)
{
uint32_t end;
	// depending on the type we save a avi, a mpeg or a XVCD
	CodecFamilty family;
	family= videoCodecGetFamily();
	// in case of copy mode, we stick to avi file format
	if(!videoProcessMode)
		family=CodecFamilyAVI;
	printf("**saving:**\n");
	// Check if we need to do a sanity B frame check
	if(!videoProcessMode)
	{	
		uint32_t pb;
		end=avifileinfo->nb_frames;
		// if the last frame is the last frame (!)
		// we add one to keep it, else we systematically skip
		// the last frame
		if(frameEnd==end-1) end=frameEnd+1;
		else
			end=frameEnd;
		if(!video_body->sanityCheckRef(frameStart,end,&pb))
		{
			if(pb)
			{
				GUI_Alert("The video starts/ends by lonely B frame\nPlease remove them");
				return 0;
			}
			if(!GUI_Question("Warning !\n Bframe has lost its reference frame\nContinue ?"))
				return 0;
		}
	
	}
	switch(family)
	{
		case CodecFamilyAVI:
					printf(" Avi family\n");
					A_SaveAudioNVideo(name);
					break;
		case CodecFamilyMpeg:
					printf(" Mpeg family\n");
					EncoderSaveMpeg(name);
					break;
		case CodecFamilyXVCD:
					printf(" Xvcd family\n");
					oplug_mpegff(name);
					break;
		default:
					assert(0);
					return 0;
	}
	return 1;
}
uint8_t DIA_encoding::isAlive( void )
{
	if(stopReq)
	{
		if(GUI_Question("Continue encoding, no will stop it ?"))
		{
			stopReq=0;
		}
	}
	if(!stopReq) return 1;
	return 0;
}
uint8_t GUI_encoderIsAlive(void)
{
 	if(window&&(	tobedestroyed==0))  return 1;
	// Ask if we are sure ?

	if(GUI_Question("Are you sure ?")==0)
	{
		if( tobedestroyed)
		{
			tobedestroyed=0;
		}
		else
		{
			GUI_encoderStart();
		}
		return 1;

	}
  return 0;

}
// CYB 2005.02.23: DND
void fileReadWrite(SELFILE_CB *cb, int rw, char *name)
{

    if(name)
    {
        if(cb)
        {
            FILE *fd;
            fd=fopen(name,"rb");
            if(rw==0) // read
            {
                // try to open it..
                if(!fd)
                {
                    GUI_Error_HIG("File error", "Cannot open \"%s\".", name);
                    return;
                }
            }
            else // write
            {
                if(fd)
                {
                    fclose(fd);
                    if(!GUI_Question("Overwrite file ?"))
                        return;
                }
                // check we have right access to it
                fd=fopen(name,"wb");
                if(!fd)
                {
                    GUI_Error_HIG("Cannot write the file", "No write access to \"%s\".", name);
                    return;
                }
            }
            fclose(fd);
            cb(name);
            ADM_dealloc(name);
        } // no callback -> return value
    }
}
/**
	Load or append a file.
	The file type is determined automatically and the ad-hoc video decoder is spawned


*/
uint8_t ADM_Composer::addFile (char *name, uint8_t mode)
{
  uint8_t    ret =    0;
  aviInfo    info;
  WAVHeader *    _wavinfo;
//  aviHeader *    tmp;
  fileType    type =    Unknown_FileType;

UNUSED_ARG(mode);
	_haveMarkers=0; // by default no markers are present
  assert (_nb_segment < MAX_SEG);
  assert (_nb_video < MAX_VIDEO);

  if (!identify (name, &type))
    return 0;


#define OPEN_AS(x,y) case x:\
						_videos[_nb_video]._aviheader=new y; \
						 ret = _videos[_nb_video]._aviheader->open(name); \
						break;
  switch (type)
    {
      case VCodec_FileType:
      		loadVideoCodecConf(name);      		
		return ADM_IGN; // we do it but it wil fail, no problem with that
      		break;
      OPEN_AS (Mp4_FileType, mp4Header);
      OPEN_AS (H263_FileType, h263Header);
      // For AVI we first try top open it as openDML
      case AVI_FileType:
      			_videos[_nb_video]._aviheader=new OpenDMLHeader; 
			 ret = _videos[_nb_video]._aviheader->open(name); 			
			break;
      
      OPEN_AS (Nuppel_FileType, nuvHeader);
      OPEN_AS (BMP_FileType, picHeader);
      OPEN_AS (MpegIdx_FileType, mpeg2decHeader);
      OPEN_AS (_3GPP_FileType, _3GPHeader);
       OPEN_AS (Ogg_FileType, oggHeader);

    case Mpeg_FileType:
    	// look if the idx exists
	char tmpname[256];
	assert(strlen(name)+5<256);;
	strcpy(tmpname,name);
	strcat(tmpname,".idx");
	if(addFile(tmpname)) return 1;
      // then propose to index it
      if (GUI_Question ("This looks like mpeg\n Do you want to index it?"))
	{
	  char *	  idx, *	    mname;
	  int	    track;

	  DIA_indexerPrefill(name);
	  if (DIA_mpegIndexer (&mname, &idx, &track, 1))
	    {
	      if ((mname == NULL) || (idx == NULL))
		{
		  GUI_Alert ("Select files!");

		  return 0;
		}
	      printf ("\n indexing :%s to \n%s\n", mname, idx);


	      if (indexMpeg (mname, idx, (uint8_t) track))
	      {
	      		printf("\n re-opening %s\n", idx);
			return addFile (idx, 0);
	      }
	      return 0;

	    }
	}
      return 0;
      break;
	case WorkBench_FileType:

  		return loadWorbench(name);
    default:
      if (type == Unknown_FileType)
	{
	  printf ("\n not identified ...\n");
	}
      else
	printf
	  ("\n successfully identified but no loader support detected...\n");
      return 0;
    }
  // check opening was successful
  if (ret == 0)
    {
      printf ("\n Attempt to open %s failed!\n", name);
      delete
	_videos[_nb_video].
	_aviheader;;
      return 0;
    }

  // else update info
  _videos[_nb_video]._aviheader->getVideoInfo (&info);
  _videos[_nb_video]._aviheader->setMyName (name);
//    fourCC::print( info.fcc );
  _total_frames += info.nb_frames;
  _videos[_nb_video]._nb_video_frames = info.nb_frames;


  // and update audio info
  //_________________________
  _wavinfo = _videos[_nb_video]._aviheader->getAudioInfo ();	//wavinfo); // will be null if no audio
  if (!_wavinfo)
    {
      printf ("\n *** NO AUDIO ***\n");
      _videos[_nb_video]._audiostream = NULL;
    }
  else
    {

      _videos[_nb_video]._aviheader->getAudioStream (&_videos[_nb_video].
						     _audiostream);
      _videos[_nb_video]._audio_size =
	_videos[_nb_video]._audiostream->getLength ();
	// For mpeg2, try to guess if it is pulldowned material
	double duration_a, duration_v;
	double rdirect, rpulldown;
	
	duration_a=_videos[_nb_video]._audio_size;
	duration_a/=_wavinfo->byterate;   // now we got duration in seconds
	
	// ditto for video
	duration_v= _videos[_nb_video]._nb_video_frames;
	duration_v/=info.fps1000;
	duration_v*=1000;
	
	printf("Audio : %f video : %f\n",duration_a,duration_v);
	if(MpegIdx_FileType==type && info.fps1000>29000 && info.fps1000<30000
		 && duration_a>1 && duration_v>1)
	{
		rdirect=(duration_a-duration_v)/duration_v;
		if(rdirect<0) rdirect=-rdirect;
		
		rpulldown=((duration_a*0.8)-duration_v)/duration_v;
		if(rpulldown<0) rpulldown=-rpulldown;
		
		
		printf("Direct : %f pd : %f\n",rdirect,rpulldown);
		if( rdirect*2> rpulldown)
		{
			printf("Probably pulldowned, switching to 23.976 \n");
			 AVIStreamHeader *ily =	_videos[_nb_video]._aviheader->	getVideoStreamHeader ();
      				ily->dwRate = 23976;
      				ily->dwScale = 1000;			
		
		}
		
	
	}
	

    }

  printf ("\n Decoder FCC: ");
  fourCC::print (info.fcc);
  // ugly hack
  if (info.fps1000 > 2000 * 1000)
    {
      printf (" FPS too high, switching to 25 fps hardcoded\n");
      info.fps1000 = 25 * 1000;
      updateVideoInfo (&info);
    }
  uint32_t
    l;
  uint8_t *
    d;
  _videos[_nb_video]._aviheader->getExtraHeaderData (&l, &d);
  _videos[_nb_video].decoder = getDecoder (info.fcc,
					   info.width, info.height, l, d);


  //
  //  And automatically create the segment
  //
  _segments[_nb_segment]._reference = _nb_video;
  _segments[_nb_segment]._audio_size = _videos[_nb_video]._audio_size;
  _segments[_nb_segment]._audio_start = 0;
  _segments[_nb_segment]._start_frame = 0;
  _segments[_nb_segment]._nb_frames   =   _videos[_nb_video]._nb_video_frames ;
  _videos[_nb_video]._isAudioVbr=0;
  // next one please
	_nb_video++;
	_nb_segment++;

//______________________________________
// 1-  check for B _ frame  existence
// 2- check  for consistency with reported flags
//______________________________________
	uint8_t count=0;
TryAgain:	
	_VIDEOS 	*vid;
	uint32_t err=0;

		vid= &(_videos[_nb_video-1]);
		vid->_forwardReference=0xFFFFFFF;
		vid->_forwardFrame= NULL;
		vid->_reorderReady=0;
		// we only try if we got everything needed...
		if(!vid->decoder)
		{
			printf("\n no decoder to check for B- frame\n");
			return 1;
		}
		if(!vid->decoder->bFramePossible())
		{
			printf("\n no  B- frame with that codec \n");
			return 1;
		}
		printf("\n checking for B-Frames...\n");
		if( vid->_nb_video_frames >15) // 12
		{
				uint8_t 		*buffer,*bufferin;
				uint32_t 		len,flags,flag2;
				uint8_t 		bframe=0, bconsistency=1;

				buffer=new uint8_t [info.width* info.height*2];
				bufferin=new uint8_t [info.width* info.height*2];


				// we decode 5 frames..should be enough to get an opinion
				for(uint32_t i=0;i<13;i++)  //10
				{
					flags=flag2=0;
  					vid->_aviheader->getFrameNoAlloc (i,
							 bufferin,
							 &len, &flags);
					if(!vid->decoder->uncompress( (uint8_t *)bufferin,(uint8_t *)buffer,len,&flag2 ))
					{
						err++;
						printf("\n ***oops***\n");
					}

					if(i<5) continue; // ignore the first frames
					
					// check if it is a b-frame
					//printf(" %lu : %lu \n",i,flag2);
					if(flag2 & AVI_B_FRAME)
					{
						printf(" %lu is a b frame\n",i);
					 	bframe=1;
						vid->_aviheader->getFlags(i,&flags);
						if(!(flags & AVI_B_FRAME))
							bconsistency=0;
						else
							printf("\n and flags is ok\n");
					}
					
				}

				delete [] buffer;
				delete [] bufferin;
				if(bframe)
				{
					printf("\n Mmm this appear to have b-frame...\n");
					if(bconsistency)
					{
						printf("\n And the index is ok\n");
						vid->_forwardFrame=new uint8_t [720*576*3];
						vid->_reorderReady=vid->_aviheader->reorder();
						if(vid->_reorderReady)
						{
							printf("\n Frames re-ordered, B-frame friendly now :)\n");
							aprintf(" we had :%lu",info.nb_frames);
							// update nb frame in case we dropped some
							_total_frames -= info.nb_frames;
							_videos[_nb_video-1]._aviheader->getVideoInfo (&info);
							aprintf(" we have now  :%lu",info.nb_frames);
							_total_frames += info.nb_frames;
  							_videos[_nb_video-1]._nb_video_frames = info.nb_frames;
						}
						else
						{
							printf("\n Frames not  re-ordered, expect problem with b-frames\n");
						}

					}
					else
					{
						printf("\n But the  index is not up to date \n");
						uint32_t ispacked=0;
						// If it is Divx 5.0.xxx use divx decoder
						if(fourCC::check(info.fcc,(uint8_t *)"DX50")
						|| fourCC::check(info.fcc,(uint8_t *)"XVID" ))
						{


							//if(vid->decoder->isDivxPacked())
							if(vid->decoder->isDivxPacked())
							{
								// can only unpack avi
								if(!count && type==AVI_FileType)
								{
									if(GUI_Question("It looks like Vop packed divx.\nDo you want me to unpack it ?"))
									{
									OpenDMLHeader *dml=NULL;
									count++;	
									dml=(OpenDMLHeader *)vid->_aviheader;
									// Can we repack it ?
									if(dml->unpackPacked())	
										goto TryAgain;
									GUI_Alert("Could not unpack it\n, using backup decoder= not frame accurate.");
									}
								}
#if  1 //def USE_DIVX

								printf("\n Switching codec...\n");
								delete vid->decoder;
								vid->decoder=getDecoderVopPacked(info.fcc,
																   info.width,
																   info.height,0,NULL);
								ispacked=1;
#else
								GUI_Alert("Troubles ahead : This a vop packed avi..");
#endif

							}

						}
						// else warn user
						if(!ispacked)
							GUI_Alert("\n Please used Misc->Rebuild frame for BFrames!");
					}
				}
				else
				{
					printf("Seems it does not contain B-frames...\n");
				}
		printf(" End of B-frame check\n");
		}

  return 1;
}
void FileSel_ReadWrite(SELFILE_CB *cb, int rw, const char *name, const char *actual_workbench_file)
{
	if(name)
	{
		if(cb)
		{
			FILE *fd;
			fd=ADM_fopen(name,"rb");
			if(rw==0) // read
			{
				// try to open it..
				if(!fd)
				{
					GUI_Error_HIG(QT_TRANSLATE_NOOP("filesel","File error"), QT_TRANSLATE_NOOP("filesel","Cannot open \"%s\"."), name);
					return;
				}
			}
			else // write
			{
				if(fd){
					struct stat buf;
					int fdino;
					ADM_fclose(fd);

					char msg[300];

					snprintf(msg, 300, QT_TRANSLATE_NOOP("filesel","%s already exists.\n\nDo you want to replace it?"), ADM_GetFileName(name));

					if(!GUI_Question(msg))
						return;
					/*
					** JSC Fri Feb 10 00:07:30 CET 2006
					** compare existing output file inode against each current open files inode
					** i'm ignoring st_dev, so we may get false positives
					** i'm testing until fd=1024, should be MAXFD computed by configure
					** keep in mind:
					** you can overwrite .idx files, they are loaded into memory and closed soon
					** you cannot overwrite segment data files, all files are kept open and
					** are detected here
					*/
#ifndef _WIN32
					if( stat(name,&buf) == -1 ){
						fprintf(stderr,"stat(%s) failed\n",name);
						return;
					}
#endif
					fdino = buf.st_ino;
					for(int i=0;i<1024;i++){
						if( fstat(i,&buf) != -1 ){
							if( buf.st_ino == fdino ){
								char str[512];
								snprintf(str,512,"File \"%s\" exists and is opened by Avidemux",name);
								GUI_Error_HIG(str,
									QT_TRANSLATE_NOOP("filesel","It is possible that you are trying to overwrite an input file!"));
								return;
							}
						}
					}
					/*
					** compare output file against actual EMCAscript file
					** need to stat() to avoid symlink (/home/x.js) vs. real file (/export/home/x.js) case
					*/
					if( actual_workbench_file ){
						if( stat(actual_workbench_file,&buf) != -1 ){
							if( buf.st_ino == fdino ){
								char str[512];
								snprintf(str,512,"File \"%s\" exists and is the actual ECMAscript file",name);
								GUI_Error_HIG(str,QT_TRANSLATE_NOOP("filesel","It is possible that you are trying to overwrite an input file!"));
								return;
							}
						}
					}
				}

				// check we have right access to it
				fd=ADM_fopen(name,"wb");
				if(!fd)
				{
					GUI_Error_HIG(QT_TRANSLATE_NOOP("filesel","Cannot write the file"),QT_TRANSLATE_NOOP("filesel", "No write access to \"%s\"."), name);
					return;
				}
			}
			ADM_fclose(fd);
			cb(name);
		} // no callback -> return value
	}
}
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;

	if(rname)
		*rname=NULL;

	dialog=create_fileselection1();
	gtk_window_set_title (GTK_WINDOW (dialog),label);
	gtk_transient(dialog);
	if( prefs->get(LASTDIR,&tmpname))
	{
	//	printf("tmpname : %s\n",tmpname);
		char *str=PathCanonize(tmpname);

	//	printf("tmpname : %s\n",str);
		PathStripName(str);

	//	printf("tmpname : *%s*\n",str);
		gtk_file_selection_set_filename(GTK_FILE_SELECTION(dialog),(gchar *)str);
		delete [] str;
	}
	if(gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_OK)
	{

			selected_filename= (gchar *) 	gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog));
			 if (*(selected_filename + strlen(selected_filename) - 1) == '/')
      	  					GUI_Alert("Cannot open directory as file !");
			else
			{
						name=strdup(selected_filename);

						char *str=PathCanonize(name);
						PathStripName(str);
						prefs->set(LASTDIR,str);			
						delete [] str;

			}
	}
	gtk_widget_destroy(dialog);

	if(name)
	{

		if(cb)
		{

			if(rw==0) // read
			{
				// try to open it..
				FILE *fd;
				fd=fopen(name,"rb");
				if(!fd)
				{
						GUI_Alert("Cannot open this file !");
						return;
				}
				fclose(fd);
				cb(name);
				free(name);

			}
			else // write
			{
				FILE *fd;
				fd=fopen(name,"rb");
				if(fd)
					{
							fclose(fd);
							if(!GUI_Question("Overwrite file ?"))
								return;
					}
				// check we have right access to it
				fd=fopen(name,"wb");
				if(!fd)
					{
						GUI_Alert("No write access to that file !");
						return;
					}
				fclose(fd);


				cb(name);
				free(name);
			}
		} // no callback -> return value
		else
		{

			*rname=name;


		}


	}

}
/**
    \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; 
}
/*-------------------------------------------------------------------------------------------------------------------*/
uint8_t  mpegWritter::save_dualpass(char *name,uint32_t final_size,uint32_t bitrate,ADM_MPEGTYPE mpegtype,
					int matrix,uint8_t interlaced,
					uint8_t bff,        // WLA
					uint8_t widescreen)
{
AVDMGenericVideoStream	 *incoming;
char *statname;

	incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
	_w=incoming->getInfo()->width;
	_h=incoming->getInfo()->height;
	_page=_w*_h;
	_page+=_page>>1;
	_fps1000=incoming->getInfo()->fps1000;
		_total=incoming->getInfo()->nb_frames;
	if(!_total) return 0;
	_buffer	=new uint8_t[_w*_h*2];
	_buffer_out=new uint8_t[_w*_h*2];


	statname=new char[strlen(name)+4+1];
	strcpy(statname,name);
	strcat(statname,".st");
	printf("Matrix : %d\n\n",matrix);
	encoding=new DIA_encoding(_fps1000);
	encoding->setPhasis("Encoding");


	// check if stat file exists ?
	FILE *fd;
	uint8_t reuse=0;
	fd=fopen(statname,"rt");
	if(fd)
	{
		fclose(fd);
		if(GUI_Question("Reuse log file ?")) reuse=1;
	}
#if 1
if(!reuse)
//	if(!dopass1(name,statname,final_size,bitrate,mpegtype,matrix,interlaced,widescreen))
	if(!dopass1(name,statname,final_size,bitrate,mpegtype,matrix,interlaced,bff,widescreen)) 
	// WLA
	{
		delete encoding;
		GUI_Alert("Error in pass 1");
		delete [] statname;
		return 0;
	}
#endif
//	if(!dopass2(name,statname,final_size,bitrate,mpegtype,matrix,interlaced,widescreen))
	if(!dopass2(name,statname,final_size,bitrate,mpegtype,matrix,interlaced,bff,widescreen)) 
	// WLA
	{
		delete encoding;
		GUI_Alert("Error in pass 2");
		delete [] statname;
		return 0;
	}
	delete encoding;
	delete [] statname;
	return 1;
}
//______________________________________
//
// Open and get the headears/index built
// along way
//______________________________________
uint8_t    OpenDMLHeader::open(char *name)
{
uint8_t badAvi=0;
uint32_t rd;

	printf("** opening OpenDML files **");	
	_fd=fopen(name,"rb");
	if(!_fd)
	{
		printf("\n cannot open %s \n",name);
		return 0;
	}
#define CLR(x)              memset(& x,0,sizeof(  x));

              CLR( _videostream);
              CLR( _mainaviheader);
	      _isvideopresent=1;
	      _isaudiopresent=0;    	     	      	 	      
	      
		_nbTrack=0;
		riffParser *parser=new riffParser(name);
		
		if(MKFCC('R','I','F','F')!=(rd=parser->read32()))
			{
				printf("Not riff\n");badAvi=1;
				printf("%lx != %lx\n",rd,MKFCC('R','I','F','F'));
			}
		parser->read32();
		if(MKFCC('A','V','I',' ')!=parser->read32())
			{
				printf("Not Avi\n");badAvi=1;
			}
		
		if(!badAvi)
			{
				walk(parser);	
			
			}					
		delete parser;
		aprintf("Found %d tracks\n:-----------\n",_nbTrack);
		// check if it looks like a correct avi
		if(!_nbTrack) badAvi=1;
		
		// if we are up to here -> good avi :)
		if(badAvi)
		{
			printf("FAIL\n");
			return 0;
		}
		// now read up each parts...
		//____________________________
		
#define DUMP_TRACK(i) aprintf(" at %llu (%llx) size : %llu (%llx)\n", \
				_Tracks[i].strh.offset,\
				_Tracks[i].strh.offset,\
				_Tracks[i].strh.size,\
				_Tracks[i].strh.size);
								
		for(uint32_t i=0;i<_nbTrack;i++)
		{
			DUMP_TRACK(i);		
		}		
		
		uint32_t vidTrack=0xff;
		// search wich track is the video one
		// and load it to _videoheader
		
		for(uint32_t i=0;i<_nbTrack;i++)
		{
			fseeko(_fd,_Tracks[i].strh.offset,SEEK_SET);
			if(_Tracks[i].strh.size!=sizeof(_videostream))
			{
				printf("Mmm(1) we have a bogey here, size mismatch : %lu \n",_Tracks[i].strh.size);
				printf("expected %d\n",sizeof(_videostream));
				if(_Tracks[i].strh.size<sizeof(_videostream)-8) // RECT is not mandatory
				{
					GUI_Alert("Maformed header!");
					return 0;
				}		
				printf("Trying to continue anyway\n");			
			}
			fread(&_videostream,sizeof(_videostream),1,_fd);
#ifdef ADM_BIG_ENDIAN
				Endian_AviStreamHeader(&_videostream);
#endif
			if(_videostream.fccType==MKFCC('v','i','d','s'))
				{
					vidTrack=i;
					printf("Video track is %ld\n",i);
					break;
				}		
		}
		if(0xff==vidTrack)
		{
			printf("Could not identify video track!");
			return 0;
		}
		
		// STOP HERE -> Alex <-
		//return 0;
		// STOP HERE -> Alex <-
		
		
		
									

		// then bih stuff
		int32_t extra;
		_fd=fopen(name,"rb");
		
		fseeko(_fd,_Tracks[vidTrack].strf.offset,SEEK_SET);		
		extra=_Tracks[vidTrack].strf.size-sizeof(_video_bih);
		if(extra<0)
		{	
			printf("bih is not big enough (%lu/%lu)!\n",_Tracks[vidTrack].strf.size,sizeof(_video_bih));
			return 0;
		}
		fread(&_video_bih,sizeof(_video_bih),1,_fd);
#ifdef ADM_BIG_ENDIAN
		Endian_BitMapInfo(&_video_bih);
#endif
		if(extra>0)
		{				
			_videoExtraLen=extra;		
			_videoExtraData=new uint8_t [extra];
			fread(_videoExtraData,extra,1,_fd);
		}
		_isvideopresent=1;
		//--------------------------------------------------
		//	Read audio trak info, select if there is
		//	several
		//--------------------------------------------------
		// and audio track
		uint32_t audioTrack=0xff;	
		uint32_t audioTrackNumber=0;
		if(_mainaviheader.dwStreams>=2)
		{
			// which one is the audio track, is there several ?
			switch(countAudioTrack())
			{
				case 0: printf("No audio track found.\n");
					break;
				case 1: printf("One audio track found\n");
					audioTrack=searchAudioTrack(0);
					audioTrackNumber=0;
					break;
				default: printf("Several audio tracks found\n");
					uint32_t t;
					t=GUI_Question("Take second audio track ?");
					audioTrackNumber=t;
					audioTrack=searchAudioTrack(t);
			}
			if(audioTrack!=0xff) // one is marked
			{
				// Read information
				printf("Taking audio track : %lu %lu\n",audioTrackNumber,audioTrack);
				_isaudiopresent=1;
				fseeko(_fd,_Tracks[audioTrack].strh.offset,SEEK_SET);

				if(_Tracks[audioTrack].strh.size!=sizeof(_audiostream));
				{
				
					printf("Mmm(2) we have a bogey here, size mismatch : %lu \n"
						,_Tracks[audioTrack].strh.size);
					printf("expected %d\n",sizeof(_audiostream));
					if(_Tracks[audioTrack].strh.size<sizeof(_audiostream)-8)
					{
						GUI_Alert("Maformed header!");
						return 0;
					}		
					printf("Trying to continue anyway\n");			
				}
				fread(&_audiostream,sizeof(_audiostream),1,_fd);
#ifdef ADM_BIG_ENDIAN
				Endian_AviStreamHeader(&_audiostream);
#endif
				if(_audiostream.fccType!=MKFCC('a','u','d','s'))
				{	
					printf("Not an audio track!\n");
					return 0;
				}
				// now read extra stuff
				fseeko(_fd,_Tracks[audioTrack].strf.offset,SEEK_SET);		
				extra=_Tracks[audioTrack].strf.size-sizeof(_wavHeader);
				if(extra<0)
				{	
					printf("WavHeader is not big enough (%lu/%lu)!\n",
					_Tracks[audioTrack].strf.size,sizeof(WAVHeader));
					return 0;
				}
				fread(&_wavHeader,sizeof(WAVHeader),1,_fd);				
#ifdef ADM_BIG_ENDIAN
				Endian_WavHeader(&_wavHeader);
#endif
				if(extra>2)
				{				
					fgetc(_fd);fgetc(_fd);
					extra-=2;
					_audioExtraLen=extra;		
					_audioExtraData=new uint8_t [extra];
					fread(_audioExtraData,extra,1,_fd);
				}					
			
			}		
		}
		
		// now look at the index stuff
		// there could be 3 cases:
		// 1- It is a openDML index, meta index  + several smaller index
		// 2- It is a legacy index (type 1 , most common)
		// 3- It is a broken index or no index at all
		//
		// If it is a openDML index we will find a "indx" field in the Tracks
		// Else we will find it in _regularIndex Track
		// Since openDML often also have a regular index we will try open DML first
		
		uint8_t ret=0;
		Dump();
		
		// take the size of riff header and actual file size
		uint64_t riffSize;
		fseeko(_fd,0,SEEK_END);		
		_fileSize=ftello(_fd);
		fseeko(_fd,0,SEEK_SET);
		read32();
		riffSize=(uint64_t )read32();
				
		
		// 1st case, we have an avi < 4 Gb
		// potentially avi type 1		
		if((_fileSize<4*1024*1024*1024LL)&&
			// if riff size is ~ fileSize try regular index
			 (abs(riffSize-_fileSize)<1024*1024))
			{
				printf("Size looks good, maybe type 1 avi\n");
				if(!ret && !_Tracks[vidTrack].indx.offset) // try regular avi
					ret=indexRegular(vidTrack,audioTrack,audioTrackNumber);		
				if (!ret && _Tracks[vidTrack].indx.offset)	
					ret=indexODML(vidTrack,audioTrack,audioTrackNumber);
				if(!ret) // re-index!
					ret=indexReindex(vidTrack,audioTrack,audioTrackNumber);		
			} // else try openDML/reindexing
		else
			{
				printf("Size mismatch, not type 1 avi\n");
				if (!ret && _Tracks[vidTrack].indx.offset)	
					ret=indexODML(vidTrack,audioTrack,audioTrackNumber);
				if(!ret) // re-index!
					ret=indexReindex(vidTrack,audioTrack,audioTrackNumber);			
			
			}
				
		if(!ret) 
		{
			printf("Cound not index it properly...\n");
			return 0;
		
		}				
		if(!_audioIdx) _isaudiopresent=0;
		else
		{
			// build audio stream
		 	_audioTrack = new AVDMAviAudioStream(_audioIdx,
   						_nbAudioChunk,
						_fd,
						&_wavHeader,						
						0,
						_audioExtraLen,_audioExtraData);
		
		}
		_videostream.fccHandler=_video_bih.biCompression;
		printf("\nOpenDML file successfully read..\n");
		
		return ret;
	
}
示例#13
0
/**
          \fn GUI_FileSelWrite (const char *label, char **name, uint32_t access)
          \brief Ask for a file for reading (access=0) or writing (access=1)
        */
static	void GUI_FileSelSelectWriteInternal(const char *label, const char *ext, char **name)
{
    *name = NULL;
    QString str ;
    QString fileName,dot=QString(".");
    QString filterFile=QString(QT_TRANSLATE_NOOP("qfile","All files (*.*)"));
    bool doFilter = !!(ext && strlen(ext));
    QFileDialog::Options opts;
    int extSize=1;

    if(doFilter)
    {
        extSize+=strlen(ext);
    }
    //printf("Do filer=%d\n",(int)doFilter);
    std::string lastFolder;
    admCoreUtils::getLastWriteFolder(lastFolder);
    if (lastFolder.size())
    {
        QString outputPath = QFileInfo(QString::fromUtf8(lastFolder.c_str())).path();

        char *tmpinputname = NULL;
        QString inputBaseName = QString("");
        std::string lastRead;
        admCoreUtils::getLastReadFolder(lastRead);
        if (lastRead.size())
        {
            inputBaseName = QFileInfo(QString::fromUtf8(lastRead.c_str())).completeBaseName();
        }

        QString outputExt = QString("");
        if (doFilter)
        {
            outputExt = dot+QString(ext);
        }
        QString separator = QString("/");
        str = outputPath+separator+inputBaseName+outputExt;

        /* LASTDIR may have gone; then do nothing and use current dir instead (implied) */
        if (!QDir(outputPath).exists())
            str.clear();
    }

    if(doFilter)
    {
        filterFile=QString(ext)+QString(QT_TRANSLATE_NOOP("qfile"," files (*."))+QString(ext)+QString(");;")+filterFile;
    }
    fileName = QFileDialog::getSaveFileName(NULL,
                                            label,  // caption
                                            str,    // folder
                                            filterFile,   // filter
                                            NULL,QFileDialog::DontConfirmOverwrite);   // selected filter


    if (fileName.isNull() ) return;

    *name=(char *)ADM_alloc(  strlen(fileName.toUtf8().constData())+extSize);
    strcpy(*name,fileName.toUtf8().constData());

    // Check if we need to add an extension....
    if(doFilter)
    {
        if(!strstr(*name,"."))
        {
            strcat(*name,".");
            strcat(*name,ext);

            fileName=fileName+QString(".")+QString(ext);
        }
    }
    QFile newFile(fileName);
    if(newFile.exists())
    {
        QFileInfo fileInfo(newFile);
        QString q=QString(QT_TRANSLATE_NOOP("qfile","Overwrite file "))+fileInfo.fileName()+QString("?");
        if(!GUI_Question(q.toUtf8().constData()))
        {
            ADM_dezalloc(*name);
            *name=NULL;
            return;
        }
    }
    admCoreUtils::setLastWriteFolder( std::string(fileName.toUtf8().constData()));
}
/*-------------------------------------------------------------------------------------------------------------------*/
uint8_t
mpegWritter::save_dualpass (const char *name, uint32_t final_size, uint32_t bitrate, ADM_MPEGTYPE mpegtype, int matrix, uint8_t interlaced, uint8_t bff,	// WLA
			    uint8_t widescreen)
{
  AVDMGenericVideoStream *incoming;
  char *statname;
  uint32_t reuse = 0;

  incoming = getLastVideoFilter (frameStart, frameEnd - frameStart);
  _w = incoming->getInfo ()->width;
  _h = incoming->getInfo ()->height;
  _page = _w * _h;
  _page += _page >> 1;
  _fps1000 = incoming->getInfo ()->fps1000;
  _total = incoming->getInfo ()->nb_frames;
  if (!_total)
    return 0;
  //_buffer       =new uint8_t[_w*_h*2];
  aImage = new ADMImage (_w, _h);
  _buffer_out = new uint8_t[_w * _h * 2];


  statname = new char[strlen (name) + 4 + 1];
  strcpy (statname, name);
  strcat (statname, ".st");
  printf ("Matrix : %d\n\n", matrix);
  encoding = new DIA_encoding (_fps1000);
  encoding->setPhasis ("Encoding");


  // check if stat file exists ?
#if 1				//ndef CYG_MANGLING
  {
    FILE *fd;
    fd = fopen (statname, "rt");
    if (fd)
      {
	fclose (fd);
	prefs->get (FEATURE_REUSE_2PASS_LOG, (uint32_t *) & reuse);
        if (!reuse && GUI_Question (_("Reuse log file ?")))
	  reuse = 1;
      }
  }
#endif
  //_ratecontrol=new ADM_oldXvidRc(_fps1000,statname);
  _ratecontrol = new ADM_newXvidRc (_fps1000, statname);

#if 1
  if (!reuse)
//      if(!dopass1(name,statname,final_size,bitrate,mpegtype,matrix,interlaced,widescreen))
    if (!dopass1
	(name, statname, final_size, bitrate, mpegtype, matrix, interlaced,
	 bff, widescreen))
      // WLA
      {
	delete encoding;
        GUI_Error_HIG (_("Error in pass 1"), NULL);
	delete[]statname;
	return 0;
      }
#endif
//      if(!dopass2(name,statname,final_size,bitrate,mpegtype,matrix,interlaced,widescreen))
  if (!dopass2
      (name, statname, final_size, bitrate, mpegtype, matrix, interlaced, bff,
       widescreen))
    // WLA
    {
      delete encoding;
      GUI_Error_HIG (_("Error in pass 2"), NULL);
      delete[]statname;
      return 0;
    }
  delete encoding;
  delete[]statname;
  return 1;
}
bool admSaver::save(void)
{


    int ret=false;
    
    
    ADM_info("Audio starting time %s\n",ADM_us2plain(startAudioTime));
    ADM_info("[A_Save] Saving..\n");
    
    const char *defaultExtension=ADM_MuxerGetDefaultExtension(muxerIndex);
    EditableAudioTrack *ed=NULL;
    ADM_info("Muxer default extension %s\n",defaultExtension);
    if(!videoEncoderIndex) 
    {
        if(false==video_body-> checkCutsAreOnIntra())
        {
            if(!GUI_Question("The video is in copy mode but the cut points are not on keyframes.\n"
                            "The video will be saved but there will corruption at cut point(s).\n"
                             "Do you want to continue anyway ?"))
            {
                return false;
            }
        }
    }

    if(!(muxer=ADM_MuxerSpawnFromIndex(muxerIndex)))
    {
        GUI_Error_HIG("Muxer","Cannot instantiante muxer");
        return 0;
    }
     
    ADM_videoStream *video=setupVideo();
    if(!video)
    {
        return false;
    }
    // adjust audio starting time
     for(int i=0;i<nbAudioTracks;i++)
        {
            ADM_audioStream  *stream=video_body->getAudioStreamAt(i);
            stream->goToTime(startAudioTime);
        }
    if(false==setupAudio())
    {
        if(video) delete video;
        if(muxer) delete muxer;
        muxer=NULL;
        return false;
    }
   
    // Check if we need to add an extension....
    if(defaultExtension)
    {
        if(!strstr(fileName.c_str(),"."))
        {
            
            fileName=fileName+std::string(".")+std::string(defaultExtension);
            ADM_info("Adding extension, filename is now %s\n",fileName.c_str());
        }

    }
    if(!muxer->open(fileName.c_str(),video,nbAudioTracks,audioAccess))
    {
        GUI_Error_HIG("Muxer","Cannot open ");
    }else
    {
        ret=muxer->save();
        muxer->close();
    }
abort123:
    if(video)
        delete video;
    video=NULL;
    for(int i=0;i<nbAudioTracks;i++)
    {
        delete audioAccess[i];
        audioAccess[i]=NULL;
    }
    return ret;
}
示例#16
0
uint8_t oplug_mpegff(const char *name, ADM_OUT_FORMAT type)
{
AVDMGenericVideoStream *_incoming;
Encoder  *encoder=NULL;
ADMMpegMuxer	*muxer=NULL;
FILE 		*file=NULL;
uint8_t		audioBuffer[48000];
uint32_t	audioLen=0;
uint32_t _w,_h,_fps1000,_page,total;	
AVDMGenericAudioStream	*audio=NULL;
uint32_t len,flags;
uint32_t size;
ADM_MUXER_TYPE mux;
uint32_t  audio_encoding=0;
uint32_t  real_framenum=0;
uint8_t   ret=0;
uint32_t  sample_target=0;
uint32_t  total_sample=0;
ADMBitstream bitstream(0);
uint32_t audioSum=0;
DIA_encoding  *encoding;
int reuse = 0;

        twoPass=new char[strlen(name)+6];
        twoFake=new char[strlen(name)+6];
  
        strcpy(twoPass,name);
        strcat(twoPass,".stat");
        strcpy(twoFake,name);
        strcat(twoFake,".fake");
 
        _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
        _w=_incoming->getInfo()->width;
        _h=_incoming->getInfo()->height;
        _fps1000=_incoming->getInfo()->fps1000;
        _page=_w*_h;
        _page+=_page>>1;

        total=_incoming->getInfo()->nb_frames;
        if(!total) return 0;	
        
        switch(type)
        {
            default:
                    ADM_assert(0);
            case ADM_ES:
                        // Else open file (if possible)                       
                        mux=MUXER_NONE;
                        break;
            case ADM_TS:
                    if(!currentaudiostream)
                    {
                      GUI_Error_HIG(QT_TR_NOOP("There is no audio track"), NULL);
					  goto finishvcdff;
                    }
                    audio=mpt_getAudioStream();
                    mux=MUXER_TS;
                    break;
            case ADM_PS:
            
            {
                if(!currentaudiostream)
                {
                  GUI_Error_HIG(QT_TR_NOOP("There is no audio track"), NULL);
				  goto finishvcdff;
                }
                audio=mpt_getAudioStream();
                // Have to check the type
                // If it is mpeg2 we use DVD-PS
                // If it is mpeg1 we use VCD-PS
                // Later check if it is SVCD
                if(!audio)
                {
                  GUI_Error_HIG(QT_TR_NOOP("Audio track is not suitable"), NULL);
				  goto finishvcdff;
                }
                // Check
                WAVHeader *hdr=audio->getInfo();	
                audio_encoding=hdr->encoding;
                if (videoCodecGetType() == CodecXVCD || videoCodecGetType() == CodecVCD)
                {
                        if(hdr->frequency!=44100 ||  hdr->encoding != WAV_MP2)
                        {
                            GUI_Error_HIG(("Incompatible audio"),QT_TR_NOOP( "For VCD, audio must be 44.1 kHz MP2."));
							goto finishvcdff;
                        }
                        mux=MUXER_VCD;
                        printf("X*CD: Using VCD PS\n");
                }else
                {    
                        aviInfo info;
                        video_body->getVideoInfo(&info);
                        if(hdr->frequency==44100 && _w==480&&hdr->encoding == WAV_MP2 ) // SVCD ?
                        {
                            mux=MUXER_SVCD;
                            printf("X*VCD: Using SVCD PS\n");
                        }
                        else
                        {
                            // mpeg2, we do only DVD right now
                            if(hdr->frequency!=48000 || 
                                (hdr->encoding != WAV_MP2 && hdr->encoding!=WAV_AC3 && hdr->encoding!=WAV_LPCM))
                            {
                                GUI_Error_HIG(QT_TR_NOOP("Incompatible audio"), QT_TR_NOOP("For DVD, audio must be 48 kHz MP2, AC3 or LPCM."));
								goto finishvcdff;
                            }
                            mux=MUXER_DVD;
                            printf("X*VCD: Using DVD PS\n");
                        }
                }
            }
         }        
        // Create muxer
       
       
        switch (videoCodecGetType())
        {
                
                case CodecXVCD:
                        encoder=new EncoderFFMPEGMpeg1(FF_MPEG1,&ffmpeg1Codec);
                        printf("\n Using ffmpeg mpeg1 encoder\n");
                        break;
                case CodecXSVCD:
                        encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2SVCDCodec);
                        printf("\n Using ffmpeg mpeg2 encoder\n");
                        break;
                case CodecXDVD:
                        encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2DVDCodec);
                        printf("\n Using ffmpeg mpeg2 encoder (DVD)\n");
                        break;
                case CodecDVD:
                  encoder=new EncoderMpeg2enc(MPEG2ENC_DVD,&DVDCodec);
                  printf("\n Using mpeg2enc encoder (DVD)\n");
                  break;
                case CodecRequant:
                  if(!isMpeg12Compatible(avifileinfo->fcc))
                  {
                    GUI_Error_HIG("Incompatible Input","The input file must be mpeg2 to be able to use requant!");
                    return 0; // Fixme, do some cleanup 
                  }
                  encoder=new EncoderRequant(&RequantCodec);
                  printf("\n Using mpeg2 requant\n");
                  break;
                break;
                case CodecSVCD:
                  encoder=new EncoderMpeg2enc(MPEG2ENC_SVCD,&SVCDCodec);
                  printf("\n Using mpeg2enc encoder (SVCD)\n");
                  break;
                case CodecVCD:
                  encoder=new EncoderMpeg2enc(MPEG2ENC_VCD,&VCDCodec);
                  printf("\n Using mpeg2enc encoder (VCD)\n");
                  break;
                default:
                ADM_assert(0);
      }

      encoder->setLogFile(twoPass,total);

	  if (encoder->isDualPass())
	  {
		  printf("Verifying log file\n");

		  if (encoder->verifyLog(twoPass, total) && GUI_Question(QT_TR_NOOP("Reuse the existing log file?")))
			  reuse = 1;
	  }

      if(!encoder->configure(_incoming, reuse))
              goto finishvcdff;

      _buffer=new uint8_t[_page]; // Might overflow if _page only
      _outbuffer=new uint8_t[_page];

      ADM_assert(  _buffer);
      ADM_assert(  _outbuffer);

      encoding =new DIA_encoding(_fps1000);
      switch (videoCodecGetType())
      {
          case CodecVCD:
            encoding->setCodec(QT_TR_NOOP("libmpeg2enc VCD"));
            break;
          case CodecSVCD:
            encoding->setCodec(QT_TR_NOOP("libmpeg2enc SVCD"));
            break;
          case CodecDVD:
            encoding->setCodec(QT_TR_NOOP("libmpeg2enc DVD"));
            break;
          case CodecXVCD:
            encoding->setCodec(QT_TR_NOOP("FFmpeg MPEG-1 VBR"));
            break;
          case CodecXSVCD:
            encoding->setCodec(QT_TR_NOOP("FFmpeg MPEG-2 SVCD VBR"));
            break;
          case CodecXDVD:
            encoding->setCodec(QT_TR_NOOP("FFmpeg MPEG-2 DVD VBR"));
            break;
          case CodecRequant:
            encoding->setCodec(QT_TR_NOOP("MPEG Requantizer"));
            break;
          
          default:
            ADM_assert(0);
	}
        switch(mux)
          {
            case MUXER_NONE:encoding->setContainer(QT_TR_NOOP("MPEG ES"));break;
            case MUXER_TS:  encoding->setContainer(QT_TR_NOOP("MPEG TS"));break;
            case MUXER_VCD: encoding->setContainer(QT_TR_NOOP("MPEG VCD"));break;
            case MUXER_SVCD:encoding->setContainer(QT_TR_NOOP("MPEG SVCD"));break;
            case MUXER_DVD: encoding->setContainer(QT_TR_NOOP("MPEG DVD"));break;
            default:
                ADM_assert(0);
          }



        // pass 1
        if(encoder->isDualPass()) //Cannot be requant
        {
                        if(!reuse)
                        {
                                encoding->setPhasis (QT_TR_NOOP("Pass 1/2"));
                                encoder->startPass1();
                                bitstream.data=_buffer;
                                bitstream.bufferSize=_page;
                                for(uint32_t i=0;i<total;i++)
                                {
                                        bitstream.cleanup(i);
                                        if(!encoder->encode( i, &bitstream))//&len,(uint8_t *) _buffer,&flags))
                                        {
                                          GUI_Error_HIG(QT_TR_NOOP("Error in pass 1"), NULL);
                                        }
                                        encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total);
                                        if(!encoding->isAlive())
                                              goto finishvcdff;
                                }
                        }
                        encoder->startPass2();
                        encoding->reset();
                }
                
              switch(type)
              {
                case ADM_PS:
                  muxer=new mplexMuxer;
                  break;
                case ADM_TS:
                  muxer=new tsMuxer;
                  break;
                case ADM_ES:
                  break;
                default:
                  ADM_assert(0);
      
      
              }
              if(muxer)
              {
                if(!muxer->open(name,0,mux,avifileinfo,audio->getInfo()))
                {
                  printf("Muxer init failed\n");
				  goto finishvcdff;
                }
                double sample_time;

                sample_time=total;
                sample_time*=1000;
                sample_time/=_fps1000; // target_time in second
                sample_time*=audio->getInfo()->frequency;
                sample_target=(uint32_t)floor(sample_time);
              }
              else
              {
                file=fopen(name,"wb");
                if(!file)
                {
                  GUI_Error_HIG(QT_TR_NOOP("File error"), QT_TR_NOOP("Cannot open \"%s\" for writing."), name);
				  goto finishvcdff;
                }
              }
          if(encoder->isDualPass())
                  encoding->setPhasis (QT_TR_NOOP("Pass 2/2"));
          else
                  encoding->setPhasis (QT_TR_NOOP("Encoding"));

         // Set info for audio if any
         if(muxer)
         {
            if(!audioProcessMode())
                  encoding->setAudioCodec(QT_TR_NOOP("Copy"));
            else
                  encoding->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding));
         }
         //**********************************************************
         //  In that case we do multithreadedwriting (yes!)
         //**********************************************************

         if(mux==MUXER_DVD || mux==MUXER_SVCD || mux==MUXER_VCD)
         {
           pthread_t audioThread,videoThread,muxerThread;
           muxerMT context;
           //
           bitstream.data=_outbuffer;
           bitstream.bufferSize=_page;
           // 
           memset(&context,0,sizeof(context));
           context.videoEncoder=encoder;
           context.audioEncoder=audio;
           context.muxer=(mplexMuxer *)muxer;
           context.nbVideoFrame=total;
           context.audioTargetSample=sample_target;
           context.audioBuffer=audioBuffer;
           context.bitstream=&bitstream;
           context.opaque=(void *)encoding;

           // start audio thread
           ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioSlave,&context)); 
           ADM_assert(!pthread_create(&videoThread,NULL,(THRINP)defaultVideoSlave,&context)); 
           while(1)
           {
             accessMutex.lock();
             if(!encoding->isAlive())
             {
               context.audioAbort=1;
               context.videoAbort=1;
               printf("[mpegFF]Waiting for slaves\n");
               accessMutex.unlock();
               while(1)
               {
                 accessMutex.lock();
                 if(context.audioDone && context.videoDone)
                 {
                   printf("[mpegFF]Both audio & video done\n");
                   if(context.audioDone==1 && context.videoDone==1) ret=1;
                   accessMutex.unlock();
                   goto finishvcdff;
                 }
                 accessMutex.unlock();
                 ADM_usleep(50000);
 
               }
               
             }
             if(context.audioDone==2 || context.videoDone==2 ) //ERROR
             {
               context.audioAbort=1;
               context.videoAbort=1;
             }
             if(context.audioDone && context.videoDone)
             {
               printf("[mpegFF]Both audio & video done\n");
               if(context.audioDone==1 && context.videoDone==1) ret=1;
               accessMutex.unlock();
               goto finishvcdff;
             }
             accessMutex.unlock();
             ADM_usleep(1000*1000);
             
           }
           
         }
         //**********************************************************
         //  NOT MULTITHREADED
         //**********************************************************

      bitstream.data=_outbuffer;
      bitstream.bufferSize=_page;
      for(uint32_t i=0;i<total;i++)
      {
       	// get frame
                bitstream.cleanup(i);
                if(!encoder->encode( i,&bitstream))// &len,(uint8_t *) _outbuffer,&flags))
                {
                  GUI_Error_HIG(QT_TR_NOOP("Error in pass 2"), NULL);
                        goto finishvcdff;
                }
                if(!bitstream.len) continue;
                
                if(file)
                {
                    fwrite(_outbuffer,bitstream.len,1,file);
                }
                else
                {
                        uint32_t samples; 
                        
                        //printf("%lu %lu\n",i,dts);
                        
                        muxer->writeVideoPacket(&bitstream);
                        real_framenum++;
                        // _muxer->writeVideoPacket(len,_buffer_out,
                        //i-MPEG_PREFILL,_codec->getCodedPictureNumber());
                        if(total_sample<sample_target)
                        {
                            while(muxer->needAudio() && total_sample<sample_target) 
                            {				
                                if(!audio->getPacket(audioBuffer, &audioLen, &samples))	
                                { 
                                        break; 
                                }
                                if(audioLen) 
                                {
                                        muxer->writeAudioPacket(audioLen,audioBuffer); 
                                        total_sample+=samples;
                                        audioSum+=audioLen;
                                }
                            }
                        }
                
                }
                encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total);
                encoding->setAudioSize(audioSum);
                if(!encoding->isAlive ())
                                  goto finishvcdff;
        }
        ret=1;
finishvcdff:
        printf("[MPEGFF] Finishing..\n");
        delete encoding;
        end();

        if(file)
        {
                fclose(file);
                file=NULL;
        }
        else if(muxer)
        {
                muxer->close();
                delete muxer;
                muxer=NULL;
        }

        delete encoder;

		if (audio)
			deleteAudioFilter(audio);

        return ret;
}
示例#17
0
ReplyType glyphToText(admGlyph *glyph,admGlyph *head,char *decodedString)
{
 admGlyph *cand;
            //printf("2t: %d x %d\n",glyph->width,glyph->height);
            if(glyph->width<2 && glyph->height<2)
            {
                delete glyph;
                return ReplyOk;
            }
            cand=searchGlyph(head,glyph);
            if(!cand) // New glyph
            {
                char *string;
                // Draw it
                displaySmall(glyph); 
                gtk_label_set_text(GTK_LABEL(WID(labelText)),decodedString);
                gtk_editable_delete_text(GTK_EDITABLE(WID(entry)), 0,-1);
                
                //gtk_widget_set_sensitive(WID(buttonAccept),1);
                //gtk_widget_set_sensitive(WID(buttonSkip),1);
                //gtk_widget_set_sensitive(WID(entryEntry),1);
                
                gtk_widget_grab_focus (WID(entry));
                gtk_widget_grab_default (WID(buttonOk));
                
                //printf("i\n");
                switch(gtk_dialog_run(GTK_DIALOG(dialog)))
                {
                case actionIgnore:
                        glyph->code=NULL;
                        insertInGlyphTree(head,glyph);
                        //*nbGl++;
                        break;
                case actionCalibrate: return ReplyCalibrate;
                case actionAccept:
                    string =gtk_editable_get_chars(GTK_EDITABLE (WID(entry)), 0, -1);
                    if(string&& strlen(string))
                    {
                        glyph->code=ADM_strdup(string);
                        insertInGlyphTree(head,glyph);
                        //printf("New glyph:%s\n",glyph->code);
                        strcat(decodedString,glyph->code);
                        //*nbGl++;
                       
                    }
                    else delete glyph;
                    break;
                case actionSkip: //SKIP
                    return ReplySkip;
                    break;
                case actionSkipAll:
                    return ReplySkipAll;
                    break;
                case GTK_RESPONSE_CLOSE:
                  if(GUI_Question(QT_TR_NOOP("Sure ?"))) return ReplyClose;
                    break; // Abort
                    
                }
                gtk_editable_delete_text(GTK_EDITABLE(WID(entry)), 0,-1);
                //gtk_widget_set_sensitive(WID(buttonAccept),0);
                //gtk_widget_set_sensitive(WID(buttonSkip),0);
                //gtk_widget_set_sensitive(WID(entryEntry),0);
            }
            else
            {
                //printf("Glyph known :%s \n",cand->code);
                if(cand->code)
                    strcat(decodedString,cand->code);
                delete glyph;
            }
           return ReplyOk;  

}
uint8_t
GenericAviSaveProcess::setupVideo (char *name)
{
	_incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
 	frametogo=_incoming->getInfo()->nb_frames;
	encoding_gui->setFps(_incoming->getInfo()->fps1000);
	// anish
 	if(_incoming->getInfo()->width%8)
		{
                  if(!GUI_Question(QT_TR_NOOP("Width is not a multiple of 8\n continue anyway ?")))
			return 0;

		}

  _encode = getVideoEncoder (_incoming->getInfo()->width,_incoming->getInfo()->height);
  if (!_encode)
    return 0;

  // init compressor
  TwoPassLogFile=new char[strlen(name)+6];
  strcpy(TwoPassLogFile,name);
  strcat(TwoPassLogFile,".stat");
  _encode->setLogFile(TwoPassLogFile,frametogo);

  int reuse = 0;

  if (_encode->isDualPass())
  {
	  FILE *tmp;

	  if ((tmp = fopen(TwoPassLogFile,"rt")))
	  {
		  fclose(tmp);

		  if (GUI_Question(QT_TR_NOOP("Reuse the existing log file?")))
			  reuse = 1;
	  }
  }
 
  if (!_encode->configure (_incoming, reuse))
    {
      delete 	_encode;
      _encode = NULL;
      GUI_Error_HIG (QT_TR_NOOP("Filter init failed"), NULL);
      return 0;
    };
 
  memcpy (&_bih, video_body->getBIH (), sizeof (_bih));
  _bih.biWidth = _incoming->getInfo ()->width;
  _bih.biHeight = _incoming->getInfo ()->height;
  _bih.biSize=sizeof(_bih);
  _bih.biXPelsPerMeter=_bih.biClrUsed=_bih.biYPelsPerMeter=0;

  _mainaviheader.dwTotalFrames= _incoming->getInfo ()->nb_frames;
_mainaviheader.dwMicroSecPerFrame=0;

  printf("\n Saved as %ld x %ld\n",_bih.biWidth,_bih.biHeight);
  _bih.biCompression=fourCC::get((uint8_t *)_encode->getCodecName());
   
  encoding_gui->setCodec(_encode->getDisplayName());
  
  // init save avi
//-----------------------2 Pass--------------------------------------
  if (_encode->isDualPass ())
    {
      uint8_t *buffer;
      uint32_t len, flag;
	int r, frameDelay = 0;

 	aprintf("\n** Dual pass encoding**\n");

	if(!reuse)
 	{
	
      	guiSetPhasis (QT_TR_NOOP("1st Pass"));
      	aprintf("**Pass 1:%lu\n",frametogo);
     	buffer = new uint8_t[_incoming->getInfo ()->width *
		    _incoming->getInfo ()->height * 3];

      	_encode->startPass1 ();

        bitstream.bufferSize = _incoming->getInfo()->width * _incoming->getInfo()->height * 3;
        bitstream.data=buffer;

		for (uint32_t cf = 0; cf < frametogo; cf++)
		{
			if (guiUpdate (cf, frametogo))
			{
abt:
				GUI_Error_HIG (QT_TR_NOOP("Aborting"), NULL);
				delete[] buffer;
				return 0;
			}

			for (;;)
			{
				bitstream.cleanup(cf);

				if (cf + frameDelay >= frametogo)
				{
					if (_encode->getRequirements() & ADM_ENC_REQ_NULL_FLUSH)
						r = _encode->encode(UINT32_MAX, &bitstream);
					else
						r = 0;
				}
				else
					r = _encode->encode(cf + frameDelay, &bitstream);

				if (!r)
				{
					printf("Encoding of frame %lu failed!\n", cf);
					goto abt;
				}

				if (bitstream.len == 0 && (_encode->getRequirements() & ADM_ENC_REQ_NULL_FLUSH))
				{
					printf("skipping frame: %u size: %i\n", cf + frameDelay, bitstream.len);
					frameDelay++;
				}
				else
					break;
			}

			encoding_gui->setFrame(cf,bitstream.len,bitstream.out_quantizer,frametogo);
		}

	encoding_gui->reset();
      	delete[]buffer;	
     	aprintf("**Pass 1:done\n");
    }// End of reuse

      if(!_encode->startPass2 ())
      {
      	printf("Pass2 ignition failed\n");
      	return 0;
	}
   }   //-------------------------/VBR-----------------------------------
  // init save avi

// now we build the new stream !
    	aprintf("**main pass:\n");

		memcpy(&_videostreamheader,video_body->getVideoStreamHeader (),sizeof(_videostreamheader));
		memcpy(&_videostreamheader.fccHandler	,_encode->getFCCHandler(),4);
		_videostreamheader.fccType	=fourCC::get((uint8_t *)"vids");
		_videostreamheader.dwScale=1000;
		_videostreamheader.dwRate= _incoming->getInfo ()->fps1000;

    		memcpy(&_mainaviheader	,video_body->getMainHeader (),sizeof(_mainaviheader));


  		  _mainaviheader.dwWidth=_bih.biWidth;
    		_mainaviheader.dwHeight=_bih.biHeight;
    		_videostreamheader.dwQuality=10000;

    uint8_t *data;
    uint32_t dataLen=0;

    _encode->hasExtraHeaderData( &dataLen,&data);
  	if (!writter->saveBegin (name,
			   &_mainaviheader,
			   frameEnd - frameStart + 1,
			   &_videostreamheader,
			   &_bih,
			   data,dataLen,
			   (AVDMGenericAudioStream *) audio_filter,
			   NULL))
    	{
      		return 0;
    	}
  aprintf("Setup video done\n");
  bitstream.data=vbuffer;
  bitstream.bufferSize=MAXIMUM_SIZE * MAXIMUM_SIZE * 3;
  return 1;
  //---------------------
}
void  A_SaveAudioNVideo(char *name)
{
	 uint32_t needSmart=0,fl;
     GenericAviSave	*nw;
     aviInfo info;

     video_body->getVideoInfo(&info);

     printf("\n video process mode : %d",videoProcessMode);
     if (!videoProcessMode)
     {
       			if(video_body->isMultiSeg()) needSmart=1;
          			video_body->getFlags(frameStart,&fl);
             		if(!(fl&AVI_KEY_FRAME)) needSmart=1;

				if(needSmart) printf("\n probably need smart copy mode\n");
    	
    		if( !isMpeg4Compatible(  info.fcc)
#ifdef USE_FFMPEG
			  && !isMSMpeg4Compatible(info.fcc)

#endif      
      			)
             {
                	printf("\n not encodable, cancelling smart mode\n");
                 	needSmart=0;

               }
    			

#ifdef HAVE_ENCODER
			if(needSmart &&
   										GUI_Question("You may need smart copy.\n Enable it ?"))
             		{
                      nw=new   GenericAviSaveSmart;
                 	}
                  else
                  {
                           nw=new   GenericAviSaveCopy;
                    }



#else
     		nw=new   GenericAviSaveCopy;
#endif
       }
       else
       {
#ifdef HAVE_ENCODER
			printf("\n Process mode\n");
     		nw=new   GenericAviSaveProcess;
#else
			GUI_Alert("\n No encoder , cannot save in process mode");
   			return ;
#endif

        }
     if(!nw->saveAvi(name))
     {
        	GUI_Alert(" AVI NOT saved");
       }
       else
        	GUI_Alert(" Saved successfully");

       delete nw;


}
/**
        \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;
}
示例#21
0
uint8_t prepareDualPass(uint32_t bufferSize,uint8_t *buffer,char *TwoPassLogFile,DIA_encoding *encoding_gui,Encoder *_encode,uint32_t total)
{
      uint32_t len, flag;
      FILE *tmp;
      uint8_t reuse=0,r;
      ADMBitstream bitstream(0);
      uint32_t prefill=0;
      uint32_t sent=0;
      
        aprintf("\n** Dual pass encoding**\n");

        if((tmp=fopen(TwoPassLogFile,"rt")))
        {
                fclose(tmp);
                if(GUI_Question(QT_TR_NOOP("\n Reuse the existing log-file ?")))
                {
                        reuse=1;
                }
        }
        
        if(!reuse)
        {
        
                encoding_gui->setPhasis ("1st Pass");
                aprintf("**Pass 1:%lu\n",total);
                _encode->startPass1 ();
                bitstream.data=buffer;
                bitstream.bufferSize=bufferSize;
                
preFilling2:
             bitstream.cleanup(0);
             if(!_encode->encode ( prefill, &bitstream))//&len, videoBuffer, &flags,&displayFrame))
             {
                        printf("MP4:First frame error\n");
                        GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL);
                        return 0;
              }
              sent++;
              if(!bitstream.len)
              {
                prefill++;
                goto preFilling2;
              }

                printf("Pass 1 prefill : %u\n",prefill);
                for (uint32_t cf = 1; cf < total; cf++)
                {
                        if (!encoding_gui->isAlive())
                        {
                                abt:
                                    GUI_Error_HIG (QT_TR_NOOP("Aborting"), NULL);
                                return 0;
                        }
                        bitstream.cleanup(cf);
                        if(!prefill || cf+prefill<total) 
                        {
                            r=_encode->encode ( prefill+cf, &bitstream);
                        }
                          else
                          {
                              r=_encode->encode ( total-1, &bitstream);
                          }
                        if (!r)
                        {
                                printf("\n Encoding of frame %lu failed !\n",cf);
                                return 0;
                        }
                        sent++;
                        encoding_gui->setFrame(cf,bitstream.len,bitstream.out_quantizer,total);
                }
                encoding_gui->reset();
                aprintf("**Pass 1:done\n");
        }// End of reuse

        if(!_encode->startPass2 ())
        {
                printf("Pass2 ignition failed\n");
                return 0;
        }
        printf("First pass : send %u frames\n",sent);
        encoding_gui->setPhasis ("2nd Pass");
        return 1;
}
示例#22
0
void HandleAction (Action action)
{
  uint32_t nf = 0;
  uint32_t old;

  admScopedMutex autolock(&singleThread); // make sure only one thread at a time calls this
  
  ADM_warning("************ %s **************\n",getActionName(action));

  // handle out of band actions
  // independant load not loaded
//------------------------------------------------
        if(action==ACT_RUN_SCRIPT)
        {
            GUI_FileSelRead("Select script/project to run", A_RunScript);
            
            return;
        }
	if (action >= ACT_SCRIPT_ENGINE_FIRST && action < ACT_SCRIPT_ENGINE_LAST)
	{
		int engineIndex = (action - ACT_SCRIPT_ENGINE_FIRST) / 3;
		int actionId = (action - ACT_SCRIPT_ENGINE_FIRST) % 3;

		tempEngine = getScriptEngines()[engineIndex];

		switch (actionId)
		{
			case 0:
				GUI_FileSelRead("Select script to run", RunScript);
				break;

			case 1:
				GUI_FileSelRead("Select script to debug", DebugScript);
				break;

			case 2:
				GUI_FileSelWrite(QT_TRANSLATE_NOOP("adm","Select script to save"), SaveScript);
				UI_refreshCustomMenu();
				break;
		}

		return;
	}

	if (action >= ACT_SCRIPT_ENGINE_SHELL_FIRST && action < ACT_SCRIPT_ENGINE_SHELL_LAST)
	{
		IScriptEngine *shellEngine = getScriptEngines()[action - ACT_SCRIPT_ENGINE_SHELL_FIRST];

		if ((shellEngine->capabilities() & IScriptEngine::DebuggerShell) == IScriptEngine::DebuggerShell)
		{
			shellEngine->openDebuggerShell();
		}
		else
		{
			interactiveScript(shellEngine);
		}

		return;
	}

  switch (action)
    {
        case ACT_TimeShift:
                                A_TimeShift();
                                return;
        case ACT_Goto:
                                brokenAct();
                                return;
        case ACT_AVS_PROXY:
                                GUI_avsProxy();
                                return;
        case ACT_BUILT_IN:
                                DIA_builtin();
                                return;
        case ACT_RECENT0:
        case ACT_RECENT1:
        case ACT_RECENT2:
        case ACT_RECENT3:
			{
                const char **name;
                int rank;

                name=prefs->get_lastfiles();
                rank=(int)action-ACT_RECENT0;
                ADM_assert(name[rank]);
                A_openAvi (name[rank]);
                return;
			}
        case ACT_RECENT_PROJECT0:
        case ACT_RECENT_PROJECT1:
        case ACT_RECENT_PROJECT2:
        case ACT_RECENT_PROJECT3:
			{
                const char **name = prefs->get_lastprojectfiles();
                int rank = (int)action - ACT_RECENT_PROJECT0;

                ADM_assert(name[rank]);
                call_scriptEngine(name[rank]);

                return;
			}
	case ACT_VIDEO_CODEC_CONFIGURE:
    		videoEncoder6Configure();
            return;
    case ACT_ContainerConfigure:
            {
            int index=UI_GetCurrentFormat();
            ADM_mux_configure(index);
            return;
            }
    case ACT_VIDEO_CODEC_CHANGED:
		{
    		int nw=UI_getCurrentVCodec();
    		videoEncoder6_SetCurrentEncoder(nw);
            return;
		}
   case ACT_AUDIO_CODEC_CHANGED:
	   {
            int nw=UI_getCurrentACodec();
            audioCodecSetByIndex(0,nw);
            return;
	   }
    case ACT_PLUGIN_INFO:
            DIA_pluginsInfo();
            return;
	case ACT_OPEN_APP_LOG:
		GUI_OpenApplicationLog();
		return;
	case ACT_OPEN_APP_FOLDER:
		GUI_OpenApplicationDataFolder();
		return;

    case ACT_ABOUT :
    		 DIA_about( );
		 return;
    case ACT_AUDIO_CODEC_CONFIGURE:
      audioCodecConfigure(0);
      return;
    case ACT_AUDIO_FILTERS:
        {
            EditableAudioTrack *ed=video_body->getDefaultEditableAudioTrack();
            if(ed) ed->audioEncodingConfig.audioFilterConfigure();
        }
      return;
    case ACT_PREFERENCES:
        if(playing) return;
    	if(DIA_Preferences())
        {
            ADM_info("Saving prefs\n");
            prefs->save ();
        }
        return;
    case ACT_SavePref:
        prefs->save ();
        return;
    case ACT_EXIT:
          if(playing)
          {
              ADM_info("Stopping playback...\n");
              GUI_PlayAvi();
          }
          ADM_info("Closing ui\n");
	  UI_closeGui();
          
          return;
      break;
    default:
      break;

    }

  if (playing)			// only allow some action
    {
      switch (action)
        {
        case ACT_PlayAvi:
        case ACT_StopAvi:
          break;
        default:
          return;
        }
    }
  // not playing,
  // restict disabled uncoded actions
  if ((int) action >= ACT_DUMMY)
    {
      GUI_Error_HIG (QT_TRANSLATE_NOOP("adm","Not coded in this version"), NULL);
      return;
    }
  // allow only if avi loaded
  if (!avifileinfo)
    {
      switch (action)
        {
          case ACT_JOG:
                break;
          case ACT_OPEN_VIDEO:
                GUI_FileSelRead (QT_TRANSLATE_NOOP("adm","Select Video File..."), (SELFILE_CB *)A_openAvi);
                break;
          default:
            break;
        }
        return;
    }

  // Dispatch actions, we have a file loaded
  if(action>ACT_NAVIGATE_BEGIN && action < ACT_NAVIGATE_END)
  {
    return HandleAction_Navigate(action);
  }
  if(action>ACT_SAVE_BEGIN && action < ACT_SAVE_END)
  {
    return HandleAction_Save(action);
  }

  switch (action)
    {
       case ACT_SAVE_PY_SCRIPT:
       {
           IScriptEngine *engine=getPythonScriptEngine();
                if(!engine)
                {
                    GUI_Error_HIG("No engine","tinyPy script is not enabled in this build");
                    break;
                }
                char fileName[1024];
                if(FileSel_SelectWrite("Saving tinypy project",fileName,1000, NULL))
                {
                        int l=strlen(fileName);
                        if(l>3)
                        {
                            char *tail=fileName+l-3;
                            if(tail[0]!='.'|| tail[1]!='p'|| tail[2]!='y')
                                strcat(fileName,".py");
                        }
                        A_saveScript(engine, fileName);
                }
                 break;
       }
                break;
       case ACT_JOG:
                A_jog();
                break;

       case ACT_CLOSE:
              GUI_close();
              break;

        case ACT_ZOOM_1_4:
        case ACT_ZOOM_1_2:
        case ACT_ZOOM_1_1:
        case ACT_ZOOM_2_1:
        case ACT_ZOOM_4_1:
                currentZoom=(renderZoom)((action-ACT_ZOOM_1_4)+ZOOM_1_4);
                changePreviewZoom(currentZoom);
                admPreview::samePicture();
                break;
        case ACT_AUDIO_SELECT_TRACK:
                A_audioTrack();
                break;

    case ACT_OPEN_VIDEO:
        GUI_FileSelRead (QT_TRANSLATE_NOOP("adm","Select Video File..."),(SELFILE_CB *) A_openAvi);
        break;
    case ACT_APPEND_VIDEO:
        GUI_FileSelRead (QT_TRANSLATE_NOOP("adm","Select Video File to Append..."),(SELFILE_CB *) A_appendAvi);
        break;
    case ACT_VIDEO_PROPERTIES:
        DIA_properties ();
        break;
    case ACT_PlayAvi:
      GUI_PlayAvi ();
      break;

#define TOGGLE_PREVIEW ADM_PREVIEW_OUTPUT
    case ACT_PreviewChanged:
    {
        ADM_PREVIEW_MODE oldpreview=getPreviewMode(),newpreview=(ADM_PREVIEW_MODE)UI_getCurrentPreview();
          printf("Old preview %d, New preview mode : %d\n",oldpreview,newpreview);

          if(oldpreview==newpreview)
          {
            return;
          }
            admPreview::stop();
            setPreviewMode(newpreview);
            admPreview::start();
//            admPreview::update(curframe);
      }
      break;
    case ACT_StopAvi:
      if (playing)
	GUI_PlayAvi ();
      break;
    case ACT_SetPostProcessing:
      A_setPostproc();
      break;
    case ACT_MarkA:
    case ACT_MarkB:
    {
      bool swapit=0;
      uint64_t markA,markB;
      uint64_t pts=admPreview::getCurrentPts();
      if( prefs->get(FEATURES_SWAP_IF_A_GREATER_THAN_B, &swapit) != RC_OK )     swapit = 1;

      markA=video_body->getMarkerAPts();
      markB=video_body->getMarkerBPts();
      if (action == ACT_MarkA)
            markA=pts;
      else
            markB=pts;
      if (markA>markB && swapit )	// auto swap
        {
          uint64_t y;
          y = markA;
          markA=markB;
          markB=y;
        }
        video_body->setMarkerAPts(markA);
        video_body->setMarkerBPts(markB);
        UI_setMarkers (markA, markB);
      break;
    }
    case ACT_Copy:
    {
                uint64_t markA,markB;
                markA=video_body->getMarkerAPts();                
                markB=video_body->getMarkerBPts();
                if(markA>markB)
                {
                    uint64_t p=markA;
                    markA=markB;
                    markB=p;
                }
  		video_body->copyToClipBoard (markA,markB);
		break;
    }
    case ACT_Paste:
            {
              uint64_t currentPts=video_body->getCurrentFramePts();
              video_body->pasteFromClipBoard(currentPts);
              video_body->getVideoInfo (avifileinfo);
              A_ResetMarkers();
      	      ReSync ();
            }
            break;
      break;

    case ACT_Undo:
        if (avifileinfo)
        {
            uint64_t currentPts=video_body->getCurrentFramePts();

            if(video_body->undo())
            {
                video_body->getVideoInfo(avifileinfo);
                ReSync();
                A_ResetMarkers();
                A_Rewind();

                if(currentPts<=video_body->getVideoDuration()) GUI_GoToTime(currentPts);
            }
        }
        break;

    case ACT_ResetSegments:
       if(avifileinfo)
         if(GUI_Question(QT_TRANSLATE_NOOP("adm","Are you sure?")))
        {
            video_body->resetSeg();
            video_body->getVideoInfo (avifileinfo);

            A_ResetMarkers();
      		ReSync ();

            // forget last project file
            video_body->setProjectName("");
        }
	break;

    case ACT_Delete:
    case ACT_Cut:
        {
            uint64_t a=video_body->getMarkerAPts();
            uint64_t b=video_body->getMarkerBPts();
            if(false==video_body->remove(a,b))
            {
                GUI_Error_HIG("Cutting","Error while cutting out.");
            }
            else
            {
              A_ResetMarkers();
              A_Resync(); // total duration & stuff
              // Rewind to first frame...
              //A_Rewind();
              GUI_GoToTime(a);

            }
        }

      break;
      // set decoder option (post processing ...)
    case ACT_DecoderOption:
      video_body->setDecodeParam ( admPreview::getCurrentPts());

      break;
    case ACT_VIDEO_FILTERS:
        GUI_handleVFilter();
        break;

   case ACT_HEX_DUMP:
      GUI_showCurrentFrameHex();
      break;
   case ACT_SIZE_DUMP:
      GUI_showSize();
      break;
   case ACT_TimeShift:
      A_TimeShift();
      break;
    default:
      printf ("\n unhandled action %d\n", action);
      ADM_assert (0);
      return;

    }
}
uint8_t
GenericAviSaveProcess::setupVideo (char *name)
{
	_notnull=0;
	_incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
 	frametogo=_incoming->getInfo()->nb_frames;
	encoding_gui->setFps(_incoming->getInfo()->fps1000);
	// anish
 	if(_incoming->getInfo()->width%8)
		{
		if(!GUI_Question("Width is not a multiple of 8\n continue anyway ?"))
			return 0;

		}

  _encode = getVideoEncoder (_incoming->getInfo()->width,_incoming->getInfo()->height);
  if (!_encode)
    return 0;

  // init compressor
  TwoPassLogFile=new char[strlen(name)+6];
  strcpy(TwoPassLogFile,name);
  strcat(TwoPassLogFile,".stat");
 _encode->setLogFile(TwoPassLogFile,frametogo);
 
 
  if (!_encode->configure (_incoming))
    {
      delete 	_encode;
      _encode = NULL;
      GUI_Error_HIG ("Filter init failed", NULL);
      return 0;
    };
 
  memcpy (&_bih, video_body->getBIH (), sizeof (_bih));
  _bih.biWidth = _incoming->getInfo ()->width;
  _bih.biHeight = _incoming->getInfo ()->height;
  _bih.biSize=sizeof(_bih);
  _bih.biXPelsPerMeter=_bih.biClrUsed=_bih.biYPelsPerMeter=0;

  _mainaviheader.dwTotalFrames= _incoming->getInfo ()->nb_frames;
_mainaviheader.dwMicroSecPerFrame=0;

  printf("\n Saved as %ld x %ld\n",_bih.biWidth,_bih.biHeight);
  _bih.biCompression=fourCC::get((uint8_t *)_encode->getCodecName());
   
  encoding_gui->setCodec(_encode->getDisplayName());
  
  // init save avi
//-----------------------VBR--------------------------------------
  if (_encode->isDualPass ())
    {
      uint8_t *buffer;
      uint32_t len, flag;
      FILE *tmp;
	uint8_t reuse=0;

 	aprintf("\n** Dual pass encoding**\n");

	
	
	if((tmp=fopen(TwoPassLogFile,"rt")))
	{
		fclose(tmp);
		if(GUI_Question("\n Reuse the existing log-file ?"))
		{
			reuse=1;
		}
	}
	
	if(!reuse)
 	{
	
      	guiSetPhasis ("1st Pass");
      	aprintf("**Pass 1:%lu\n",frametogo);
     	buffer = new uint8_t[_incoming->getInfo ()->width *
		    _incoming->getInfo ()->height * 3];

      	_encode->startPass1 ();
      //__________________________________
      //   now go to main loop.....
      //__________________________________

      	for (uint32_t cf = 0; cf < frametogo; cf++)
	{
	  if (guiUpdate (cf, frametogo))
	    {
	    abt:
	      GUI_Error_HIG ("Aborting", NULL);
	      delete[]buffer;
	      return 0;
	    }

	  if (!_encode->encode (cf, &len, buffer, &flag))
		{
			printf("\n Encoding of frame %lu failed !\n",cf);
	    		goto abt;
		}
	   encoding_gui->setQuant(_encode->getLastQz());
	   encoding_gui->feedFrame(len);		
	}
//      guiStop ();
	encoding_gui->reset();
      	delete[]buffer;	
     	aprintf("**Pass 1:done\n");
    }// End of reuse

      if(!_encode->startPass2 ())
      {
      	printf("Pass2 ignition failed\n");
      	return 0;
	}
   }   //-------------------------/VBR-----------------------------------
  // init save avi

// now we build the new stream !
    	aprintf("**main pass:\n");

		memcpy(&_videostreamheader,video_body->getVideoStreamHeader (),sizeof(_videostreamheader));
		memcpy(&_videostreamheader.fccHandler	,_encode->getFCCHandler(),4);
		_videostreamheader.fccType	=fourCC::get((uint8_t *)"vids");
		_videostreamheader.dwScale=1000;
		_videostreamheader.dwRate= _incoming->getInfo ()->fps1000;

    		memcpy(&_mainaviheader	,video_body->getMainHeader (),sizeof(_mainaviheader));


  		  _mainaviheader.dwWidth=_bih.biWidth;
    		_mainaviheader.dwHeight=_bih.biHeight;
    		_videostreamheader.dwQuality=10000;

    uint8_t *data;
    uint32_t dataLen=0;

    _encode->hasExtraHeaderData( &dataLen,&data);
  	if (!writter->saveBegin (name,
			   &_mainaviheader,
			   frameEnd - frameStart + 1,
			   &_videostreamheader,
			   &_bih,
			   data,dataLen,
			   (AVDMGenericAudioStream *) audio_filter,
			   NULL))
    	{
      		return 0;
    	}
  aprintf("Setup video done\n");
  return 1;
  //---------------------
}
//________________________________________________
uint8_t	ADM_ogmWriteProcess::initVideo(char *name)
{		
uint32_t w,h,fps1000,fcc;
		
	_incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
 	_togo=_incoming->getInfo()->nb_frames;
  	_encode = getVideoEncoder (_incoming->getInfo()->width,_incoming->getInfo()->height);
	if (!_encode)
    		return 0;
 	
	TwoPassLogFile=new char[strlen(name)+6];
  	strcpy(TwoPassLogFile,name);
  	strcat(TwoPassLogFile,".stat"); 	  
   
 	_encode->setLogFile(TwoPassLogFile,_togo);
	
  	if (!_encode->configure (_incoming))
    	{
      		delete 	_encode;
      		_encode = NULL;
      		GUI_Alert ("Init of filter failed");
      		return 0;
    	};
 	w= _incoming->getInfo ()->width;
	h=_incoming->getInfo ()->height;
	fps1000=_incoming->getInfo ()->fps1000;
	_fps1000=fps1000;
	fcc= fourCC::get((uint8_t *)_encode->getCodecName());
   	_videoBuffer=new uint8_t[w*h*3];
  	encoding_gui->setCodec(_encode->getDisplayName());
   
//-----------------------VBR--------------------------------------
	if (_encode->isDualPass ())
	{
		uint8_t *buffer;
		uint32_t len, flag;
		FILE *tmp;
		uint8_t reuse=0;

		aprintf("\n** Dual pass encoding**\n");

		if((tmp=fopen(TwoPassLogFile,"rt")))
		{
			fclose(tmp);
			if(GUI_Question("\n Reuse the existing log-file ?"))
			{
				reuse=1;
			}
		}
	
		if(!reuse)
 		{
      			aprintf("**Pass 1:%lu\n",_togo);
      			_encode->startPass1 ();
			encoding_gui->setCodec((char *)_encode->getCodecName());
			encoding_gui->setPhasis("Pass one");
      			//__________________________________
      			//   now go to main loop.....
      			//__________________________________
      			for (uint32_t cf = 0; cf < _togo; cf++)
			{	  
	  			if (!_encode->encode (cf, &len, _videoBuffer, &flag))
				{
					printf("\n Encoding of frame %lu failed !\n",cf);
	    				return 0;
				}
				encoding_gui->feedFrame(len);
				encoding_gui->setFrame(cf,_togo);
				encoding_gui->setQuant(_encode->getLastQz());
				if(!encoding_gui->isAlive())
				{
					return 0;
				}
			}
		     	aprintf("**Pass 1:done\n");
    		}// End of reuse

      		if(!_encode->startPass2 ())
		{
      			printf("Pass2 ignition failed\n");
      			return 0;
		}
		encoding_gui->setPhasis("Pass 2");
	}   //-------------------------/VBR-----------------------------------
	else
	{
		encoding_gui->setPhasis("Encoding");
	}
  // init save avi

// now we build the new stream !
    	aprintf("**main pass:\n");


		stream_header header;
		int64_t dur64;
		uint32_t dur32;
		uint16_t dur16;
		
		memset(&header,0,sizeof(header));
		
		memcpy(&(header.streamtype),"video\0\0\0",8);
		MEMCPY(&(header.subtype),&fcc,4);
		
		//header.size=sizeof(header);
		dur32=sizeof(header);
		MEMCPY(&header.size,&dur32,4);
		MEMCPY(&(header.video.width),&w,4);
		MEMCPY(&(header.video.height),&h,4);
		// Timing ..
		double duration; // duration in 10us
		duration=fps1000;
		duration=1000./duration;
		duration*=1000*1000;
		duration*=10;
		
		dur64=(int64_t)duration;
		
		MEMCPY(&header.time_unit,&dur64,8);
		dur64=1;
		MEMCPY(&header.samples_per_unit,&dur64,8);
		
		dur32=0x10000;
		MEMCPY(&header.buffersize,&dur32,4);
		
		dur16=24;
		MEMCPY(&header.bits_per_sample,&dur16,2);
		
		
		//header.default_len=1;
		dur32=1;
		MEMCPY(&header.default_len,&dur32,4);
		
		return videoStream->writeHeaders(sizeof(header),(uint8_t *)&header); // +4 ?

}
int A_Save(const char *name)
{
uint32_t end;
int ret=0;
	// depending on the type we save a avi, a mpeg or a XVCD
	CodecFamilty family;
	family= videoCodecGetFamily();
	// in case of copy mode, we stick to avi file format
	if(!videoProcessMode())
	{
		family=CodecFamilyAVI;
		if( UI_GetCurrentFormat()==ADM_PS ||UI_GetCurrentFormat()==ADM_TS )  // exception
		{
			family=CodecFamilyMpeg;
		}
                        
	}
        else
        {
                if(UI_GetCurrentFormat()==ADM_AVI_DUAL)
                {
                  GUI_Error_HIG(QT_TR_NOOP("Dual audio can only be used in copy mode"),QT_TR_NOOP( "Select Copy as the video codec."));
                        return 0;
                }
        }
	printf("**saving:**\n");
	// Check if we need to do a sanity B frame check
	if(!videoProcessMode())
	{	
		uint32_t pb;
		end=avifileinfo->nb_frames;
		// if the last frame is the last frame (!)
		// we add one to keep it, else we systematically skip
		// the last frame
#if 0					
		if(frameEnd==end-1) end=frameEnd+1;
		else
			end=frameEnd;

		if(!video_body->sanityCheckRef(frameStart,end,&pb))
		{
			if(pb)
			{
				GUI_Error_HIG("Cannot save the file", "The video starts/ends with a lonely B-frame. Please remove it.");
				return 0;
			}
			if(!GUI_Question("Warning !\n Bframe has lost its reference frame\nContinue ?"))
				return 0;
		}
#endif
		// Alter frameEnd so that it is not a B frame	
		// as frameEnd -1 position	
		uint32_t tgt=frameEnd;;
		uint32_t flag=0,found=0;
		
		// need to do something ?
		if(frameEnd>frameStart)
		{
			tgt=frameEnd;
			if(tgt==end-1) tgt++;
			video_body->getFlags(tgt-1,&flag);
			if((frameEnd&AVI_B_FRAME))
			{
				printf("Last frame is a B frame, choosing better candidate\n");
				 // The last real one is not a I/P Frame
				 // Go forward or rewind
				 if(tgt<end-1)
				{	// Try next if possible
					video_body->getFlags(tgt,&flag);
					if(!(flag&AVI_B_FRAME))
					{
						printf("Taking next frame as last frame %lu\n",tgt+1);
				 		frameEnd=tgt+1;
				 		found=1;
					}
				}
				if(!found) // next frame not possible, rewind
				{
					if(tgt>=end-2) tgt=end-2;
					while(tgt>frameStart)
					{
						printf("Trying :%lu\n",tgt);
						video_body->getFlags(tgt,&flag);
						if(!(flag&AVI_B_FRAME))
						{
							printf("Taking previous frame as last frame %lu\n",tgt+1);
				 			frameEnd=tgt+1;
				 			found=1;
							break;
						}
						else tgt--;
					}
				}
				ADM_assert(found);
			}
		}
		
		
		
	}
        printf("Output format:%d\n",UI_GetCurrentFormat());
	switch(family)
	{
		case CodecFamilyAVI:
					printf(" AVI family\n");
					switch(UI_GetCurrentFormat())
					{
						case ADM_DUMMY:
					                            			ret=oplug_dummy(name);
					                            			break;
						case ADM_FLV:
                            			ret=oplug_flv(name);
                            			break;
                        case ADM_MP4:
                        case ADM_PSP:
                        case ADM_MATROSKA:
                        
                                                    ret=oplug_mp4(name,UI_GetCurrentFormat());
                                                    break;
						case ADM_AVI:
								ret=A_SaveAudioNVideo(name);
								break;
						case ADM_OGM:
								ret=ogmSave(name);
								break;
						case ADM_ES:
								ret=ADM_saveRaw(name);
								break;
						case ADM_AVI_DUAL:
								ret=A_SaveAudioDualAudio(name);
								break;
                                                case ADM_AVI_PAK:
								ret=A_SavePackedVop(name);
								break;

						case ADM_AVI_UNP:
								ret=A_SaveUnpackedVop(name);
								break;
						default:
                                                  GUI_Error_HIG(QT_TR_NOOP("Incompatible output format"), NULL);
					}
					break;
		case CodecFamilyMpeg:
					printf(" MPEG family\n");
					if(!videoProcessMode())
					{
						
						printf("Using pass through\n");
                                                switch(UI_GetCurrentFormat())
                                                {
                                                  case ADM_PS:
                                                  case ADM_TS:
						          ret=mpeg_passthrough(name,UI_GetCurrentFormat());
                                                          break;
                                                  default:
                                                    GUI_Error_HIG(QT_TR_NOOP("Incompatible output format"), NULL);
                                                }
                                                break;
                                        } // THERE IS NO BREAK HERE, NOT A MISTAKE!
		case CodecFamilyXVCD:
                    switch(UI_GetCurrentFormat())
                    {
                        case ADM_TS:
                        case ADM_PS:
                        case ADM_ES:
                                ret=oplug_mpegff(name,UI_GetCurrentFormat());;
                                break;
                        default:
                          GUI_Error_HIG(QT_TR_NOOP("Incompatible output format"), NULL);
                    }
                    break;
                default:
                            ADM_assert(0);
                            return 0;
        }
        getFirstVideoFilter(0,avifileinfo->nb_frames);
        return ret;
}