/*______________________________________________
        Save the project as a script
______________________________________________*/
uint8_t ADM_Composer::saveAsScript (const char *name, const char *outputname)
{
const char *truefalse[]={"false","true"};
printf("\n **Saving script project **\n");
  char *    tmp;

  if (!_nb_segment)
    return 1;

  FILE *    fd;

  if( !(fd = qfopen (name, "wt")) ){
    fprintf(stderr,"\ncan't open script file \"%s\" for writing: %u (%s)\n",
                   name, errno, strerror(errno));
    return 0;
  }

// Save source and segment
//______________________________________________
  qfprintf( fd,"//AD  <- Needed to identify");
  qfprintf (fd, "//\n");
  qfprintf (fd, "//--automatically built--\n");
  qfprintf (fd, "//--Project: %s\n\n",name);

  qfprintf (fd, "var app = new Avidemux();\n");
  qfprintf (fd,"\n//** Video **\n");
  qfprintf (fd,"// %02ld videos source \n", _nb_video);
  char *nm;
  uint32_t vop=!!(video_body->getSpecificMpeg4Info()&ADM_VOP_ON);

  for (uint32_t i = 0; i < _nb_video; i++)
    {
        nm=ADM_cleanupPath(_videos[i]._aviheader->getMyName() );
        if(vop)
        {
          qfprintf(fd,"app.forceUnpack();\n");
        }
        if(!i)
        {
                qfprintf (fd, "app.load(\"%s\");\n", nm);
        }
        else
        {
            qfprintf (fd, "app.append(\"%s\");\n", nm);
        }
        ADM_dealloc(nm);
    }
  
  qfprintf (fd,"//%02ld segments\n", _nb_segment);
  qfprintf (fd,"app.clearSegments();\n");
  
 

for (uint32_t i = 0; i < _nb_segment; i++)
    {
        uint32_t src,start,nb;
                src=_segments[i]._reference;
                start=_segments[i]._start_frame;
                nb=_segments[i]._nb_frames;
                qfprintf (fd, "app.addSegment(%lu,%lu,%lu);\n",src,start,nb);
    }
// Markers
//
        qfprintf(fd,"app.markerA=%d;\n",frameStart);
        qfprintf(fd,"app.markerB=%d;\n",frameEnd);
// Reordering : Warning works only for video with one source video
//        if(video_body->isReordered(0) && !vop)
        {
 //           qfprintf(fd,"app.rebuildIndex();\n");
        }
        
// postproc
//___________________________

        uint32_t pptype, ppstrength,ppswap;
                video_body->getPostProc( &pptype, &ppstrength, &ppswap);
                qfprintf(fd,"\n//** Postproc **\n");
                qfprintf(fd,"app.video.setPostProc(%d,%d,%d);\n",pptype,ppstrength,ppswap);

// fps
	if( avifileinfo ){
	  aviInfo info;
		video_body->getVideoInfo(&info);
		qfprintf(fd,"\napp.video.setFps1000(%u);\n",info.fps1000);
	}

// Filter
//___________________________
        qfprintf(fd,"\n//** Filters **\n");
        filterSaveScriptJS(fd);

// Video codec
//___________________________
		uint8_t *extraData;
		uint32_t extraDataSize;

		qfprintf(fd, "\n//** Video Codec conf **\n");
		videoCodecGetConf(&extraDataSize, &extraData);

		if (videoCodecGetType() == CodecExternal)
			qfprintf(fd, "app.video.codecPlugin(\"%s\", \"%s\", \"%s\", \"%s\");\n", videoCodecPluginGetGuid(), videoCodecGetName(), videoCodecGetMode(), extraData);
		else
		{
			qfprintf(fd, "app.video.codec(\"%s\", \"%s\", \"", videoCodecGetName(), videoCodecGetMode());

			// Now deal with extra data
			qfprintf(fd, "%d ", extraDataSize);

			if (extraDataSize)
				for(int i = 0; i < extraDataSize; i++)
					qfprintf(fd, "%02x ", extraData[i]);

			qfprintf(fd, "\");\n");
		}
        
// Audio Source
//______________________________________________

// Audio
//______________________________________________

   uint32_t delay,bitrate;
   
   qfprintf(fd,"\n//** Audio **\n");
   qfprintf(fd,"app.audio.reset();\n");

   // External audio ?
        char *audioName;
        AudioSource  source;

        source=getCurrentAudioSource(&audioName);
        if(!audioName) audioName="";

        if(source!=AudioAvi)
        {
                char *nm=ADM_cleanupPath(audioName);
                qfprintf(fd,"app.audio.load(\"%s\",\"%s\");\n", audioSourceFromEnum(source),nm); 
                ADM_dealloc(nm);
        }
        else 
        { // Maybe not the 1st track
          int source;
               source=video_body->getCurrentAudioStreamNumber(0);
               if(source)
                        qfprintf(fd,"app.audio.setTrack(%d);\n", source); 
                        
        }
   getAudioExtraConf(&bitrate,&extraDataSize,&extraData);
   qfprintf(fd,"app.audio.codec(\"%s\",%d,%d,\"", audioCodecGetName(),bitrate,extraDataSize); 
   for(int i=0;i<extraDataSize;i++)
   {
     qfprintf(fd,"%02x ",extraData[i]);
   }
   qfprintf(fd,"\");\n");
   
   
   //qfprintf(fd,"app.audio.process=%s;\n",truefalse[audioProcessMode()]);
   qfprintf(fd,"app.audio.normalizeMode=%d;\n",audioGetNormalizeMode());
   qfprintf(fd,"app.audio.normalizeValue=%d;\n",audioGetNormalizeValue());
   qfprintf(fd,"app.audio.delay=%d;\n",audioGetDelay());
   qfprintf(fd,"app.audio.mixer(\"%s\");\n",getCurrentMixerString());

    // VBR ?
    if(currentaudiostream)
    {
        uint32_t encoding=currentaudiostream->getInfo()->encoding;
        if((encoding==WAV_MP3 || encoding==WAV_MP2))
        {
            qfprintf(fd,"app.audio.scanVBR();\n");
        }
    }


   // Change fps ?
        switch(audioGetFpsConv())
        {
                case FILMCONV_NONE:      ;break;
                case FILMCONV_PAL2FILM:  qfprintf(fd,"app.audio.pal2film=true;\n");break;
                case FILMCONV_FILM2PAL:  qfprintf(fd,"app.audio.film2pal=true;\n");break;
                default:ADM_assert(0);
        }
   // Resampling
        switch(audioGetResampling())
        {
                case RESAMPLING_NONE:         ;break;
                case RESAMPLING_CUSTOM:        qfprintf(fd,"app.audio.resample=%u;\n",audioGetResample());break;
                default:ADM_assert(0);
        }
        if (audioGetDrc()) qfprintf(fd,"app.audio.drc=true;\n");
        
        
  // Mixer

  // container
        
  qfprintf(fd,"app.setContainer(\"%s\");\n",getCurrentContainerAsString());
  if(outputname)
  {
        char *o=ADM_cleanupPath(outputname);
        qfprintf(fd,"setSuccess(app.save(\"%s\"));\n",o);
        ADM_dealloc(o);
  }
  else
  {
        qfprintf(fd,"setSuccess(%d);\n",1);
  }
  qfprintf(fd,"//app.Exit();\n");
  qfprintf(fd,"\n//End of script\n");
  // All done
  qfclose (fd);
  
  return 1;


}
diaElemBar::~diaElemBar()
{
  ADM_dealloc(paramTitle);
}
uint8_t  DIA_v2v(char **vobname, char **ifoname,char **vobsubname)
{
uint8_t ret=0;
char *tmp=NULL,*tmp2=NULL,*tmp3=NULL;

        GtkWidget *dialog;

        dialog=create_dialog1();
        gtk_register_dialog(dialog);
        gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(buttonVob),actionVOB);
        gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(buttonIfo),actionIFO);
        gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(buttonVobSub),actionVOBSUB);

#define ENTRY_SET(x,y) {gtk_write_entry_string(WID(x),*y);}

        ENTRY_SET(entryIfo,ifoname);
        ENTRY_SET(entryVob,vobname);
        ENTRY_SET(entryVobSub,vobsubname);

        while(1)
        {
                switch(gtk_dialog_run(GTK_DIALOG(dialog)))
                {
                        case actionVOB:
                                        {
                                        
                                        int r;
                                                GUI_FileSelRead(_("Select Vob file to scan"),&tmp);
                                                if(!tmp) continue;
                                                gtk_editable_delete_text(GTK_EDITABLE(WID(entryVob)), 0,-1);
                                                gtk_editable_insert_text(GTK_EDITABLE(WID(entryVob)), tmp, strlen(tmp), &r);
                                                ADM_dealloc(tmp);
                                        }
                                        break;
                        case actionIFO:
                                        {
                                        
                                        int r;
                                                GUI_FileSelRead(_("Select ifo file to use"),&tmp);
                                                if(!tmp) continue;
                                                gtk_editable_delete_text(GTK_EDITABLE(WID(entryIfo)), 0,-1);
                                                gtk_editable_insert_text(GTK_EDITABLE(WID(entryIfo)), tmp, strlen(tmp), &r);
                                                ADM_dealloc(tmp);
                                        }
                                        break;
                        case actionVOBSUB:
                                        {
                                        
                                        int r;
                                                GUI_FileSelWrite(_("Select vobsub to write"),&tmp);
                                                if(!tmp) continue;
                                                gtk_editable_delete_text(GTK_EDITABLE(WID(entryVobSub)), 0,-1);
                                                gtk_editable_insert_text(GTK_EDITABLE(WID(entryVobSub)), tmp, strlen(tmp), &r);
                                                ADM_dealloc(tmp);
                                        }
                                        break;

                                        break;
                        case GTK_RESPONSE_OK: 
                                        {
                                           tmp=gtk_editable_get_chars(GTK_EDITABLE (WID(entryVob)), 0, -1);
                                           if(!tmp || !*tmp)
                                           {
                                             GUI_Error_HIG(_("Invalid vobname"),_("Please select or enter a valid vob name"));
                                                        continue;
                                            }
                                           tmp2=gtk_editable_get_chars(GTK_EDITABLE (WID(entryIfo)), 0, -1);
                                           if(!tmp2 || !*tmp2)
                                           {
                                             GUI_Error_HIG(_("Invalid ifo"),_("Please select or enter a valid ifo file"));
                                                        continue;
                                            }
                                           tmp3=gtk_editable_get_chars(GTK_EDITABLE (WID(entryVobSub)), 0, -1);
                                           if(!tmp3 || !*tmp3 )
                                           {
                                             GUI_Error_HIG(_("Invalid vobsubname"),_("Please select or enter a valid vobsub file"));
                                                        continue;
                                            }
                                            if(*vobname) ADM_dealloc(*vobname);
                                            if(*ifoname) ADM_dealloc(*ifoname);
                                            if(*vobsubname) ADM_dealloc(*vobsubname);

                                             *vobname=*ifoname=*vobsubname=NULL;

                                            *vobname=ADM_strdup(tmp);
                                            *ifoname=ADM_strdup(tmp2);
                                            *vobsubname=(char *)ADM_alloc(strlen(tmp3)+5); //ADM_strdup(tmp3);
                                            strcpy(*vobsubname,tmp3);
                                            if(tmp3[strlen(tmp3)-1]!='x') strcat(*vobsubname,".idx");
                                            ret=1;
                                        }
                        default: goto _nxt;
                }
        }
_nxt:
        gtk_unregister_dialog(dialog);
        gtk_widget_destroy(dialog);
        return ret;
}
uint8_t DIA_vobsub(vobSubParam *param)
{
    char *name=NULL;
    int32_t shift;
    int ret,ext,r;

    ret=0;
    ext=0;

    if(param->subname)
        name=ADM_strdup(param->subname);
    shift=param->subShift;

    while(!ext)
    {
        dialog=create_dialog1();
        gtk_register_dialog(dialog);
        //gtk_transient(dialog);
        gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(buttonSelect), GTK_RESPONSE_APPLY);


        fq=new GtkWidget*[ADM_MAX_LANGUAGE];

        // Upload if any
        if(name)
        {
            update(name,param->index);
        }
        else
        {
            gtk_label_set_text(GTK_LABEL(WID(labelVobsub)),QT_TR_NOOP("none"));
        }
        gtk_write_entry(WID(entryShift),shift);
        r=gtk_dialog_run(GTK_DIALOG(dialog));
        shift=gtk_read_entry(WID(entryShift));
        switch(r)
        {
        case GTK_RESPONSE_APPLY:
        {
            char *file;
            GUI_FileSelRead(QT_TR_NOOP("Select .idx file"),&file);
            if(file)
            {
                if(name) ADM_dealloc(name);
                name=NULL;
                name=ADM_strdup(file); // Leak ?
            }
        }
        break;
        case GTK_RESPONSE_OK:
            ret=1;
            ext=1;
            if(name)
            {
                ADM_dealloc(name);
            }
            name=ADM_strdup(gtk_label_get_text(GTK_LABEL(WID(labelVobsub))));
            if(param->subname)
                ADM_dealloc(param->subname);
            param->subname=name;
            //

            param->index=indeces[getRangeInMenu(WID(optionmenu1))];
            param->subShift=shift;
            break;
        case GTK_RESPONSE_CANCEL:
            ret=0;
            ext=1;
            break;
        default:
            break;
        }
        delete [] fq;
        gtk_unregister_dialog(dialog);
        gtk_widget_destroy(dialog);

    }

    return ret;
}
/**
    \fn addFile
    \brief	Load or append a file.	The file type is determined automatically and the ad-hoc video decoder is spawned
    
    @param name: filename
    @param mode: 0 open, 1 append
    @param forcedType : if !=Unknown_FileType, it enables to force the file type

    @return 1 on success, 0 on failure
        

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

UNUSED_ARG(mode);
	_haveMarkers=0; // by default no markers are present

  if (_nb_video == (max_videos - 1))
  {
	  max_videos += MAX_VIDEO;
	  printf("extending max_videos: %i\n", max_videos);

	  _VIDEOS *vid = new _VIDEOS[max_videos];

	  memset(vid, 0, sizeof(_VIDEOS) * max_videos);
	  memcpy(vid, _videos, sizeof(_VIDEOS) * (max_videos - MAX_VIDEO));

	  delete _videos;
	  _videos = vid;
  }

  if (_nb_segment == max_seg - 1)
	  extendSegmentBuffer();

  ADM_assert (_nb_segment < max_seg);
  ADM_assert (_nb_video < max_videos);

  // Autodetect file type ?
  if(Unknown_FileType==type)
  {
      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);
      
      case ASF_FileType:
              _videos[_nb_video]._aviheader=new asfHeader; 
              ret = _videos[_nb_video]._aviheader->open(name); 
              if(!ret)
              {
                delete _videos[_nb_video]._aviheader;
                printf("Trying mpeg\n"); 
                goto thisIsMpeg; 
              }
              break;
      OPEN_AS (NewMpeg_FileType,dmxHeader);
      // 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;
      
    case Nuppel_FileType:
	{ // look if the idx exists
	  char *tmpname = (char*)ADM_alloc(strlen(name)+strlen(".idx")+1);
		ADM_assert(tmpname);
		sprintf(tmpname,"%s.idx",name);
		if(addFile(tmpname))
		{
			return 1; // Memleak ?
		}
		ADM_dealloc(tmpname);
		// open .nuv file
		_videos[_nb_video]._aviheader=new nuvHeader;
		ret = _videos[_nb_video]._aviheader->open(name);
		// we store the native .nuv file in the edl
		// the next load of the edl will open .idx instead
		break;
	}
      OPEN_AS (BMP_FileType, picHeader);
      OPEN_AS (Matroska_FileType, mkvHeader);
      OPEN_AS (FLV_FileType, flvHeader);
      OPEN_AS (AvsProxy_FileType, avsHeader);
      OPEN_AS (_3GPP_FileType, MP4Header);
      OPEN_AS (Ogg_FileType, oggHeader);
      OPEN_AS (AMV_FileType, amvHeader);

    case Mpeg_FileType:
thisIsMpeg:
    	// look if the idx exists
	char tmpname[256];
	ADM_assert(strlen(name)+5<256);
	strcpy(tmpname,name);
	strcat(tmpname,".idx");
        if(ADM_fileExist(tmpname))
        {
	       return addFile(tmpname);
        }
	/* check for "Read-only file system" */
	{
                int fd = ADM_open(tmpname,O_CREAT|O_EXCL|O_WRONLY,S_IRUSR|S_IWUSR);
                if( fd >= 0 )
                {
                    close(fd);
                    unlink(tmpname);
                    printf("Filesystem is writable\n");
		}else if( errno == EROFS ){
		  char *tmpdir = getenv("TMPDIR");
#ifdef __WIN32
                        printf("Filesystem is not writable, looking for somewhere else\n");
			if( !tmpdir )
				tmpdir = "c:";
			snprintf(tmpname,256,"%s%s.idx",tmpdir,strrchr(name,'\\'));
#else
			if( !tmpdir )
				tmpdir = "/tmp";
			snprintf(tmpname,256,"%s%s.idx",tmpdir,strrchr(name,'/'));
#endif
			tmpname[255] = 0;
                        printf("Storing index in %s\n",tmpname);
                    if(ADM_fileExist(tmpname))
                    {
                        printf("Index present, loading it\n");
                        return addFile(tmpname);
                    }
                }
        }
        if(tryIndexing(name,tmpname))
        {
                return addFile (tmpname);
        }
        return 0;
      break;
	case WorkBench_FileType:

  		return loadWorbench(name);
#if 0
        case Script_FileType:
                return parseScript(name);
#endif
	case ECMAScript_FileType:
                printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n");
                printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n");
                printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n");
                return 0;
		
                
    default:
      if (type == Unknown_FileType)
	{
	  printf ("\n not identified ...\n");
	}
      else
        GUI_Error_HIG(QT_TR_NOOP("File type identified but no loader support detected..."),
                      QT_TR_NOOP("May be related to an old index file."));
      return 0;
    }

   // check opening was successful
   if (ret == 0) {
     char str[512+1];
     snprintf(str,512,QT_TR_NOOP("Attempt to open %s failed!"), name);
      str[512] = '\0';
      GUI_Error_HIG(str,NULL);
      delete _videos[_nb_video]._aviheader;
      return 0;
   }

   /* check for resolution */
   if( _nb_video ){
      /* append operation */
      aviInfo info0, infox;
      _videos[   0     ]._aviheader->getVideoInfo (&info0);
      _videos[_nb_video]._aviheader->getVideoInfo (&infox);

      if(info0.width != infox.width || info0.height != infox.height)
	  {
         GUI_Error_HIG(QT_TR_NOOP("Video dimensions don't match."), QT_TR_NOOP("You cannot mix different video dimensions yet. Using the partial video filter later will not work around this problem. The workaround is:\n\n1) \"Resize\" / \"Add Border\" / \"Crop\" each stream to the same resolution\n2) Concatenate them together"));
		 delete _videos[_nb_video]._aviheader;
         return 0;
      }
   }
 
  // else update info
  _videos[_nb_video]._aviheader->getVideoInfo (&info);
  _videos[_nb_video]._aviheader->setMyName (name);
  
  // Printf some info about extradata
  {
    uint32_t l=0;
    uint8_t *d=NULL;
    _videos[_nb_video]._aviheader->getExtraHeaderData(&l,&d);
    if(l && d)
    {
        printf("The video codec has some extradata (%d bytes)\n",l);
        mixDump(d,l);
        printf("\n");
    }
  }
  // 1st if it is our first video we update postproc
 if(!_nb_video)
 {
        uint32_t type,value;

        if(!prefs->get(DEFAULT_POSTPROC_TYPE,&type)) type=3;
        if(!prefs->get(DEFAULT_POSTPROC_VALUE,&value)) value=3; 	

	deletePostProc(&_pp );
 	initPostProc(&_pp,info.width,info.height);
	_pp.postProcType=type;
	_pp.postProcStrength=value;
	_pp.forcedQuant=0;
	updatePostProc(&_pp);

	if(_imageBuffer) delete _imageBuffer;
	_imageBuffer=new ADMImage(info.width,info.height);
 	_imageBuffer->_qSize= ((info.width+15)>>4)*((info.height+15)>>4);
	_imageBuffer->quant=new uint8_t[_imageBuffer->_qSize];
	_imageBuffer->_qStride=(info.width+15)>>4;
 }
 ADM_AudiocodecWMA::~ADM_AudiocodecWMA()
 {
        avcodec_close(_context);
        ADM_dealloc(_context);
        _contextVoid=NULL;
}    
//______________________________________________________
// Check and build a confCouple from the args
// the filter_param arg is a template for that filter
//______________________________________________________
CONFcouple *filterBuildCouple(FILTER_PARAM *param,uint32_t nb,Arg *args)
{
int found,l;
int trans[MAXPARAM];
	if(param->nb>VARIABLE_PARAMS)
	{
		// Variable # of parameters
		// We check we have at least what is required by the template
		for(int i=0;i<(param->nb-VARIABLE_PARAMS);i++)
				{
					l=strlen(param->param[i]);
					ADM_assert(l);
					found=-1;
					for(int j=0;j<nb;j++)
					{
						if(!strncasecmp(param->param[i],args[j].arg.string,l))
						{
							if(strlen(args[j].arg.string)>l && args[j].arg.string[l]=='=')
							{
								found=j;
								break;
							}
						}
					}
					if(found==-1)
					{	
						printf("Param : %s not found or incorrect\n",param->param[i]);
						 return NULL;
					}
				}
				// if we get here, it means we found each param, time to build the couples
				CONFcouple *couple;
				couple=new CONFcouple(nb);
				for(int i=0;i<nb;i++)
				{
					char *copy=ADM_strdup(args[i].arg.string);
					// Search "="
					char *where=strstr(copy,"=");
					if(!where) ADM_assert(0);
					*where=0;
					if(!couple->setCouple(copy,where+1))
						{
							printf("Set couple failed\n");
							delete couple;
							return NULL;
						}
					ADM_dealloc(copy);
				}
				return couple;
	}
	//********************* Constant # of parameters #################
	else
	{
		if(nb!=param->nb )
		{
			printf("# of parameters mismatch: expected %d, got %d\n",nb,param->nb);
			return NULL;
		}
		// For each param check we are ok
		// the generic form is name=value
		// name should be the same as in the param array
		for(int i=0;i<nb;i++)
		{
			l=strlen(param->param[i]);
			ADM_assert(l);
			found=-1;
			for(int j=0;j<nb;j++)
			{
				if(!strncasecmp(param->param[i],args[j].arg.string,l))
				{
					if(strlen(args[j].arg.string)>l && args[j].arg.string[l]=='=')
					{
						found=j;
						trans[i]=j;
						break;
					}
				}
			}
			if(found==-1)
			{	
				printf("Param : %s not found or incorrect\n",param->param[i]);
				 return NULL;
			}
		}
		// if we get here, it means we found each param, time to build the couples
		CONFcouple *couple;
		couple=new CONFcouple(nb);
		for(int i=0;i<nb;i++)
		{
			l=strlen(param->param[i]);
			if(!couple->setCouple(param->param[i],args[ trans[i]].arg.string+l+1))
				{
					printf("Set couple failed\n");
					delete couple;
					return NULL;
				}
		}
		return couple;
	}
	
}
uint8_t DIA_ass(ASSParams *param)
{
  uint8_t r=0;
  GtkWidget *dialog=create_dialog1();
  gtk_register_dialog(dialog);
  
  SPIN_SET(spinbuttonScale,font_scale);
  SPIN_SET(spinbuttonSpacing,line_spacing); 
  SPIN_SET(spinbuttonTop,top_margin);
  SPIN_SET(spinbuttonBottom,bottom_margin);
  if(param->subfile)
  {
    int r;
    char *s=(char *)(param->subfile);
    gtk_editable_delete_text(GTK_EDITABLE(WID(entrySub)), 0,-1);
    gtk_editable_insert_text(GTK_EDITABLE(WID(entrySub)), s, strlen(s), &r);
  }
  ASSOCIATE(button1,LOADSUB);
  /* Upload */
  int x=0,d;
  while(!x)
  {
      d=gtk_dialog_run(GTK_DIALOG(dialog));
      switch(d)
      {
        case LOADSUB:
          {
            char *name=NULL;
            GUI_FileSelRead("Select ASS/SSA file",&name);
            if(name)
            {
                int r;
                gtk_editable_delete_text(GTK_EDITABLE(WID(entrySub)), 0,-1);
                gtk_editable_insert_text(GTK_EDITABLE(WID(entrySub)), name, strlen(name), &r);
                ADM_dealloc(name);
            }
          }
            break;
        case GTK_RESPONSE_OK:
        case GTK_RESPONSE_APPLY:
              {
                SPIN_GET(spinbuttonScale,font_scale);
                SPIN_GET(spinbuttonSpacing,line_spacing); 
                SPIN_GETI(spinbuttonTop,top_margin);
                SPIN_GETI(spinbuttonBottom,bottom_margin);
                char *n;
                if(param->subfile)
                {
                  ADM_dealloc(param->subfile);
                  param->subfile=NULL;
                }
                n=gtk_editable_get_chars(GTK_EDITABLE (WID(entrySub)), 0, -1);
                printf("Name :%s\n",n);
                param->subfile=(ADM_filename *)ADM_strdup(n);
                r=1;
                x=1;
                break;
              }
        default:
                r=0;
                x=1;
                break;
      }
  }
  gtk_unregister_dialog(dialog);
  gtk_widget_destroy(dialog);
  return r; 
}
/**
    \fn saveAsJpg
    \brief save current image into filename, into jpg format
*/
bool  ADMImage::saveAsJpg(const char *filename)
{

AVCodecContext   *context=NULL;   
AVFrame          frame;     
bool             result=false;
AVCodec          *codec=NULL;
int              sz=0,r=0;
ADM_byteBuffer   byteBuffer;

    context=avcodec_alloc_context();
    if(!context) 
    {
        printf("[saveAsJpg] Cannot allocate context\n");
        return false;
    }
    codec=avcodec_find_encoder(CODEC_ID_MJPEG);
    if(!codec)
    {
        printf("[saveAsJpg] Cannot allocate codec\n");
        goto jpgCleanup;
    }
    context->pix_fmt =PIX_FMT_YUV420P;
    context->strict_std_compliance = -1;
    context->time_base.den=1;
    context->time_base.num=1;
    context->width=_width;
    context->height=_height;
    context->flags |= CODEC_FLAG_QSCALE;
    r=avcodec_open(context, codec); 
    if(r<0)
    {
        printf("[saveAsJpg] Cannot mix codec and context\n");
        ADM_dealloc (context);
        return false;
    }
    // Setup our image & stuff....
        

        frame.linesize[0] = GetPitch(PLANAR_Y); 
        frame.linesize[1] = GetPitch(PLANAR_U); 
        frame.linesize[2] = GetPitch(PLANAR_V); 
        
        frame.data[0] = GetWritePtr(PLANAR_Y);
        frame.data[2] = GetWritePtr(PLANAR_U);
        frame.data[1] = GetWritePtr(PLANAR_V);
    // Grab a temp buffer
    
    // Encode!
     
      frame.quality = (int) floor (FF_QP2LAMBDA * 2+ 0.5);

      byteBuffer.setSize(_width*_height*4);
	  

        if ((sz = avcodec_encode_video (context, byteBuffer.at(0), _width*_height*4, &frame)) < 0)
        {
            printf("[jpeg] Error %d encoding video\n",sz);
            goto  jpgCleanup;
        }
        // Ok now write our file...
        {
            FILE *f=ADM_fopen(filename,"wb");
            if(f)
            {
                fwrite(byteBuffer.at(0),sz,1,f);
                fclose(f);
                result=true;
            }else
            {
                printf("[saveAsJpeg] Cannot open %s for writing!\n",filename);

            }
       }

// Cleanup
jpgCleanup:
    if(context)
    {
        avcodec_close (context);
        av_free (context);
    }

    context=NULL;
    return result;
}
/**
	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
  ADM_assert (_nb_segment < MAX_SEG);
  ADM_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);
      OPEN_AS (ASF_FileType, asfHeader);
      OPEN_AS (NewMpeg_FileType,dmxHeader);
      // 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;
      
    case Nuppel_FileType:
	{ // look if the idx exists
	  char *tmpname = (char*)ADM_alloc(strlen(name)+strlen(".idx")+1);
		ADM_assert(tmpname);
		sprintf(tmpname,"%s.idx",name);
		if(addFile(tmpname))
		{
			return 1; // Memleak ?
		}
		ADM_dealloc(tmpname);
		// open .nuv file
		_videos[_nb_video]._aviheader=new nuvHeader;
		ret = _videos[_nb_video]._aviheader->open(name);
		// we store the native .nuv file in the edl
		// the next load of the edl will open .idx instead
		break;
	}
      OPEN_AS (BMP_FileType, picHeader);
      OPEN_AS (Matroska_FileType, mkvHeader);
      OPEN_AS (AvsProxy_FileType, avsHeader);
      OPEN_AS (_3GPP_FileType, _3GPHeader);
       OPEN_AS (Ogg_FileType, oggHeader);

    case Mpeg_FileType:
    	// look if the idx exists
	char tmpname[256];
	ADM_assert(strlen(name)+5<256);;
	strcpy(tmpname,name);
	strcat(tmpname,".idx");
        if(ADM_fileExist(tmpname))
        {
	       return addFile(tmpname);
        }
	/* check for "Read-only file system" */
	{
                int fd = open(tmpname,O_CREAT|O_EXCL|O_WRONLY,S_IRUSR|S_IWUSR);
                if( fd >= 0 )
                {
                    close(fd);
                    unlink(tmpname);
                    printf("Filesystem is writable\n");
		}else if( errno == EROFS ){
		  char *tmpdir = getenv("TMPDIR");
#ifdef CYG_MANGLING
                        printf("Filesystem is not writable, looking for somewhere else\n");
			if( !tmpdir )
				tmpdir = "c:";
			snprintf(tmpname,256,"%s%s.idx",tmpdir,strrchr(name,'\\'));
#else
			if( !tmpdir )
				tmpdir = "/tmp";
			snprintf(tmpname,256,"%s%s.idx",tmpdir,strrchr(name,'/'));
#endif
			tmpname[255] = 0;
                        printf("Storing index in %s\n",tmpname);
                    if(ADM_fileExist(tmpname))
                    {
                        printf("Index present, loading it\n");
                        return addFile(tmpname);
                    }
                }
        }
        if(tryIndexing(name,tmpname))
        {
                return addFile (tmpname);
        }
        return 0;
      break;
	case WorkBench_FileType:

  		return loadWorbench(name);
#if 0
        case Script_FileType:
                return parseScript(name);
#endif
	case ECMAScript_FileType:
                printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n");
                printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n");
                printf("****** This is an ecmascript, run it with avidemux2 --run yourscript *******\n");
                return 0;
		
                
    default:
      if (type == Unknown_FileType)
	{
	  printf ("\n not identified ...\n");
	}
      else
        GUI_Error_HIG(_("File type identified but no loader support detected..."),
                      _("May be related to an old index file."));
      return 0;
    }

   // check opening was successful
   if (ret == 0) {
     char str[512+1];
     snprintf(str,512,_("Attempt to open %s failed!"), name);
      str[512] = '\0';
      GUI_Error_HIG(str,NULL);
      delete _videos[_nb_video]._aviheader;;
      return 0;
   }

   /* check for resolution */
   if( _nb_video ){
      /* append operation */
      aviInfo info0, infox;
      _videos[   0     ]._aviheader->getVideoInfo (&info0);
      _videos[_nb_video]._aviheader->getVideoInfo (&infox);
      if( info0.width != infox.width || info0.height != infox.height ){
        char str[512+1];
         str[0] = '\0';
         if( info0.width != infox.width )
            strcpy(str,"width");
         if( info0.height != infox.height )
            snprintf(str+strlen(str),512-strlen(str),
              "%sheight%sdifferent between first and this video stream",
                 (strlen(str)?" and ":""),
                 (strlen(str)?" are ":" is ") );
         str[512] = '\0';
         GUI_Error_HIG(str,_("You cannot mix different video dimensions yet. Using the partial video filter later, will not work around this problem. The workaround is:\n1.) \"resize\" / \"add border\" / \"crop\" each stream to the same resolution\n2.) concatinate them together"));
         delete _videos[_nb_video]._aviheader;;
         return 0;
      }
   }
 
  // else update info
  _videos[_nb_video]._aviheader->getVideoInfo (&info);
  _videos[_nb_video]._aviheader->setMyName (name);
  // 1st if it is our first video we update postproc
 if(!_nb_video)
 {
        uint32_t type,value;

        if(!prefs->get(DEFAULT_POSTPROC_TYPE,&type)) type=3;
        if(!prefs->get(DEFAULT_POSTPROC_VALUE,&value)) value=3; 	

	deletePostProc(&_pp );
 	initPostProc(&_pp,info.width,info.height);
	_pp.postProcType=type;
	_pp.postProcStrength=value;
	_pp.forcedQuant=0;
	updatePostProc(&_pp);

	if(_imageBuffer) delete _imageBuffer;
	_imageBuffer=new ADMImage(info.width,info.height);
 	_imageBuffer->_qSize= ((info.width+15)>>4)*((info.height+15)>>4);
	_imageBuffer->quant=new uint8_t[_imageBuffer->_qSize];
	_imageBuffer->_qStride=(info.width+15)>>4;
 }
/**
    \fn dtor
*/
Decimate::~Decimate(void)
{
		if (sum != NULL) ADM_dealloc(sum);
		sum=NULL;
}
//static uint8_t Vbuffer[7.0*5.6*3];
//AVDMGenericVideoStream *getFirstVideoFilter( void)
//
//_____________________________________________________________
void GUI_PlayAvi(void)
{
    uint32_t  time_e, time_a = 0;
    uint32_t err = 0, acc = 0;
    uint32_t max;

    uint32_t framelen,flags;
    AVDMGenericVideoStream *filter;

    vids = 0, auds = 0, dauds = 0;
    // check we got everything...
    if (!avifileinfo)
	return;
  if((curframe+1)>= avifileinfo->nb_frames-1)
  {
      printf("No frame left\n");
      return;
   }
    if (avifileinfo->fps1000 == 0)
        return;
    if (playing)
      {
        stop_req = 1;
        return;
      }

	uint32_t priorityLevel;

	originalPriority = getpriority(PRIO_PROCESS, 0);
	prefs->get(PRIORITY_PLAYBACK,&priorityLevel);
	setpriority(PRIO_PROCESS, 0, ADM_getNiceValue(priorityLevel));

  uint32_t played_frame=0;
  uint32_t remaining=avifileinfo->nb_frames-curframe;

    
    if(getPreviewMode()==ADM_PREVIEW_OUTPUT)
    {
            filter=getLastVideoFilter(curframe,remaining);
    }
    else
    {
            filter=getFirstVideoFilter(curframe,remaining );
    }
    
    max=filter->getInfo()->nb_frames;

    // compute how much a frame lasts in ms
    one_frame = (uint32_t) floor(1000.*1000.*10. / filter->getInfo()->fps1000);
    err = one_frame % 10;
    one_frame /= 10; // Duration of a frame in ms, err =leftover in 1/10 ms
    
    // go to RealTime...    
    printf("One frame : %lu, err=%lu ms\n", one_frame, err);
    
    // prepare 1st frame

    stop_req = 0;
    playing = 1;

#ifdef HAVE_AUDIO
    ComputePreload();
#endif
    
     
     //renderStartPlaying();
// reset timer reference
    resetTime();
    admPreview::deferDisplay(1,curframe);
    admPreview::update(played_frame);
    do
    {
        vids++;
        admPreview::displayNow(played_frame);;
        update_status_bar();
        if (time_a == 0)
            time_a = getTime(0);
        // mark !
        //printf("\n Rendering %lu frame\n",curframe);
        // read frame in chunk

        if((played_frame)>=(max-1))
        {
            printf("\nEnd met (%lu  / %lu )\n",played_frame,max);
            goto abort_play;
         }
        
        admPreview::update(played_frame+1);;
	curframe++;
	played_frame++;

#ifdef HAVE_AUDIO
	  FillAudio();
#endif

	  time_e = getTime(1);
	  acc += err;
	  if (acc > 10)
	    {
		acc -= 10;
		time_a++;
	    }
	  time_a += one_frame;
	  // delta a is next frame time
	  // time is is current time
	  delta = time_a - time_e;
	  if (delta <= 0)
	    {
		//if(delta<-19)  // allow 19 ms late without warning...
		// tick seems to be ~ 18 ms
		//printf("\n Late ....,due : %lu ms / found : %lu \n",
		//                                              time_a,time_e); 
		// a call to whatever sleep function will last at leat 10 ms
		// give some time to GTK                
	
	  } else
	    {
		// a call to whatever sleep function will last at leat 10 ms
		// give some time to GTK                		
		if (delta > 10)
		    GUI_Sleep(delta - 10);
	    }
     	//
            UI_purge();
            if(getPreviewMode()==ADM_PREVIEW_SEPARATE )
            {
              UI_purge();
              UI_purge(); 
            }
      }
    while (!stop_req);

abort_play:
		// ___________________________________
    // Flush buffer   
    // go back to normal display mode
    //____________________________________
    playing = 0;
          
	   getFirstVideoFilter( );

           admPreview::deferDisplay(0,0);
           UI_purge();
           // Updated by expose ? 
           admPreview::update(curframe);
           UI_purge();
     	   update_status_bar();
#ifdef HAVE_AUDIO
    if (currentaudiostream)
      {
	  if (wavbuf)
	      ADM_dealloc(wavbuf);
          deleteAudioFilter(NULL);
	  currentaudiostream->endDecompress();
	  AVDM_AudioClose();

      }
#endif
    // done.

	setpriority(PRIO_PROCESS, 0, originalPriority);
};
Exemple #13
0
/**
    \fn saveAsPngInternal
    \brief save current image into filename in PNG format
*/
bool ADMImage::saveAsPngInternal(const char *filename)
{
    AVCodecContext *context=NULL;
    AVFrame *frame=NULL;
    AVCodec *codec=NULL;
    bool result=false;
    int sz=_width*_height*3, r=0;
    uint8_t *out;
    int xss[3], xds[3];
    uint8_t *xsp[3], *xdp[3];
    ADMColorScalerSimple converter(_width, _height, ADM_COLOR_YV12, ADM_COLOR_RGB24);
    ADM_byteBuffer byteBuffer;

    frame=av_frame_alloc();
    if(!frame)
    {
        ADM_error("Cannot allocate frame\n");
        goto __cleanup;
    }

    codec=avcodec_find_encoder(AV_CODEC_ID_PNG);
    if(!codec)
    {
        ADM_error("Cannot allocate codec\n");
        goto __cleanup;
    }

    context=avcodec_alloc_context3(codec);
    if(!context)
    {
        ADM_error("Cannot allocate context\n");
        goto __cleanup;
    }

    context->pix_fmt=AV_PIX_FMT_RGB24;
    context->strict_std_compliance = -1;
    context->time_base.den=1;
    context->time_base.num=1;
    context->width=_width;
    context->height=_height;

    r=avcodec_open2(context, codec, NULL);
    if(r<0)
    {
        ADM_error("Cannot combine codec and context\n");
        ADM_dealloc(context);
        return false;
    }

    // swap U & V planes first
    out=(uint8_t *)ADM_alloc(sz);
    xss[0] = this->GetPitch(PLANAR_Y);
    xss[1] = this->GetPitch(PLANAR_V);
    xss[2] = this->GetPitch(PLANAR_U);
    xsp[0] = this->GetReadPtr(PLANAR_Y);
    xsp[1] = this->GetReadPtr(PLANAR_V);
    xsp[2] = this->GetReadPtr(PLANAR_U);
    xds[0] = _width*3;
    xds[1] = xds[2] = 0;
    xdp[0] = out;
    xdp[1] = xdp[2] = NULL;

    // convert colorspace
    converter.convertPlanes(xss,xds,xsp,xdp);

    // setup AVFrame
    frame->width = _width;
    frame->height = _height;
    frame->format = AV_PIX_FMT_RGB24;

    frame->linesize[0] = _width*3;
    frame->linesize[1] = 0;
    frame->linesize[2] = 0;

    frame->data[0] = out;
    frame->data[1] = NULL;
    frame->data[2] = NULL;

    // Grab a temp buffer
    byteBuffer.setSize(sz);

    // Encode
    AVPacket pkt;
    av_init_packet(&pkt);
    int gotSomething;
    pkt.size=sz;
    pkt.data=byteBuffer.at(0);
    r=avcodec_encode_video2(context,&pkt,frame,&gotSomething);
    if(r || !gotSomething)
    {
        ADM_error("Error %d encoding image\n",r);
        goto __cleanup;
    }

    // Ok now write our file...
    {
        FILE *f=ADM_fopen(filename,"wb");
        if(f)
        {
            fwrite(byteBuffer.at(0),pkt.size,1,f);
            fclose(f);
            result=true;
        }else
        {
            ADM_error("Cannot open %s for writing!\n",filename);
        }
    }

__cleanup:
    // Cleanup
    if(context)
    {
        avcodec_close(context);
        av_free(context);
        context=NULL;
    }

    if(frame)
    {
        av_frame_free(&frame);
        frame=NULL;
    }

    return result;
}
Exemple #14
0
/**
    \fn saveAsJpg
    \brief save current image into filename, into jpg format
*/
bool  ADMImage::saveAsJpgInternal(const char *filename)
{

AVCodecContext   *context=NULL;   
AVFrame          *frame=NULL;
bool             result=false;
AVCodec          *codec=NULL;
int              r=0;
ADM_byteBuffer   byteBuffer;

    frame=av_frame_alloc();
    if(!frame)
    {
        printf("[saveAsJpg] Cannot allocate frame\n");
        goto  jpgCleanup;
    }

    codec=avcodec_find_encoder(AV_CODEC_ID_MJPEG);
    if(!codec)
    {
        printf("[saveAsJpg] Cannot allocate codec\n");
        goto  jpgCleanup;
    }

    context=avcodec_alloc_context3(codec);
    if(!context) 
    {
        printf("[saveAsJpg] Cannot allocate context\n");
        goto  jpgCleanup;
    }

    context->pix_fmt =AV_PIX_FMT_YUV420P;
    context->strict_std_compliance = -1;
    context->time_base.den=1;
    context->time_base.num=1;
    context->width=_width;
    context->height=_height;
    context->flags |= CODEC_FLAG_QSCALE;
    r=avcodec_open2(context, codec, NULL); 
    if(r<0)
    {
        printf("[saveAsJpg] Cannot mix codec and context\n");
        ADM_dealloc (context);
        return false;
    }
    // Setup our image & stuff....
        frame->width=_width;
        frame->height=_height;
        frame->format=AV_PIX_FMT_YUV420P;

        frame->linesize[0] = GetPitch(PLANAR_Y);
        frame->linesize[2] = GetPitch(PLANAR_U);
        frame->linesize[1] = GetPitch(PLANAR_V);

        frame->data[0] = GetWritePtr(PLANAR_Y);
        frame->data[2] = GetWritePtr(PLANAR_U);
        frame->data[1] = GetWritePtr(PLANAR_V);
    // Grab a temp buffer
    
    // Encode!
     
      frame->quality = (int) floor (FF_QP2LAMBDA * 2+ 0.5);

      byteBuffer.setSize(_width*_height*4);
	  

      AVPacket pkt;
      av_init_packet(&pkt);
      int gotSomething;
      pkt.size=_width*_height*4;
      pkt.data=byteBuffer.at(0);
      r=avcodec_encode_video2(context,&pkt,frame,&gotSomething);
      if(r || !gotSomething)
      {
            ADM_error("[jpeg] Error %d encoding video\n",r);
            goto  jpgCleanup;
      }
      
        // Ok now write our file...
        {
            FILE *f=ADM_fopen(filename,"wb");
            if(f)
            {
                fwrite(byteBuffer.at(0),pkt.size,1,f);
                fclose(f);
                result=true;
            }else
            {
                printf("[saveAsJpeg] Cannot open %s for writing!\n",filename);

            }
       }

// Cleanup
jpgCleanup:
    if(context)
    {
        avcodec_close (context);
        av_free (context);
        context=NULL;
    }

    if(frame)
    {
        av_frame_free(&frame);
        frame=NULL;
    }

    return result;
}
uint8_t
computeResize (void)
{

int targetx,targetxFinal,targetyPAL,targetyNTSC;

  ADV_Info *info;
  char *inputratio = NULL;


  uint8_t res = 0;		/* 1 Pal, 2 NSTC or film */
  uint32_t targety;

  // scale as if it was 1:1 -> 4:3
        prefs->get (FEATURE_SVCDRES_PREFEREDSOURCERATIO, &inputratio);
        if(inputratio)
        {
                if (inputratio && !strcmp (inputratio, "1:1")) 
                        sourceAR=RESWIZ_AR_1_1;
                if (inputratio && !strcmp (inputratio, "4:3")) 
                        sourceAR=RESWIZ_AR_4_3;
                if (inputratio && !strcmp (inputratio, "16:9")) 
                        sourceAR=RESWIZ_AR_16_9;
     
                ADM_dealloc (inputratio);
                inputratio = NULL;
        }
        
  
  if (!DIA_resizeWiz (&format, &sourceAR, &destinationAR))
    return 0;

 targetx=allFormats[format]->x1;
 targetxFinal=allFormats[format]->x2;
 targetyPAL=allFormats[format]->y1;
 targetyNTSC=allFormats[format]->y2;
        

  info = getLastVideoFilter (frameStart, frameEnd - frameStart)->getInfo ();


  res = identMovieType (info->fps1000);
  //printf("fps : %lu / %d \n",info->fps1000,res);
  switch (res)
    {
    case FRAME_PAL:
      res = 1;
      break;
    case FRAME_NTSC:
    case FRAME_FILM:
      res = 2;
      break;
    default:
      res = 0;
      return 0;
      break;
    }
  if (res == 2)
    targety = targetyNTSC;
  else
    targety = targetyPAL;


  double rx, ry;
  uint32_t newx, newy;
  uint32_t cropx, cropy;
  uint32_t original_x, original_y;


  original_x = info->width;
  original_y = info->height;

  
  // scale as if it was 1:1 -> 4:3
  rx = original_x;
  switch (res)
  {
      case 1:		//PAL
                rx = rx *aspectRatio[1][sourceAR]/aspectRatio[1][destinationAR];
                break;
       case 2:		// NTSC
                rx = rx * aspectRatio[0][sourceAR]/aspectRatio[0][destinationAR];
                break;
   }

  original_x = (uint32_t) floor (rx + 0.49);

  rx = original_x;
  rx = rx / targetxFinal;


  ry = original_y;
  ry = ry / targety;

  // which do do we compress less ?
  if (rx > ry)			// resize by X, add border afterward
    {
      newx = targetx;
      ry = original_y;
      ry = ry / rx;
      newy = (uint32_t) floor (ry + 0.49);
      printf (" resize by x\n");

    }
  else
    {
      newy = targety;
      rx = original_x;
      rx = rx / ry;
      rx *= targetx;
      rx /= targetxFinal;
      newx = (uint32_t) floor (rx + 0.49);
      printf (" resize by y\n");

    }

  printf ("\n New X x Y = %u x %u\n", newx, newy);

  // correct odd / even

  newx -= newx % 4;
  newy -= newy % 4;

  // Now correct crop


  cropx = targetx - newx;
  cropy = targety - newy;

  printf ("\n Resized to : %u x %u, add black border %u x %u",
	  newx, newy, cropx, cropy);

  // now build filter


// first resize (if needed)

  CONFcouple *couple;
  if (newx != info->width || newy != info->height)
    {
      videofilters[nb_active_filter].filter =
	createResizeFromParam (getLastVideoFilter (), newx, newy);


      videofilters[nb_active_filter].tag = VF_MPLAYERRESIZE;
      videofilters[nb_active_filter].filter->getCoupledConf (&couple);
      videofilters[nb_active_filter].conf = couple;;
      nb_active_filter++;
    }
// then add crop (if needed)

  if (cropx || cropy)
    {
      videofilters[nb_active_filter].filter =
	create_addBorder (videofilters[nb_active_filter - 1].filter,
			  cropx >> 1, cropx >> 1, cropy >> 1, cropy >> 1);

      videofilters[nb_active_filter].tag = VF_ADDBORDER;
      videofilters[nb_active_filter].filter->getCoupledConf (&couple);
      videofilters[nb_active_filter].conf = couple;;
      nb_active_filter++;
    }
/**
    \fn saveAsBmp
    \brief save current image into filename, into bmp format
*/
bool  ADMImage::saveAsBmp(const char *filename)
{
  ADM_BITMAPFILEHEADER bmfh;
  ADM_BITMAPINFOHEADER bmph;
  FILE *fd;
  uint32_t sz;
  uint16_t s16;
  uint32_t s32;

  sz = _width* _height * 3;

  bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  bmfh.bfOffBits = sizeof (bmfh) + sizeof (bmph);
//_________________________________________
  bmph.biSize = sizeof (bmph);
  bmph.biWidth = _width;
  bmph.biHeight = _height;
  bmph.biPlanes = 1;
  bmph.biBitCount = 24;
  bmph.biCompression = 0;	// COMPRESSION NONE
  bmph.biSizeImage = sz;
  bmph.biXPelsPerMeter = 0;
  bmph.biYPelsPerMeter = 0;
  bmph.biClrUsed = 0;
  bmph.biClrImportant = 0;
/*
	bmph.resolutionUnits=0;
	bmph.origin=0;
	bmph.colorEncoding=0;
*/

  ADMImageDefault image(_width,_height);


  printf ("\n %u x %u=%u\n", bmph.biWidth, bmph.biHeight, sz);

  uint8_t *out;

        out=(uint8_t *)ADM_alloc(sz);
        if(!out)
        {
            GUI_Error_HIG(QT_TR_NOOP("Memory error"), NULL);
//            ADM_dealloc(out);
            return 0;
        }
        ADMColorScalerSimple converter(bmph.biWidth, bmph.biHeight, ADM_COLOR_YV12,ADM_COLOR_RGB24);
        converter.convertImage(this,out);
        uint32_t ww=bmph.biWidth;
        uint32_t hh=bmph.biHeight;
        uint8_t *swap = new uint8_t[ww*3];
        uint8_t *up=out;
        uint8_t *down=out+(hh-1)*ww*3;
        
        for(int y=0;y<hh>>1;y++)
        {
            SwapMe(swap,up,ww); 
            SwapMe(up,down,ww);
            memcpy( down,swap,ww*3);
            down-=3*ww;
            up+=3*ww;
        }

		delete [] swap;

        fd = ADM_fopen (filename, "wb");
        if (!fd)
        {
                GUI_Error_HIG (QT_TR_NOOP("Something bad happened"), NULL);
                ADM_dealloc(out);
                return 0;
        }

	// Bitmpap file header, not using tructure due to gcc padding it
#ifdef ADM_BIG_ENDIAN
	s16 = 0x424D;
#else
  	s16 = 0x4D42;
#endif
  	s32 = 14 + sizeof (bmph) + sz;
#ifdef ADM_BIG_ENDIAN
	#define SWAP32(x) x=R32(x)
#else
	#define SWAP32(x) ;
#endif
        SWAP32(s32);
        fwrite (&s16, 2, 1, fd);
        fwrite (&s32, 4, 1, fd);
        s32 = 0;
        fwrite (&s32, 4, 1, fd);
        s32 = 14 + sizeof (bmph);
        SWAP32(s32);
        fwrite (&s32, 4, 1, fd);
#ifdef ADM_BIG_ENDIAN
	Endian_BitMapInfo(&bmph);
#endif
        fwrite (&bmph, sizeof (bmph), 1, fd);
        fwrite (out, sz, 1, fd);

        fclose(fd);
        ADM_dealloc(out);
        return 1;
}
/**
      \fn DIA_Preferences
      \brief Handle preference dialog
*/
uint8_t DIA_Preferences(void)
{
uint32_t olddevice,newdevice;

bool     use_odml=0;
uint32_t autosplit=0;
uint32_t render;
bool     useTray=0;


bool     useSwap=0;

uint32_t lavcThreads=0;
uint32_t encodePriority=2;
uint32_t indexPriority=2;
uint32_t playbackPriority=0;
uint32_t downmix;
bool     mpeg_no_limit=0;
uint32_t msglevel=2;

uint32_t mixer=0;

char     *alsaDevice=NULL;

bool     balternate_mp3_tag=true;

uint32_t pp_type=3;
uint32_t pp_value=5;

bool     bvdpau=false;
bool     hzd,vzd,dring;
bool     capsMMX,capsMMXEXT,caps3DNOW,caps3DNOWEXT,capsSSE,capsSSE2,capsSSE3,capsSSSE3,capsAll;
bool     hasOpenGl=false;

bool     askPortAvisynth=false;
uint32_t defaultPortAvisynth = 9999;

#ifdef USE_OPENGL
          prefs->get(FEATURES_ENABLE_OPENGL,&hasOpenGl);
#endif

	olddevice=newdevice=AVDM_getCurrentDevice();

        // Default pp
         if(!prefs->get(DEFAULT_POSTPROC_TYPE,&pp_type)) pp_type=3;
         if(!prefs->get(DEFAULT_POSTPROC_VALUE,&pp_value)) pp_value=3;
#define DOME(x,y) y=!!(pp_type & x)
    
    DOME(1,hzd);
    DOME(2,vzd);
    DOME(4,dring);
     
// Cpu caps
#define CPU_CAPS(x)    	if(CpuCaps::myCpuMask & ADM_CPUCAP_##x) caps##x=1; else caps##x=0;
    
    	if(CpuCaps::myCpuMask==ADM_CPUCAP_ALL) capsAll=1; else capsAll=0;
    	CPU_CAPS(MMX);
    	CPU_CAPS(MMXEXT);
    	CPU_CAPS(3DNOW);
    	CPU_CAPS(3DNOWEXT);
    	CPU_CAPS(SSE);
    	CPU_CAPS(SSE2);
    	CPU_CAPS(SSE3);
    	CPU_CAPS(SSSE3);

    	//Avisynth
    	if(!prefs->get(AVISYNTH_AVISYNTH_ALWAYS_ASK, &askPortAvisynth))
        {
    		ADM_info("Always ask not set\n");
    		askPortAvisynth=0;
    	}

    	if(!prefs->get(AVISYNTH_AVISYNTH_DEFAULTPORT, &defaultPortAvisynth))
        {
    			printf("Port not set\n");
                        defaultPortAvisynth=9999;
    	}
    	ADM_info("Avisynth port: %d\n",defaultPortAvisynth);
    
        // Alsa
#ifdef ALSA_SUPPORT
        if( prefs->get(DEVICE_AUDIO_ALSA_DEVICE, &alsaDevice) != RC_OK )
                alsaDevice = ADM_strdup("plughw:0,0");
#endif
        // vdpau
        prefs->get(FEATURES_VDPAU,&bvdpau);
        
        // Alternate mp3 tag (haali)
        prefs->get(FEATURES_ALTERNATE_MP3_TAG,&balternate_mp3_tag);
        
        // Video renderer
        if(prefs->get(VIDEODEVICE,&render)!=RC_OK)
        {       
                render=(uint32_t)RENDER_GTK;
        }
        // SysTray
        if(!prefs->get(FEATURES_USE_SYSTRAY,&useTray)) 
                useTray=0;
        // Accept mpeg for DVD when fq!=48 kHz
        if(!prefs->get(FEATURES_MPEG_NO_LIMIT,&mpeg_no_limit)) mpeg_no_limit=0;

        // Multithreads
        prefs->get(FEATURES_THREADING_LAVC, &lavcThreads);


		// Encoding priority
		if(!prefs->get(PRIORITY_ENCODING, &encodePriority))
                encodePriority=2;
		// Indexing / unpacking priority
		if(!prefs->get(PRIORITY_INDEXING, &indexPriority))
                indexPriority=2;
		// Playback priority
		if(!prefs->get(PRIORITY_PLAYBACK, &playbackPriority))
                playbackPriority=0;

        // VCD/SVCD split point		
        if(!prefs->get(MPEGSPLIT_AUTOSPLIT, &autosplit))
                autosplit=690;		
                        
        // Open DML (Gmv)
        if(!prefs->get(FEATURES_USE_ODML, &use_odml))
          use_odml=0;
#if defined(ALSA_SUPPORT) || defined (OSS_SUPPORT)
		// Master or PCM for audio
        if(!prefs->get(FEATURES_AUDIOBAR_USES_MASTER, &useMaster))
                useMaster=0;
#endif

        // SWAP A&B if A>B
        if(!prefs->get(FEATURES_SWAP_IF_A_GREATER_THAN_B, &useSwap))
                useSwap=0;
        // Get level of message verbosity
        prefs->get(MESSAGE_LEVEL,&msglevel);
        // Downmix default
        if(prefs->get(DEFAULT_DOWNMIXING,&downmix)!=RC_OK)
        {       
            downmix=0;
        }
        olddevice=newdevice=AVDM_getCurrentDevice();
        // Audio device
        /************************ Build diaelems ****************************************/
        diaElemToggle useVdpau(&bvdpau,QT_TR_NOOP("Decode video using VDPAU"));
        diaElemToggle useOpenGl(&hasOpenGl,QT_TR_NOOP("Enable openGl support"));
#ifndef USE_OPENGL
        //useOpenGl.enable(0);
#endif
        
        diaElemToggle useSysTray(&useTray,QT_TR_NOOP("_Use systray while encoding"));
        diaElemToggle allowAnyMpeg(&mpeg_no_limit,QT_TR_NOOP("_Accept non-standard audio frequency for DVD"));
        diaElemToggle openDml(&use_odml,QT_TR_NOOP("Create _OpenDML files"));

        

        diaElemFrame frameSimd(QT_TR_NOOP("SIMD"));

		diaElemToggle capsToggleAll(&capsAll,QT_TR_NOOP("Enable all SIMD"));
        diaElemToggle capsToggleMMX(&capsMMX, QT_TR_NOOP("Enable MMX"));
		diaElemToggle capsToggleMMXEXT(&capsMMXEXT, QT_TR_NOOP("Enable MMXEXT"));
		diaElemToggle capsToggle3DNOW(&caps3DNOW, QT_TR_NOOP("Enable 3DNOW"));
		diaElemToggle capsToggle3DNOWEXT(&caps3DNOWEXT, QT_TR_NOOP("Enable 3DNOWEXT"));
		diaElemToggle capsToggleSSE(&capsSSE, QT_TR_NOOP("Enable SSE"));
		diaElemToggle capsToggleSSE2(&capsSSE2, QT_TR_NOOP("Enable SSE2"));
		diaElemToggle capsToggleSSE3(&capsSSE3, QT_TR_NOOP("Enable SSE3"));
		diaElemToggle capsToggleSSSE3(&capsSSSE3, QT_TR_NOOP("Enable SSSE3"));

		capsToggleAll.link(0, &capsToggleMMX);
		capsToggleAll.link(0, &capsToggleMMXEXT);
		capsToggleAll.link(0, &capsToggle3DNOW);
		capsToggleAll.link(0, &capsToggle3DNOWEXT);
		capsToggleAll.link(0, &capsToggleSSE);
		capsToggleAll.link(0, &capsToggleSSE2);
		capsToggleAll.link(0, &capsToggleSSE3);
		capsToggleAll.link(0, &capsToggleSSSE3);

		frameSimd.swallow(&capsToggleAll);
		frameSimd.swallow(&capsToggleMMX);
		frameSimd.swallow(&capsToggleMMXEXT);
		frameSimd.swallow(&capsToggle3DNOW);
		frameSimd.swallow(&capsToggle3DNOWEXT);
		frameSimd.swallow(&capsToggleSSE);
		frameSimd.swallow(&capsToggleSSE2);
		frameSimd.swallow(&capsToggleSSE3);
		frameSimd.swallow(&capsToggleSSSE3);

		diaElemThreadCount lavcThreadCount(&lavcThreads, QT_TR_NOOP("_lavc threads:"));

		diaElemFrame frameThread(QT_TR_NOOP("Multi-threading"));
		frameThread.swallow(&lavcThreadCount);

		diaMenuEntry priorityEntries[] = {
                             {0,       QT_TR_NOOP("High"),NULL}
                             ,{1,      QT_TR_NOOP("Above normal"),NULL}
                             ,{2,      QT_TR_NOOP("Normal"),NULL}
							 ,{3,      QT_TR_NOOP("Below normal"),NULL}
							 ,{4,      QT_TR_NOOP("Low"),NULL}
        };
		diaElemMenu menuEncodePriority(&encodePriority,QT_TR_NOOP("_Encoding priority:"), sizeof(priorityEntries)/sizeof(diaMenuEntry), priorityEntries,"");
		diaElemMenu menuIndexPriority(&indexPriority,QT_TR_NOOP("_Indexing/unpacking priority:"), sizeof(priorityEntries)/sizeof(diaMenuEntry), priorityEntries,"");
		diaElemMenu menuPlaybackPriority(&playbackPriority,QT_TR_NOOP("_Playback priority:"), sizeof(priorityEntries)/sizeof(diaMenuEntry), priorityEntries,"");

		diaElemFrame framePriority(QT_TR_NOOP("Prioritisation"));
		framePriority.swallow(&menuEncodePriority);
		framePriority.swallow(&menuIndexPriority);
		framePriority.swallow(&menuPlaybackPriority);

        diaElemUInteger autoSplit(&autosplit,QT_TR_NOOP("_Split MPEG files every (MB):"),10,4096);
        
        diaElemToggle   togTagMp3(&balternate_mp3_tag,QT_TR_NOOP("_Use alternative tag for MP3 in .mp4"));
        
        diaMenuEntry videoMode[]={
                             {RENDER_GTK, getNativeRendererDesc(), NULL}
#ifdef USE_XV
                             ,{RENDER_XV,   QT_TR_NOOP("XVideo (best)"),NULL}
#endif
#ifdef USE_VDPAU
                             ,{RENDER_VDPAU,   QT_TR_NOOP("VDPAU (best)"),NULL}
#endif
#ifdef USE_OPENGL
                             ,{RENDER_QTOPENGL,   QT_TR_NOOP("OpenGL (best)"),NULL}
#endif

#ifdef USE_SDL
#ifdef _WIN32
                             ,{RENDER_SDL,      QT_TR_NOOP("MS Windows GDI (SDL)"),NULL}
							 ,{RENDER_DIRECTX,      QT_TR_NOOP("MS Windows DirectX (SDL)"),NULL}
#else
							 ,{RENDER_SDL,      QT_TR_NOOP("SDL (good)"),NULL}
#endif
#endif
        };        
        diaElemMenu menuVideoMode(&render,QT_TR_NOOP("Video _display:"), sizeof(videoMode)/sizeof(diaMenuEntry),videoMode,"");
        
        
        
        diaMenuEntry msgEntries[]={
                             {0,       QT_TR_NOOP("No alerts"),NULL}
                             ,{1,      QT_TR_NOOP("Display only error alerts"),NULL}
                             ,{2,      QT_TR_NOOP("Display all alerts"),NULL}
        };
        diaElemMenu menuMessage(&msglevel,QT_TR_NOOP("_Message level:"), sizeof(msgEntries)/sizeof(diaMenuEntry),msgEntries,"");
        
        
#if defined(ALSA_SUPPORT) || defined (OSS_SUPPORT)
        diaMenuEntry volumeEntries[]={
                             {0,       QT_TR_NOOP("PCM"),NULL}
                             ,{1,      QT_TR_NOOP("Master"),NULL}};
        diaElemMenu menuVolume(&useMaster,QT_TR_NOOP("_Volume control:"), sizeof(volumeEntries)/sizeof(diaMenuEntry),volumeEntries,"");
#endif
        
        
         diaMenuEntry mixerEntries[]={
                             {0,       QT_TR_NOOP("No downmixing"),NULL}
                             ,{1,       QT_TR_NOOP("Stereo"),NULL}
                             ,{2,      QT_TR_NOOP("Pro Logic"),NULL}
                              ,{3,      QT_TR_NOOP("Pro Logic II"),NULL}
         };
        diaElemMenu menuMixer(&downmix,QT_TR_NOOP("_Local playback downmixing:"), sizeof(mixerEntries)/sizeof(diaMenuEntry),mixerEntries,"");
//*********** AV_
		
//***AV
        uint32_t nbAudioDevice=ADM_av_getNbDevices();
        diaMenuEntryDynamic **audioDeviceItems=new diaMenuEntryDynamic *[nbAudioDevice+1];
        audioDeviceItems[0]=new diaMenuEntryDynamic(0,"Dummy","Dummy");
        for(int i=0;i<nbAudioDevice;i++)
        {
            const char *name;
            uint32_t major,minor,patch;
            ADM_av_getDeviceInfo(i, &name, &major,&minor,&patch);
            audioDeviceItems[i+1]=new diaMenuEntryDynamic(i+1,name,name);
        }
        diaElemMenuDynamic menuAudio(&newdevice,QT_TR_NOOP("_AudioDevice"), nbAudioDevice+1, 
                    audioDeviceItems,NULL);
        // default Post proc
     diaElemToggle     fhzd(&hzd,QT_TR_NOOP("_Horizontal deblocking"));
     diaElemToggle     fvzd(&vzd,QT_TR_NOOP("_Vertical deblocking"));
     diaElemToggle     fdring(&dring,QT_TR_NOOP("De_ringing"));
     diaElemUInteger   postProcStrength(&pp_value,QT_TR_NOOP("_Strength:"),0,5);
     diaElemFrame      framePP(QT_TR_NOOP("Default Postprocessing"));
     
     framePP.swallow(&fhzd);
     framePP.swallow(&fvzd);
     framePP.swallow(&fdring);
     framePP.swallow(&postProcStrength);
     

        /* User Interface */
        diaElem *diaUser[]={&useSysTray,&menuMessage};
        diaElemTabs tabUser(QT_TR_NOOP("User Interface"),2,diaUser);
        
         /* Automation */
        
        
        /* Output */
        diaElem *diaOutput[]={&autoSplit,&openDml,&allowAnyMpeg,&togTagMp3};
        diaElemTabs tabOutput(QT_TR_NOOP("Output"),4,(diaElem **)diaOutput);
        
        /* Audio */

#if 0 //defined(ALSA_SUPPORT)
        diaElem *diaAudio[]={&menuMixer,&menuVolume,&menuAudio,&entryAlsaDevice};
        diaElemTabs tabAudio(QT_TR_NOOP("Audio"),4,(diaElem **)diaAudio);
//#elif defined(OSS_SUPPORT)
        diaElem *diaAudio[]={&menuMixer,&menuVolume,&menuAudio};
        diaElemTabs tabAudio(QT_TR_NOOP("Audio"),3,(diaElem **)diaAudio);
#endif

#if 1
        diaElem *diaAudio[]={&menuMixer,&menuAudio};
        diaElemTabs tabAudio(QT_TR_NOOP("Audio"),2,(diaElem **)diaAudio);
#endif

        
        /* Video */
        diaElem *diaVideo[]={&menuVideoMode,&framePP,&useVdpau,&useOpenGl};
        diaElemTabs tabVideo(QT_TR_NOOP("Video"),4,(diaElem **)diaVideo);
        
        /* CPU tab */
		diaElem *diaCpu[]={&frameSimd};
		diaElemTabs tabCpu(QT_TR_NOOP("CPU"),1,(diaElem **)diaCpu);

        /* Threading tab */
		diaElem *diaThreading[]={&frameThread, &framePriority};
		diaElemTabs tabThreading(QT_TR_NOOP("Threading"),2,(diaElem **)diaThreading);

		/* Avisynth tab */
		diaElemToggle togAskAvisynthPort(&askPortAvisynth,"_Always ask which port to use");
		diaElemUInteger uintDefaultPortAvisynth(&defaultPortAvisynth,"Default port to use",1024,65535);
		diaElem *diaAvisynth[]={&togAskAvisynthPort, &uintDefaultPortAvisynth};
		diaElemTabs tabAvisynth("Avisynth",2,(diaElem **)diaAvisynth);

        /* Global Glyph tab */

                                    
// SET
        diaElemTabs *tabs[]={&tabUser,&tabOutput,&tabAudio,&tabVideo,&tabCpu,&tabThreading, &tabAvisynth};
        if( diaFactoryRunTabs(QT_TR_NOOP("Preferences"),7,tabs))
	{
        	//
#ifdef USE_OPENGL
          prefs->set(FEATURES_ENABLE_OPENGL,hasOpenGl);
#endif
        	// cpu caps
        		if(capsAll)
        		{
        			CpuCaps::myCpuMask=ADM_CPUCAP_ALL;
        		}else
        		{
        			CpuCaps::myCpuMask=0;
#undef CPU_CAPS
#define CPU_CAPS(x)    	if(caps##x) CpuCaps::myCpuMask|= ADM_CPUCAP_##x;        	    	
        	    	CPU_CAPS(MMX);
        	    	CPU_CAPS(MMXEXT);
        	    	CPU_CAPS(3DNOW);
        	    	CPU_CAPS(3DNOWEXT);
        	    	CPU_CAPS(SSE);
        	    	CPU_CAPS(SSE2);
        	    	CPU_CAPS(SSE3);
        	    	CPU_CAPS(SSSE3);
        		}
        		prefs->set(FEATURES_CPU_CAPS,CpuCaps::myCpuMask);

                // Postproc
                #undef DOME
                #define DOME(x,y) if(y) pp_type |=x;
                pp_type=0;
                DOME(1,hzd);
                DOME(2,vzd);
                DOME(4,dring);
                prefs->set(DEFAULT_POSTPROC_TYPE,pp_type);
                prefs->set(DEFAULT_POSTPROC_VALUE,pp_value);

                // Alsa
#ifdef ALSA_SUPPORT
                if(alsaDevice)
                {
                   prefs->set(DEVICE_AUDIO_ALSA_DEVICE, alsaDevice);
                   ADM_dealloc(alsaDevice);
                   alsaDevice=NULL;
                }
#endif
                // Device
                //printf("[AudioDevice] Old : %d, new :%d\n",olddevice,newdevice);
                if(olddevice!=newdevice)
                {
                      AVDM_switch((AUDIO_DEVICE)newdevice); // Change current device
                      AVDM_audioSave();                     // Save it in prefs
                      AVDM_audioInit();                     // Respawn
                }
                // Downmixing (default)
                prefs->set(DEFAULT_DOWNMIXING,downmix);
#if defined(ALSA_SUPPORT) || defined (OSS_SUPPORT)
                // Master or PCM
                prefs->set(FEATURES_AUDIOBAR_USES_MASTER, useMaster);
#endif
                // allow non std audio fq for dvd
                prefs->set(FEATURES_MPEG_NO_LIMIT, mpeg_no_limit);
                // Video render
                prefs->set(VIDEODEVICE,render);
                // Odml
                prefs->set(FEATURES_USE_ODML, use_odml);
				// Split
                prefs->set(MPEGSPLIT_AUTOSPLIT, autosplit);
                
                // number of threads
                prefs->set(FEATURES_THREADING_LAVC, lavcThreads);
                // Encoding priority
                prefs->set(PRIORITY_ENCODING, encodePriority);
                // Indexing / unpacking priority
                prefs->set(PRIORITY_INDEXING, indexPriority);
                // Playback priority
                prefs->set(PRIORITY_PLAYBACK, playbackPriority);

                // Auto swap A/B
                prefs->set(FEATURES_SWAP_IF_A_GREATER_THAN_B, useSwap);
                //
                prefs->set(MESSAGE_LEVEL,msglevel);
                // Use tray while encoding
                prefs->set(FEATURES_USE_SYSTRAY,useTray);

                // VDPAU
                prefs->set(FEATURES_VDPAU,bvdpau);
                // Alternate mp3 tag (haali)
                prefs->set(FEATURES_ALTERNATE_MP3_TAG,balternate_mp3_tag);

			
                // Avisynth
                prefs->set(AVISYNTH_AVISYNTH_DEFAULTPORT,defaultPortAvisynth);
                prefs->set(AVISYNTH_AVISYNTH_ALWAYS_ASK, askPortAvisynth);
#if defined(_WIN32) && defined(USE_SDL)
                // Initialise SDL again as driver may have changed
                initSdl(render);
#endif
                
	}
        for(int i=0;i<nbAudioDevice+1;i++)
        {
            
            delete audioDeviceItems[i];
        }
        delete [] audioDeviceItems;



	return 1;
}
/**
    \fn saveAsBmp
    \brief save current image into filename, into bmp format
*/
uint8_t  ADMImage::saveAsBmp(const char *filename)
{
  BITMAPFILEHEADER bmfh;
  BITMAPINFOHEADER bmph;
  FILE *fd;
  uint32_t sz;
  uint16_t s16;
  uint32_t s32;
  
  sz = _width* _height * 3;

  bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  bmfh.bfOffBits = sizeof (bmfh) + sizeof (bmph);
//_________________________________________
  bmph.biSize = sizeof (bmph);
  bmph.biWidth = _width;
  bmph.biHeight = _height;
  bmph.biPlanes = 1;
  bmph.biBitCount = 24;
  bmph.biCompression = 0;	// COMPRESSION NONE
  bmph.biSizeImage = sz;
  bmph.biXPelsPerMeter = 0;
  bmph.biYPelsPerMeter = 0;
  bmph.biClrUsed = 0;
  bmph.biClrImportant = 0;
/*
	bmph.resolutionUnits=0;
	bmph.origin=0;
	bmph.colorEncoding=0;
*/

  ADMImage image(_width,_height);
  

  printf ("\n %u x %u=%u\n", bmph.biWidth, bmph.biHeight, sz);

  uint8_t *out;

        out=(uint8_t *)ADM_alloc(sz);
        if(!out)
        {
            GUI_Error_HIG(QT_TR_NOOP("Memory error"), NULL);
//            ADM_dealloc(out);
            return 0;
        }

        if(!COL_yv12rgbBMP(bmph.biWidth, bmph.biHeight,data, out))
        {
              GUI_Error_HIG(QT_TR_NOOP("Error converting to BMP"), NULL);
              ADM_dealloc(out);
              return 0;
        }
        fd = fopen (filename, "wb");
        if (!fd)
        {
                GUI_Error_HIG (QT_TR_NOOP("Something bad happened"), NULL);
                ADM_dealloc(out);
                return 0;
        }

	// Bitmpap file header, not using tructure due to gcc padding it
#ifdef ADM_BIG_ENDIAN
	s16 = 0x424D;
#else	
  	s16 = 0x4D42;
#endif	
  	s32 = 14 + sizeof (bmph) + sz;
#ifdef ADM_BIG_ENDIAN	
	#define SWAP32(x) x=R32(x)	
#else
	#define SWAP32(x) ; 
#endif
        SWAP32(s32);	
        fwrite (&s16, 2, 1, fd);
        fwrite (&s32, 4, 1, fd);
        s32 = 0;
        fwrite (&s32, 4, 1, fd);
        s32 = 14 + sizeof (bmph);
        SWAP32(s32);
        fwrite (&s32, 4, 1, fd);
#ifdef ADM_BIG_ENDIAN
	Endian_BitMapInfo(&bmph);
#endif
        fwrite (&bmph, sizeof (bmph), 1, fd);
        fwrite (out, sz, 1, fd);
  
        fclose(fd);
        ADM_dealloc(out);
        return 1;
}
int preferences::set_lastfile(const char* file){
   char *internal_file;
	if( ! file ){
		fprintf(stderr,"Prefs: set_lastfile(NULL) called\n");
		return RC_FAILED;
	}
	internal_file = ADM_PathCanonize(file);
	if( !internal_file ){
		fprintf(stderr,"Prefs: set_lastfile(): PathCanonize() returns NULL\n");
		return RC_FAILED;
        }
#ifdef DEBUG_PREFS
	fprintf(stderr,"Prefs: set_lastfile(%s)\n",file);
	if( strcmp(file,internal_file) )
		fprintf(stderr,"Prefs: set_lastfile(%s) (with appended current dir)\n",internal_file);
	PRT_LAFI("<= LASTFILES_",1,opt_defs[LASTFILES_FILE1].current_val);
	PRT_LAFI("<= LASTFILES_",2,opt_defs[LASTFILES_FILE2].current_val);
	PRT_LAFI("<= LASTFILES_",3,opt_defs[LASTFILES_FILE3].current_val);
	PRT_LAFI("<= LASTFILES_",4,opt_defs[LASTFILES_FILE4].current_val);
#endif
	// change opt_defs array
	//
	// ToDo:
	// * a call with a file already in lastfiles will resort lastfiles with
	//   the actual argument on top
	// * a call with a file new to lastfiles will drop LASTFILE_4, move all
	//   one step down and add the file as LASTFILE_1
	if( opt_defs[LASTFILES_FILE4].current_val &&
	    !strncmp(opt_defs[LASTFILES_FILE4].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE4].current_val)) ){
	  char *x = opt_defs[LASTFILES_FILE4].current_val;
		opt_defs[LASTFILES_FILE4].current_val = opt_defs[LASTFILES_FILE3].current_val;
		opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val;
		opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val;
		opt_defs[LASTFILES_FILE1].current_val = x;
	}else if( opt_defs[LASTFILES_FILE3].current_val &&
            !strncmp(opt_defs[LASTFILES_FILE3].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE3].current_val)) ){
          char *x = opt_defs[LASTFILES_FILE3].current_val;
		opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val;
                opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val;
                opt_defs[LASTFILES_FILE1].current_val = x;
        }else if( opt_defs[LASTFILES_FILE2].current_val &&
            !strncmp(opt_defs[LASTFILES_FILE2].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE2].current_val)) ){
          char *x = opt_defs[LASTFILES_FILE2].current_val;
		opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val;
		opt_defs[LASTFILES_FILE1].current_val = x;
	}else if( opt_defs[LASTFILES_FILE1].current_val &&
            !strncmp(opt_defs[LASTFILES_FILE1].current_val,internal_file,strlen(opt_defs[LASTFILES_FILE1].current_val)) ){
		; // nothing to do - always on top
	}else{
		if( opt_defs[LASTFILES_FILE4].current_val )
			ADM_dealloc(opt_defs[LASTFILES_FILE4].current_val);
		opt_defs[LASTFILES_FILE4].current_val = opt_defs[LASTFILES_FILE3].current_val;
		opt_defs[LASTFILES_FILE3].current_val = opt_defs[LASTFILES_FILE2].current_val;
		opt_defs[LASTFILES_FILE2].current_val = opt_defs[LASTFILES_FILE1].current_val;
		opt_defs[LASTFILES_FILE1].current_val = ADM_strdup(internal_file);
	}

#ifdef USE_LIBXML2
	// change the xmlDocument
	if( ! xdoc ){
		// no .avidemuxrc file or not loaded yet
		load();          // try to load it
		if( ! xdoc ){    // really: no .avidemuxrc file
			save();  // generate one from internal defaults and actual changes
			if( xdoc )
				erase_blank_nodes(xdoc->children);
		}
	}
	if( ! xdoc ){
		fprintf(stderr,"Prefs: no xml document generated ny load() nor save()\n");
	}else{
	  xmlNodePtr p;
	  xmlNodePtr q;
		// we assume a valid xml document, but maybe an older version
		ADM_assert( xdoc->children );
		p = xdoc->children;				// ->avidemux (should be there)
		p = goto_node_with_create(p, "lastfiles");	// ->avidemux->lastfile
		q = goto_node_with_create(p, "file1");		// ->avidemux->lastfile->1
		xmlNodeSetContent( q,
			(xmlChar*)(opt_defs[LASTFILES_FILE1].current_val?opt_defs[LASTFILES_FILE1].current_val:""));
		q = goto_node_with_create(p, "file2");		// ->avidemux->lastfile->2
		xmlNodeSetContent( q,
			(xmlChar*)(opt_defs[LASTFILES_FILE2].current_val?opt_defs[LASTFILES_FILE2].current_val:""));
		q = goto_node_with_create(p, "file3");		// ->avidemux->lastfile->3
		xmlNodeSetContent( q,
			(xmlChar*)(opt_defs[LASTFILES_FILE3].current_val?opt_defs[LASTFILES_FILE3].current_val:""));
		q = goto_node_with_create(p, "file4");		// ->avidemux->lastfile->4
		xmlNodeSetContent( q,
			(xmlChar*)(opt_defs[LASTFILES_FILE4].current_val?opt_defs[LASTFILES_FILE4].current_val:""));
		save_xml_to_file();
	}
#endif

#ifdef DEBUG_PREFS
	PRT_LAFI("=> LASTFILES_",1,opt_defs[LASTFILES_FILE1].current_val);
	PRT_LAFI("=> LASTFILES_",2,opt_defs[LASTFILES_FILE2].current_val);
	PRT_LAFI("=> LASTFILES_",3,opt_defs[LASTFILES_FILE3].current_val);
	PRT_LAFI("=> LASTFILES_",4,opt_defs[LASTFILES_FILE4].current_val);
#endif
	delete[] internal_file;
	return RC_OK;
}
uint8_t DIA_vobsub(vobSubParam *param)
{
  char *name;
  int32_t shift;     
  int ret,ext;
        
  ret = 0;
  ext = 0;
  name = param->subname;
  shift = param->subShift;
  
  while(!ext)
  {
    dialog = create_dialog1();

	gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
										GTK_RESPONSE_OK,
										GTK_RESPONSE_CANCEL,
										-1);

    gtk_register_dialog(dialog);
    gtk_dialog_add_action_widget(GTK_DIALOG(dialog),WID(buttonSelect),GTK_RESPONSE_APPLY);
    
    fq = new GtkWidget*[ADM_MAX_LANGUAGE];
    
    // update if any
        if(name)
        {
                update(name,param->index);
      gtk_label_set_text(GTK_LABEL(WID(labelVobsub)),name);
        }
        else
        {
                gtk_label_set_text(GTK_LABEL(WID(labelVobsub)),QT_TR_NOOP("none"));     
        }

        gtk_write_entry(WID(entryShift),shift);

    switch(gtk_dialog_run(GTK_DIALOG(dialog)))
        {
              case GTK_RESPONSE_APPLY:
                char *file;
                        GUI_FileSelRead(QT_TR_NOOP("Select .idx file"),&file); 
                        if(file)
                        {
          ADM_dealloc(name);
          name = file;
              }
        shift = gtk_read_entry(WID(entryShift));
                break;
              case GTK_RESPONSE_OK:
        if(!name)
                {
          GUI_Error_HIG(QT_TR_NOOP("Wrong VobSub parametering"),QT_TR_NOOP("The idx/sub file does not set."));
        }
        else
        {
          param->subname = name;
          param->index = indeces[getRangeInMenu(WID(optionmenu1))];
          param->subShift = gtk_read_entry(WID(entryShift));
          ret = 1;
          ext = 1;
                }
                break;
              case GTK_RESPONSE_CANCEL:
      default:
        if(name != param->subname)
        {
          ADM_dealloc(name);
        }
                ret=0;
                ext=1;
                break;
        }
        delete [] fq;          
        gtk_unregister_dialog(dialog);
        gtk_widget_destroy(dialog);
  }
     
  return ret;
}    
void GUI_FileSel(const char *label, SELFILE_CB cb, int rw,char **rname)
{
	/* Create the selector */
	GtkWidget *dialog;
	char *name = NULL;
	char *tmpname;
	gchar *selected_filename;
	uint8_t res;

	if (rname)
		*rname = NULL;

	if (rw)
		dialog = gtk_file_chooser_dialog_new ("Save", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
	else
		dialog = gtk_file_chooser_dialog_new ("Open File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, 
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);

	gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
	gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
											GTK_RESPONSE_ACCEPT,
											GTK_RESPONSE_CANCEL,
											-1);

	initFileSelector();
	setFilter(dialog);

	gtk_window_set_title (GTK_WINDOW(dialog), label);
	gtk_register_dialog(dialog);

	if (rw)
		res = prefs->get(LASTFILES_LASTDIR_WRITE,(char **)&tmpname);
	else
		res = prefs->get(LASTFILES_LASTDIR_READ,(char **)&tmpname);

	if (res)
	{
		DIR *dir;
		char *str = ADM_PathCanonize(tmpname);

		ADM_PathStripName(str);

		/* LASTDIR may have gone; then do nothing and use current dir instead (implied) */
		if (dir = opendir(str))
		{
			closedir(dir);
			gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),(gchar *)str);
		}

		delete [] str;
	}

	ADM_dealloc(tmpname);

	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
	{
		selected_filename = (gchar *)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));

#ifdef _WIN32
		if (*(selected_filename + strlen(selected_filename) - 1) == '\\'){
#else
		if (*(selected_filename + strlen(selected_filename) - 1) == '/'){
#endif
			GUI_Error_HIG(QT_TR_NOOP("Cannot open directory as a file"), NULL);
		}
		else
		{
			name = ADM_strdup(selected_filename);

			char *str = ADM_PathCanonize(name);

			ADM_PathStripName(str);

			if (rw)
				prefs->set(LASTFILES_LASTDIR_WRITE, (char*)str);
			else
				prefs->set(LASTFILES_LASTDIR_READ, (char*)str);

			delete [] str;
		}
	}

	gtk_unregister_dialog(dialog);
	gtk_widget_destroy(dialog);

	// CYB 2005.02.23
	if (cb)
	{
#warning fixme
        const char *leak=NULL;
		FileSel_ReadWrite(cb, rw, name, leak);
		ADM_dealloc(name);
	}
	else
		*rname = name;
}


/* Mean:It seems it is attached to the dialog & destroyed with it
As it leads to crash if we don't recreate them each time....*/
void initFileSelector(void)
{
#define ADD_PAT(x,y) gtk_file_filter_add_pattern(x,"*."#y);

	filter_avi=gtk_file_filter_new();
	gtk_file_filter_set_name(filter_avi, "AVI (*.avi)");
	ADD_PAT(filter_avi, avi);
	ADD_PAT(filter_avi, AVI);

	filter_mpeg=gtk_file_filter_new();
	gtk_file_filter_set_name(filter_mpeg, "MPEG (*.m*,*.vob)");
	ADD_PAT(filter_mpeg, [mM][12][Vv]);
	ADD_PAT(filter_mpeg, [Mm][pP][gG]);
	ADD_PAT(filter_mpeg, [Vv][Oo][Bb]);
	ADD_PAT(filter_mpeg, ts);
	ADD_PAT(filter_mpeg, TS);

	filter_image = gtk_file_filter_new();

	gtk_file_filter_set_name(filter_image, QT_TR_NOOP("Images"));
	ADD_PAT(filter_image, png);
	ADD_PAT(filter_image, bmp);
	ADD_PAT(filter_image, jpg);

	ADD_PAT(filter_image, PNG);
	ADD_PAT(filter_image, BMP);
	ADD_PAT(filter_image, JPG);

	filter_all = gtk_file_filter_new();

	gtk_file_filter_set_name(filter_all, QT_TR_NOOP("All"));
	gtk_file_filter_add_pattern(filter_all, "*");
}
/**
      \fn DIA_Preferences
      \brief Handle preference dialog
*/
uint8_t DIA_Preferences(void)
{
uint32_t olddevice,newdevice;

uint32_t	lavcodec_mpeg=0;
uint32_t        use_odml=0;
uint32_t	autosplit=0;
uint32_t render;
uint32_t useTray=0;
uint32_t useMaster=0;
uint32_t useAutoIndex=0;
uint32_t useSwap=0;
uint32_t useNuv=0;
uint32_t lavcThreads=0,x264Threads=0,xvidThreads=0;
uint32_t encodePriority=2;
uint32_t indexPriority=2;
uint32_t playbackPriority=0;
uint32_t downmix;
uint32_t mpeg_no_limit=0;
uint32_t msglevel=2;
uint32_t activeXfilter=0;
uint32_t mixer=0;
char     *filterPath=NULL;
char     *alsaDevice=NULL;
uint32_t autovbr=0;
uint32_t autoindex=0;
uint32_t autounpack=0;
uint32_t alternate_mp3_tag=1;
uint32_t pp_type=3;
uint32_t pp_value=5;
uint32_t hzd,vzd,dring;
uint32_t capsMMX,capsMMXEXT,caps3DNOW,caps3DNOWEXT,capsSSE,capsSSE2,capsSSE3,capsSSSE3,capsAll;

uint32_t useGlobalGlyph=0;
char     *globalGlyphName=NULL;

	olddevice=newdevice=AVDM_getCurrentDevice();

        // Default pp
         if(!prefs->get(DEFAULT_POSTPROC_TYPE,&pp_type)) pp_type=3;
         if(!prefs->get(DEFAULT_POSTPROC_VALUE,&pp_value)) pp_value=3;
#define DOME(x,y) y=!!(pp_type & x)
    
    DOME(1,hzd);
    DOME(2,vzd);
    DOME(4,dring);
     
// Cpu caps
#define CPU_CAPS(x)    	if(CpuCaps::myCpuMask & ADM_CPUCAP_##x) caps##x=1; else caps##x=0;
    
    	if(CpuCaps::myCpuMask==ADM_CPUCAP_ALL) capsAll=1; else capsAll=0;
    	CPU_CAPS(MMX);
    	CPU_CAPS(MMXEXT);
    	CPU_CAPS(3DNOW);
    	CPU_CAPS(3DNOWEXT);
    	CPU_CAPS(SSE);
    	CPU_CAPS(SSE2);
    	CPU_CAPS(SSE3);
    	CPU_CAPS(SSSE3);
    
        // Alsa
#ifdef ALSA_SUPPORT
        if( prefs->get(DEVICE_AUDIO_ALSA_DEVICE, &alsaDevice) != RC_OK )
                alsaDevice = ADM_strdup("plughw:0,0");
#endif
        // autovbr
        prefs->get(FEATURE_AUTO_BUILDMAP,&autovbr);
        // autoindex
        prefs->get(FEATURE_AUTO_REBUILDINDEX,&autoindex);
        // Global glyph
        prefs->get(FEATURE_GLOBAL_GLYPH_ACTIVE,&useGlobalGlyph);
        prefs->get(FEATURE_GLOBAL_GLYPH_NAME,&globalGlyphName);
         // autoindex
        prefs->get(FEATURE_AUTO_UNPACK,&autounpack);
        // Alternate mp3 tag (haali)
        prefs->get(FEATURE_ALTERNATE_MP3_TAG,&alternate_mp3_tag);
        
        // Video renderer
        if(prefs->get(DEVICE_VIDEODEVICE,&render)!=RC_OK)
        {       
                render=(uint32_t)RENDER_GTK;
        }
        // SysTray
        if(!prefs->get(FEATURE_USE_SYSTRAY,&useTray)) 
                useTray=0;
        // Accept mpeg for DVD when fq!=48 kHz
        if(!prefs->get(FEATURE_MPEG_NO_LIMIT,&mpeg_no_limit)) mpeg_no_limit=0;

        // Multithreads
        prefs->get(FEATURE_THREADING_LAVC, &lavcThreads);
        prefs->get(FEATURE_THREADING_X264, &x264Threads);
        prefs->get(FEATURE_THREADING_XVID, &xvidThreads);

		// Encoding priority
		if(!prefs->get(PRIORITY_ENCODING, &encodePriority))
                encodePriority=2;
		// Indexing / unpacking priority
		if(!prefs->get(PRIORITY_INDEXING, &indexPriority))
                indexPriority=2;
		// Playback priority
		if(!prefs->get(PRIORITY_PLAYBACK, &playbackPriority))
                playbackPriority=0;

        // VCD/SVCD split point		
        if(!prefs->get(SETTINGS_MPEGSPLIT, &autosplit))
                autosplit=690;		
                        
        if(!prefs->get(FEATURE_USE_LAVCODEC_MPEG, &lavcodec_mpeg))
                lavcodec_mpeg=0;
        // Open DML (Gmv)
        if(!prefs->get(FEATURE_USE_ODML, &use_odml))
          use_odml=0;
#if defined(ALSA_SUPPORT) || defined (OSS_SUPPORT)
		// Master or PCM for audio
        if(!prefs->get(FEATURE_AUDIOBAR_USES_MASTER, &useMaster))
                useMaster=0;
#endif
        // Autoindex files
        if(!prefs->get(FEATURE_TRYAUTOIDX, &useAutoIndex))
                useAutoIndex=0;

        // SWAP A&B if A>B
        if(!prefs->get(FEATURE_SWAP_IF_A_GREATER_THAN_B, &useSwap))
                useSwap=0;
        // No nuv sync
        if(!prefs->get(FEATURE_DISABLE_NUV_RESYNC, &useNuv))
                useNuv=0;
        // Get level of message verbosity
        prefs->get(MESSAGE_LEVEL,&msglevel);
        // External filter
         prefs->get(FILTERS_AUTOLOAD_ACTIVE,&activeXfilter);
        // Downmix default
        if(prefs->get(DOWNMIXING_PROLOGIC,&downmix)!=RC_OK)
        {       
            downmix=0;
        }
        olddevice=newdevice=AVDM_getCurrentDevice();
        // Audio device
        /************************ Build diaelems ****************************************/
        diaElemToggle useSysTray(&useTray,QT_TR_NOOP("_Use systray while encoding"));
        diaElemToggle allowAnyMpeg(&mpeg_no_limit,QT_TR_NOOP("_Accept non-standard audio frequency for DVD"));
        diaElemToggle useLavcodec(&lavcodec_mpeg,QT_TR_NOOP("_Use libavcodec MPEG-2 decoder"));
        diaElemToggle openDml(&use_odml,QT_TR_NOOP("Create _OpenDML files"));
        diaElemToggle autoIndex(&useAutoIndex,QT_TR_NOOP("Automatically _index MPEG files"));
        diaElemToggle autoSwap(&useSwap,QT_TR_NOOP("Automatically _swap A and B if A>B"));
        diaElemToggle nuvAudio(&useNuv,QT_TR_NOOP("_Disable NUV audio sync"));        
        
        diaElemToggle togAutoVbr(&autovbr,QT_TR_NOOP("Automatically _build VBR map"));
        diaElemToggle togAutoIndex(&autoindex,QT_TR_NOOP("Automatically _rebuild index"));
        diaElemToggle togAutoUnpack(&autounpack,QT_TR_NOOP("Automatically remove _packed bitstream"));

        diaElemFrame frameSimd(QT_TR_NOOP("SIMD"));

		diaElemToggle capsToggleAll(&capsAll,QT_TR_NOOP("Enable all SIMD"));
        diaElemToggle capsToggleMMX(&capsMMX, QT_TR_NOOP("Enable MMX"));
		diaElemToggle capsToggleMMXEXT(&capsMMXEXT, QT_TR_NOOP("Enable MMXEXT"));
		diaElemToggle capsToggle3DNOW(&caps3DNOW, QT_TR_NOOP("Enable 3DNOW"));
		diaElemToggle capsToggle3DNOWEXT(&caps3DNOWEXT, QT_TR_NOOP("Enable 3DNOWEXT"));
		diaElemToggle capsToggleSSE(&capsSSE, QT_TR_NOOP("Enable SSE"));
		diaElemToggle capsToggleSSE2(&capsSSE2, QT_TR_NOOP("Enable SSE2"));
		diaElemToggle capsToggleSSE3(&capsSSE3, QT_TR_NOOP("Enable SSE3"));
		diaElemToggle capsToggleSSSE3(&capsSSSE3, QT_TR_NOOP("Enable SSSE3"));

		capsToggleAll.link(0, &capsToggleMMX);
		capsToggleAll.link(0, &capsToggleMMXEXT);
		capsToggleAll.link(0, &capsToggle3DNOW);
		capsToggleAll.link(0, &capsToggle3DNOWEXT);
		capsToggleAll.link(0, &capsToggleSSE);
		capsToggleAll.link(0, &capsToggleSSE2);
		capsToggleAll.link(0, &capsToggleSSE3);
		capsToggleAll.link(0, &capsToggleSSSE3);

		frameSimd.swallow(&capsToggleAll);
		frameSimd.swallow(&capsToggleMMX);
		frameSimd.swallow(&capsToggleMMXEXT);
		frameSimd.swallow(&capsToggle3DNOW);
		frameSimd.swallow(&capsToggle3DNOWEXT);
		frameSimd.swallow(&capsToggleSSE);
		frameSimd.swallow(&capsToggleSSE2);
		frameSimd.swallow(&capsToggleSSE3);
		frameSimd.swallow(&capsToggleSSSE3);

		diaElemThreadCount lavcThreadCount(&lavcThreads, QT_TR_NOOP("_lavc threads:"));
		diaElemThreadCount x264ThreadCount(&x264Threads, QT_TR_NOOP("_x264 threads:"));
		diaElemThreadCount xvidThreadCount(&xvidThreads, QT_TR_NOOP("X_vid threads:"));

		diaElemFrame frameThread(QT_TR_NOOP("Multi-threading"));
		frameThread.swallow(&lavcThreadCount);
		frameThread.swallow(&x264ThreadCount);
		frameThread.swallow(&xvidThreadCount);

		diaMenuEntry priorityEntries[] = {
                             {0,       QT_TR_NOOP("High"),NULL}
                             ,{1,      QT_TR_NOOP("Above normal"),NULL}
                             ,{2,      QT_TR_NOOP("Normal"),NULL}
							 ,{3,      QT_TR_NOOP("Below normal"),NULL}
							 ,{4,      QT_TR_NOOP("Low"),NULL}
        };
		diaElemMenu menuEncodePriority(&encodePriority,QT_TR_NOOP("_Encoding priority:"), sizeof(priorityEntries)/sizeof(diaMenuEntry), priorityEntries,"");
		diaElemMenu menuIndexPriority(&indexPriority,QT_TR_NOOP("_Indexing/unpacking priority:"), sizeof(priorityEntries)/sizeof(diaMenuEntry), priorityEntries,"");
		diaElemMenu menuPlaybackPriority(&playbackPriority,QT_TR_NOOP("_Playback priority:"), sizeof(priorityEntries)/sizeof(diaMenuEntry), priorityEntries,"");

		diaElemFrame framePriority(QT_TR_NOOP("Prioritisation"));
		framePriority.swallow(&menuEncodePriority);
		framePriority.swallow(&menuIndexPriority);
		framePriority.swallow(&menuPlaybackPriority);

        diaElemUInteger autoSplit(&autosplit,QT_TR_NOOP("_Split MPEG files every (MB):"),10,4096);
        
        diaElemToggle   togTagMp3(&alternate_mp3_tag,QT_TR_NOOP("_Use alternative tag for MP3 in .mp4"));
        
        diaMenuEntry videoMode[]={
                             {RENDER_GTK,      QT_TR_NOOP("GTK+ (slow)"),NULL}
#ifdef USE_XV
                             ,{RENDER_XV,   QT_TR_NOOP("XVideo (best)"),NULL}
#endif
#ifdef USE_SDL
#ifdef __WIN32
                             ,{RENDER_SDL,      QT_TR_NOOP("SDL (GDI)"),NULL}
							 ,{RENDER_DIRECTX,      QT_TR_NOOP("SDL (DirectX)"),NULL}
#else
							 ,{RENDER_SDL,      QT_TR_NOOP("SDL (good)"),NULL}
#endif
#endif
        };        
        diaElemMenu menuVideoMode(&render,QT_TR_NOOP("Video _display:"), sizeof(videoMode)/sizeof(diaMenuEntry),videoMode,"");
        
        
        
        diaMenuEntry msgEntries[]={
                             {0,       QT_TR_NOOP("No alerts"),NULL}
                             ,{1,      QT_TR_NOOP("Display only error alerts"),NULL}
                             ,{2,      QT_TR_NOOP("Display all alerts"),NULL}
        };
        diaElemMenu menuMessage(&msglevel,QT_TR_NOOP("_Message level:"), sizeof(msgEntries)/sizeof(diaMenuEntry),msgEntries,"");
        
        
#if defined(ALSA_SUPPORT) || defined (OSS_SUPPORT)
        diaMenuEntry volumeEntries[]={
                             {0,       QT_TR_NOOP("PCM"),NULL}
                             ,{1,      QT_TR_NOOP("Master"),NULL}};
        diaElemMenu menuVolume(&useMaster,QT_TR_NOOP("_Volume control:"), sizeof(volumeEntries)/sizeof(diaMenuEntry),volumeEntries,"");
#endif
        
        
         diaMenuEntry mixerEntries[]={
                             {0,       QT_TR_NOOP("No downmixing"),NULL}
                             ,{1,       QT_TR_NOOP("Stereo"),NULL}
                             ,{2,      QT_TR_NOOP("Pro Logic"),NULL}
                              ,{3,      QT_TR_NOOP("Pro Logic II"),NULL}
         };
        diaElemMenu menuMixer(&downmix,QT_TR_NOOP("_Local playback downmixing:"), sizeof(mixerEntries)/sizeof(diaMenuEntry),mixerEntries,"");

		diaMenuEntry audioEntries[] =
		{
		#ifdef ALSA_SUPPORT
			{DEVICE_ALSA, QT_TR_NOOP("ALSA")},
		#endif
		#ifdef USE_ARTS
			{DEVICE_ARTS, QT_TR_NOOP("aRts")},
		#endif
		#ifdef __APPLE__
			{DEVICE_COREAUDIO, QT_TR_NOOP("Core Audio")},
		#endif
		#ifdef USE_ESD
			{DEVICE_ESD, QT_TR_NOOP("ESD")},
		#endif
		#ifdef USE_JACK
			{DEVICE_JACK, QT_TR_NOOP("JACK")},
		#endif
		#ifdef OSS_SUPPORT
			{DEVICE_OSS, QT_TR_NOOP("OSS")},
		#endif
		#if	defined(USE_SDL) && !defined(__WIN32)
			{DEVICE_SDL, QT_TR_NOOP("SDL")},
		#endif
		#ifdef __WIN32
			{DEVICE_WIN32, QT_TR_NOOP("Win32")},
		#endif
			{DEVICE_DUMMY, QT_TR_NOOP("None")}
		};

        diaElemMenu menuAudio(&newdevice,QT_TR_NOOP("_Audio output:"), sizeof(audioEntries)/sizeof(diaMenuEntry),audioEntries,"");
                
#ifdef ALSA_SUPPORT
		diaElemText entryAlsaDevice(&alsaDevice,QT_TR_NOOP("ALSA _device:"),NULL);

          int z,m;
          m=sizeof(audioEntries)/sizeof(diaMenuEntry);
          for(z=0;z<m;z++)
          {
            if(audioEntries[z].val==DEVICE_ALSA)
                menuAudio.link(&(audioEntries[z]),1,&entryAlsaDevice);
          }
#endif
        // default Post proc
     diaElemToggle     fhzd(&hzd,QT_TR_NOOP("_Horizontal deblocking"));
     diaElemToggle     fvzd(&vzd,QT_TR_NOOP("_Vertical deblocking"));
     diaElemToggle     fdring(&dring,QT_TR_NOOP("De_ringing"));
     diaElemUInteger   postProcStrength(&pp_value,QT_TR_NOOP("_Strength:"),0,5);
     diaElemFrame      framePP(QT_TR_NOOP("Default Postprocessing"));
     
     framePP.swallow(&fhzd);
     framePP.swallow(&fvzd);
     framePP.swallow(&fdring);
     framePP.swallow(&postProcStrength);
     
        // Filter path
        if( prefs->get(FILTERS_AUTOLOAD_PATH, &filterPath) != RC_OK )
#ifndef __WIN32
               filterPath = ADM_strdup("/tmp");
#else
               filterPath = ADM_strdup("c:\\");
#endif
        diaElemDirSelect  entryFilterPath(&filterPath,QT_TR_NOOP("_Filter directory:"),QT_TR_NOOP("Select filter directory"));
		diaElemToggle loadEx(&activeXfilter,QT_TR_NOOP("_Load external filters"));
		loadEx.link(1, &entryFilterPath);

		diaElemToggle togGlobalGlyph(&useGlobalGlyph, QT_TR_NOOP("Use _Global GlyphSet"));
		diaElemFile  entryGLyphPath(0,&globalGlyphName,QT_TR_NOOP("Gl_yphSet:"), NULL, QT_TR_NOOP("Select GlyphSet file"));
		togGlobalGlyph.link(1, &entryGLyphPath);

        /* User Interface */
        diaElem *diaUser[]={&useSysTray,&menuMessage};
        diaElemTabs tabUser(QT_TR_NOOP("User Interface"),2,diaUser);
        
         /* Automation */
        diaElem *diaAuto[]={&autoSwap,&togAutoVbr,&togAutoIndex,&togAutoUnpack,&autoIndex,};
        diaElemTabs tabAuto(QT_TR_NOOP("Automation"),5,diaAuto);
        
        /* Input */
        diaElem *diaInput[]={&nuvAudio,&useLavcodec};
        diaElemTabs tabInput(QT_TR_NOOP("Input"),2,(diaElem **)diaInput);
        
        /* Output */
        diaElem *diaOutput[]={&autoSplit,&openDml,&allowAnyMpeg,&togTagMp3};
        diaElemTabs tabOutput(QT_TR_NOOP("Output"),4,(diaElem **)diaOutput);
        
        /* Audio */
#if defined(ALSA_SUPPORT)
        diaElem *diaAudio[]={&menuMixer,&menuVolume,&menuAudio,&entryAlsaDevice};
        diaElemTabs tabAudio(QT_TR_NOOP("Audio"),4,(diaElem **)diaAudio);
#elif defined(OSS_SUPPORT)
        diaElem *diaAudio[]={&menuMixer,&menuVolume,&menuAudio};
        diaElemTabs tabAudio(QT_TR_NOOP("Audio"),3,(diaElem **)diaAudio);
#else
        diaElem *diaAudio[]={&menuMixer,&menuAudio};
        diaElemTabs tabAudio(QT_TR_NOOP("Audio"),2,(diaElem **)diaAudio);
#endif
        
        /* Video */
        diaElem *diaVideo[]={&menuVideoMode,&framePP};
        diaElemTabs tabVideo(QT_TR_NOOP("Video"),2,(diaElem **)diaVideo);
        
        /* CPU tab */
		diaElem *diaCpu[]={&frameSimd};
		diaElemTabs tabCpu(QT_TR_NOOP("CPU"),1,(diaElem **)diaCpu);

        /* Threading tab */
		diaElem *diaThreading[]={&frameThread, &framePriority};
		diaElemTabs tabThreading(QT_TR_NOOP("Threading"),2,(diaElem **)diaThreading);

        /* Global Glyph tab */
        diaElem *diaGlyph[]={&togGlobalGlyph,&entryGLyphPath};
        diaElemTabs tabGlyph(QT_TR_NOOP("Global GlyphSet"),2,(diaElem **)diaGlyph);

        /* Xfilter tab */
        diaElem *diaXFilter[]={&loadEx,&entryFilterPath};
        diaElemTabs tabXfilter(QT_TR_NOOP("External Filters"),2,(diaElem **)diaXFilter);
                                    
// SET
        diaElemTabs *tabs[]={&tabUser,&tabAuto,&tabInput,&tabOutput,&tabAudio,&tabVideo,&tabCpu,&tabThreading,&tabGlyph,&tabXfilter};
        if( diaFactoryRunTabs(QT_TR_NOOP("Preferences"),10,tabs))
	{
        	
        	// cpu caps
        		if(capsAll)
        		{
        			CpuCaps::myCpuMask=ADM_CPUCAP_ALL;
        		}else
        		{
        			CpuCaps::myCpuMask=0;
#undef CPU_CAPS
#define CPU_CAPS(x)    	if(caps##x) CpuCaps::myCpuMask|= ADM_CPUCAP_##x;        	    	
        	    	CPU_CAPS(MMX);
        	    	CPU_CAPS(MMXEXT);
        	    	CPU_CAPS(3DNOW);
        	    	CPU_CAPS(3DNOWEXT);
        	    	CPU_CAPS(SSE);
        	    	CPU_CAPS(SSE2);
        	    	CPU_CAPS(SSE3);
        	    	CPU_CAPS(SSSE3);
        		}
        		prefs->set(FEATURE_CPU_CAPS,CpuCaps::myCpuMask);

        		// Glyphs
               prefs->set(FEATURE_GLOBAL_GLYPH_ACTIVE,useGlobalGlyph);
               prefs->set(FEATURE_GLOBAL_GLYPH_NAME,globalGlyphName);

                // Postproc
                #undef DOME
                #define DOME(x,y) if(y) pp_type |=x;
                pp_type=0;
                DOME(1,hzd);
                DOME(2,vzd);
                DOME(4,dring);
                prefs->set(DEFAULT_POSTPROC_TYPE,pp_type);
                prefs->set(DEFAULT_POSTPROC_VALUE,pp_value);
                //
                 prefs->set(FEATURE_AUTO_UNPACK,autounpack);
                 // autovbr
                prefs->set(FEATURE_AUTO_BUILDMAP,autovbr);
                // autoindex
                prefs->set(FEATURE_AUTO_REBUILDINDEX,autoindex);
                // Alsa
#ifdef ALSA_SUPPORT
                if(alsaDevice)
                {
                   prefs->set(DEVICE_AUDIO_ALSA_DEVICE, alsaDevice);
                   ADM_dealloc(alsaDevice);
                   alsaDevice=NULL;
                }
#endif
                // Device
                if(olddevice!=newdevice)
                {
                      AVDM_switch((AUDIO_DEVICE)newdevice);
                }
                // Downmixing (default)
                prefs->set(DOWNMIXING_PROLOGIC,downmix);
#if defined(ALSA_SUPPORT) || defined (OSS_SUPPORT)
                // Master or PCM
                prefs->set(FEATURE_AUDIOBAR_USES_MASTER, useMaster);
#endif
                // allow non std audio fq for dvd
                prefs->set(FEATURE_MPEG_NO_LIMIT, mpeg_no_limit);
                // Video render
                prefs->set(DEVICE_VIDEODEVICE,render);
                // Mpeg /lavcodec
                prefs->set(FEATURE_USE_LAVCODEC_MPEG, lavcodec_mpeg);
                // Odml
                prefs->set(FEATURE_USE_ODML, use_odml);
				// Split
                prefs->set(SETTINGS_MPEGSPLIT, autosplit);
                
                // number of threads
                prefs->set(FEATURE_THREADING_LAVC, lavcThreads);
				prefs->set(FEATURE_THREADING_X264, x264Threads);
				prefs->set(FEATURE_THREADING_XVID, xvidThreads);

				// Encoding priority
				prefs->set(PRIORITY_ENCODING, encodePriority);
				// Indexing / unpacking priority
				prefs->set(PRIORITY_INDEXING, indexPriority);
				// Playback priority
				prefs->set(PRIORITY_PLAYBACK, playbackPriority);

                // Auto index mpeg
                prefs->set(FEATURE_TRYAUTOIDX, useAutoIndex);
                // Auto swap A/B
                prefs->set(FEATURE_SWAP_IF_A_GREATER_THAN_B, useSwap);

                // Disable nuv sync
                prefs->set(FEATURE_DISABLE_NUV_RESYNC, useNuv);
                // Use tray while encoding
                prefs->set(FEATURE_USE_SYSTRAY,useTray);
                // Filter directory
				prefs->set(FILTERS_AUTOLOAD_ACTIVE, activeXfilter);

                if(filterPath)
                  prefs->set(FILTERS_AUTOLOAD_PATH, filterPath);
                // Alternate mp3 tag (haali)
                prefs->set(FEATURE_ALTERNATE_MP3_TAG,alternate_mp3_tag);

			#if defined(__WIN32) && defined(USE_SDL)
				// Initialise SDL again as driver may have changed
				initSdl();
			#endif
	}

	ADM_dealloc(filterPath);
	ADM_dealloc(globalGlyphName);

	return 1;
}
diaElemReadOnlyText::~diaElemReadOnlyText()
{
  if(paramTitle)
    delete paramTitle;
  ADM_dealloc(readOnly);
}
Exemple #24
0
diaElemButton::~diaElemButton()
{
	ADM_dealloc(paramTitle);
}
/* NOTE: ptr = NULL is explicetly allowed */
void av_free(void *ptr)
{
	if(ptr)
		ADM_dealloc(ptr);  
}
uint8_t DIA_animated(ANIMATED_PARAM *param)
{
    uint8_t ret=0;
    GtkWidget *dialog;
    const char *entries[MAX_VIGNETTE]={"spinbuttonTC0","spinbuttonTC1","spinbuttonTC2",
                            "spinbuttonTC3","spinbuttonTC4","spinbuttonTC5" };

        dialog=create_dialog1();
        gtk_register_dialog(dialog);

        CHECK_SET(checkbuttonStd,isNTSC);
        SPIN_SET(spinbuttonvignetteW,vignetteW);
        SPIN_SET(spinbuttonvignetteH,vignetteH);
        if(param->backgroundImg)
            ENTRY_SET(entryBgd,param->backgroundImg);
        for(int i=0;i<MAX_VIGNETTE;i++)
        {
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(dialog,entries[i])),
                    (gfloat)param->timecode[i]) ;
        }

        ASSOCIATE(button1,LOAD_BGD);
        //gtk_widget_show(dialog);
        int action;

        while(1)
        {
            action=gtk_dialog_run(GTK_DIALOG(dialog));
            if(action==LOAD_BGD)
            {
                char *nw;
                    GUI_FileSelRead(_("Select background picture"), &nw);
                    if(nw)
                    {
                        ENTRY_SET(entryBgd,nw);
                        ADM_dealloc(nw);
                    }

                continue;
            }
            break;
        }
        if(action==GTK_RESPONSE_OK)
        {
            CHECK_GET(checkbuttonStd,isNTSC);
            SPIN_GET(spinbuttonvignetteW,vignetteW);
            SPIN_GET(spinbuttonvignetteH,vignetteH);

            if(param->backgroundImg) ADM_dealloc(param->backgroundImg);
            param->backgroundImg=NULL;
            ENTRY_GET(entryBgd,param->backgroundImg);

            for(int i=0;i<MAX_VIGNETTE;i++)
            {
                
                param->timecode[i]=(uint32_t)gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(dialog,entries[i]))) ;
            }
            ret=1;
        }

        gtk_unregister_dialog(dialog);
        gtk_widget_destroy(dialog);
        return ret;
}
diaElemReadOnlyText::~diaElemReadOnlyText()
{
  ADM_dealloc(param);
}
Exemple #28
0
void mpeg2_free (void * buf)
{

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

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

                        lastPts=pts;
                        pts+=startPts;
            }
#if 0
            if(pts!=ADM_NO_PTS)
            {
              timestamp=pts/90;
              ms2time(timestamp,&hh,&mm,&ss,&ms);
              printf("%02d:%02d:%02d \n",hh,mm,ss);
            }
#endif
            blockSize=demuxer->read16i();
            allIndex[stream-0x20].run(blockSize,data,packetLen,usedLen, pts)  ;
       }
    }
//static uint8_t Vbuffer[7.0*5.6*3];
//AVDMGenericVideoStream *getFirstVideoFilter( void)
//
//_____________________________________________________________
void GUI_PlayAvi(void)
{
    uint32_t  time_e, time_a = 0;
    uint32_t err = 0, acc = 0;
    uint32_t max;

    uint32_t framelen,flags;
    AVDMGenericVideoStream *filter;
    ADMImage *buffer=NULL;

    vids = 0, auds = 0, dauds = 0;
    // check we got everything...
    if (!avifileinfo)
	return;
  if((curframe+1)>= avifileinfo->nb_frames-1)
  {
      printf("No frame left\n");
      return;
   }
    if (avifileinfo->fps1000 == 0)
        return;
    if (playing)
      {
        stop_req = 1;
        return;
      }
  uint32_t played_frame=0;
  uint32_t remaining=avifileinfo->nb_frames-curframe;


    if(guiOutputDisplay)
    {
                filter=getLastVideoFilter(curframe,remaining);
                if(mode_preview)
                {
                      editorKillPreview ();
                      UI_setPreviewToggleStatus( 0 );
                      mode_preview=0;
                }
    }
    else
    {
            filter=getFirstVideoFilter(curframe,remaining );
    }
    max=filter->getInfo()->nb_frames;

    // compute how much a frame lasts in ms
    one_frame = (uint32_t) floor(1000.*1000.*10. / filter->getInfo()->fps1000);
    err = one_frame % 10;
    one_frame /= 10; // Duration of a frame in ms, err =leftover in 1/10 ms
    buffer=new ADMImage(filter->getInfo()->width,filter->getInfo()->height);
    // go to RealTime...    
    printf(" One frame : %lu, err=%lu ms\n", one_frame, err);
    // read frame in chunk
    if(!filter->getFrameNumberNoAlloc(1,&framelen,buffer,&flags))
    {
        printf("\n cannot read frame!\n");
        goto abort_play;
    }
      curframe++;
      played_frame++;
    // prepare 1st frame

    stop_req = 0;
    playing = 1;

#ifdef HAVE_AUDIO
    ComputePreload();
#endif
     renderResize(filter->getInfo()->width,filter->getInfo()->height,currentZoom);
     renderStartPlaying();
// reset timer reference
    resetTime();
    do
    {
        vids++;
        renderUpdateImage(buffer->data);
        if(mode_preview&&!guiOutputDisplay)
        {	
            editorUpdatePreview(played_frame);
        }
        update_status_bar(buffer);
        if (time_a == 0)
            time_a = getTime(0);
        // mark !
        //printf("\n Rendering %lu frame\n",curframe);
        // read frame in chunk

        if((played_frame)>=(max-1))
        {
            printf("\n End met (%lu  / %lu )\n",played_frame,max);
            goto abort_play;
         }
        if(!filter->getFrameNumberNoAlloc(played_frame+1,&framelen,buffer,&flags))
        {
            printf("\n cannot read frame!\n");
            goto abort_play;
        }
	curframe++;
	played_frame++;

#ifdef HAVE_AUDIO
	  FillAudio();
#endif

	  time_e = getTime(1);
	  acc += err;
	  if (acc > 10)
	    {
		acc -= 10;
		time_a++;
	    }
	  time_a += one_frame;
	  // delta a is next frame time
	  // time is is current time
	  delta = time_a - time_e;
	  if (delta <= 0)
	    {
		//if(delta<-19)  // allow 19 ms late without warning...
		// tick seems to be ~ 18 ms
		//printf("\n Late ....,due : %lu ms / found : %lu \n",
		//                                              time_a,time_e); 
		// a call to whatever sleep function will last at leat 10 ms
		// give some time to GTK                
	
	  } else
	    {
		// a call to whatever sleep function will last at leat 10 ms
		// give some time to GTK                		
		if (delta > 10)
		    GUI_Sleep(delta - 10);
	    }
     	//
            UI_purge();
            if(mode_preview)
            {
              UI_purge();
              UI_purge(); 
            }
      }
    while (!stop_req);

abort_play:
		// ___________________________________
    // Flush buffer   
    // go back to normal display mode
    //____________________________________
    playing = 0;
	  delete  buffer;

	   renderStopPlaying();
	   renderResize(avifileinfo->width ,  avifileinfo->height,currentZoom);
	   getFirstVideoFilter( );
	   //video_body->getUncompressedFrame(curframe, rdr_decomp_buffer,&flags);
	   GUI_getFrame(curframe, rdr_decomp_buffer, &flags);
	   renderUpdateImage(rdr_decomp_buffer->data);
	   renderRefresh();
     	   update_status_bar(rdr_decomp_buffer);
	   if(mode_preview)
	   {
		editorUpdatePreview(curframe);
	   }
#ifdef HAVE_AUDIO
    if (currentaudiostream)
      {
	  if (wavbuf)
	      ADM_dealloc(wavbuf);
          deleteAudioFilter(NULL);
	  currentaudiostream->endDecompress();
	  AVDM_AudioClose();

      }
#endif
    // done.
};