//******************************************
// Compute the value that will not change
// (duration)
// and init the entries for current bitrate
//******************************************
void prepare( void )
{

	float duration=0;
	aviInfo info;
	char string[200];
	 uint16_t mm,hh,ss,ms;
	 AVDMProcessAudioStream *stream;
	 
	 if(frameStart<frameEnd) numberOfVideoFrames=frameEnd-frameStart;
	 else			 numberOfVideoFrames=frameStart-frameEnd;
 
 	
	
	duration=(float)video_body->getTime (numberOfVideoFrames);
	duration=duration/1000.;
	
	if(duration<0) duration=-duration;
	
	video_body->getVideoInfo(&info);
	
	videoDuration=(uint32_t)ceil(duration);
	frame2time(numberOfVideoFrames,info.fps1000, &hh, &mm, &ss, &ms);
	// now we can set it
	sprintf(string,"%02d:%02d:%02d",hh,mm,ss);
	gtk_label_set_text(GTK_LABEL(WID(labelDuration)),string);
	
	printf("Video duration :%lu\n",videoDuration);

	// Now get audio info
	track1=0;
	if(audioProcessMode() && currentaudiostream)
	{
		stream=buildFakeAudioFilter(currentaudiostream,
				0, 0xffffffff);
	
		if(stream)
		{
			track1=(stream->getInfo()->byterate*8)/1000;
		}
		deleteAudioFilter();
	}else
	{
		if(currentaudiostream) track1=(currentaudiostream->getInfo()->byterate*8)/1000;
	}
	
	track2=0;
	gtk_write_entry(WID(entry3), track1);
	gtk_write_entry(WID(entry4), track2);
	
	printf("Track1 bitrate :%lu\n",track1);
	printf("Track2 bitrate :%lu\n",track2);

	
	
}
//******************************************
// Compute the value that will not change
// (duration)
// and init the entries for current bitrate
//******************************************
void prepare( void )
{
#if 0
	float duration=0;
	aviInfo info;
	char string[200];
	 uint16_t mm,hh,ss,ms;
         AVDMGenericAudioStream *stream;

	 if(frameStart<frameEnd) numberOfVideoFrames=frameEnd-frameStart;
	 else			 numberOfVideoFrames=frameStart-frameEnd;



	duration=(float)video_body->getTime (numberOfVideoFrames);
	duration=duration/1000.;

	if(duration<0) duration=-duration;

	video_body->getVideoInfo(&info);

	videoDuration=(uint32_t)ceil(duration);
	frame2time(numberOfVideoFrames,info.fps1000, &hh, &mm, &ss, &ms);
	// now we can set it
	sprintf(string,"%02d:%02d:%02d",hh,mm,ss);
	gtk_label_set_text(GTK_LABEL(GW(labelDuration),string);

	printf("Video duration :%lu\n",videoDuration);

	// Now get audio info
	track1=0;
	if(audioProcessMode() && currentaudiostream)
	{
//		stream=buildAudioFilter(currentaudiostream,0);

		if(stream)
		{
			track1=(stream->getInfo()->byterate*8)/1000;
		}
//                deleteAudioFilter(stream);
	}else
	{
		if(currentaudiostream) track1=(currentaudiostream->getInfo()->byterate*8)/1000;
	}

	track2=0;
	gtk_spin_button_set_value(GTK_SPIN_BUTTON(GW(spinbuttonTrack1)), track1);
	gtk_spin_button_set_value(GTK_SPIN_BUTTON(GW(spinbuttonTrack2)), track2);

	printf("Track1 bitrate :%lu\n",track1);
	printf("Track2 bitrate :%lu\n",track2);

#endif

}
calculatorDialog::calculatorDialog(QWidget* parent) : QDialog(parent)
{
    ui.setupUi(this);

    connect(ui.formatComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(comboBox_currentIndexChanged(int)));
    connect(ui.mediumComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(mediumComboBox_currentIndexChanged(int)));
    connect(ui.customSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(spinBox_valueChanged(int)));
    connect(ui.audioTrack1SpinBox, SIGNAL(valueChanged(int)), this, SLOT(spinBox_valueChanged(int)));
    connect(ui.audioTrack2SpinBox, SIGNAL(valueChanged(int)), this, SLOT(spinBox_valueChanged(int)));

    float duration = 0;
    aviInfo info;
    uint16_t mm, hh, ss, ms;
    unsigned int track1 = 0;

    if (frameStart < frameEnd)
        _videoFrameCount = frameEnd - frameStart;
    else
        _videoFrameCount = frameStart - frameEnd;

    duration = ((float)video_body->getTime(_videoFrameCount) / 1000.);

    if (duration < 0)
        duration = -duration;

    _videoDuration = (uint32_t)ceil(duration);

    video_body->getVideoInfo(&info);
    frame2time(_videoFrameCount, info.fps1000, &hh, &mm, &ss, &ms);

    ui.durationLabel->setText(QString("%1:%2:%3").arg(hh, 2, 10, QLatin1Char('0')).arg(mm, 2, 10, QLatin1Char('0')).arg(ss, 2, 10, QLatin1Char('0')));

    if (audioProcessMode() && currentaudiostream)
    {
        AVDMGenericAudioStream *stream ; //= buildAudioFilter(currentaudiostream, 0);

        if (stream)
            track1 = (stream->getInfo()->byterate * 8) / 1000;

//		deleteAudioFilter(stream);
    }
    else if(currentaudiostream)
        track1 = (currentaudiostream->getInfo()->byterate * 8) / 1000;

    ui.audioTrack1SpinBox->setValue(track1);

    update();
}
//_________________________________________________________________
//
//                                                              Set up audio system
//_________________________________________________________________
uint8_t
GenericAviSave::setupAudio (void)
{
// 1- Prepare audio filter
//__________________________

    _audioInBuffer = 0;
    _audioTarget=_audioCurrent=0;
    _audioTotal=0;
    audio_filter=NULL;
    if(!currentaudiostream)
    {
        encoding_gui->setAudioCodec(QT_TR_NOOP("None"));
        return 1;
    }
    printf (" mux mode : %d mux param %d\n", muxMode, muxParam);

    if (audioProcessMode())	// else Raw copy mode
    {
        audio_filter = buildAudioFilter (currentaudiostream,video_body->getTime (frameStart));
        if(!audio_filter) return 0;
        encoding_gui->setAudioCodec(getStrFromAudioCodec(audio_filter->getInfo()->encoding));
    }
    else // copymode
    {
        // else prepare the incoming raw stream
        // audio copy mode here
        encoding_gui->setAudioCodec(QT_TR_NOOP("Copy"));
        audio_filter=buildAudioFilter( currentaudiostream,video_body->getTime (frameStart));
        if(!audio_filter) return 0;
    }
    /* Setup audioQ */
    pthread_t     audioThread;
    _pq=new PacketQueue("AVI audioQ",5000,2*1024*1024);
    memset(&_context,0,sizeof(_context));
    _context.audioEncoder=audio_filter;
    _context.audioTargetSample=0xFFFF0000; ; //FIXME
    _context.packetQueue=_pq;
    // start audio thread
    ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&_context));
    ADM_usleep(4000);
    return 1;
}
AVDMGenericAudioStream *mpt_getAudioStream (void)
{
  AVDMGenericAudioStream *audio = NULL;
  if (audioProcessMode ())	// else Raw copy mode
  {
    if (currentaudiostream->isCompressed ())
    {
      if (!currentaudiostream->isDecompressable ())
      {
        return NULL;
      }
    }
    audio =  buildAudioFilter (currentaudiostream,  video_body->getTime (frameStart));
  }
  else				// copymode
  {
      // else prepare the incoming raw stream
      // audio copy mode here
    audio = buildAudioFilter (currentaudiostream,video_body->getTime (frameStart));
  }
  return audio;
}
uint8_t oplug_mpegff(const char *name, ADM_OUT_FORMAT type)
{
AVDMGenericVideoStream *_incoming;
Encoder  *encoder=NULL;
ADMMpegMuxer	*muxer=NULL;
FILE 		*file=NULL;
uint8_t		audioBuffer[48000];
uint32_t	audioLen=0;
uint32_t _w,_h,_fps1000,_page,total;	
AVDMGenericAudioStream	*audio=NULL;
uint32_t len,flags;
uint32_t size;
ADM_MUXER_TYPE mux;
uint32_t  audio_encoding=0;
uint32_t  real_framenum=0;
uint8_t   ret=0;
uint32_t  sample_target=0;
uint32_t  total_sample=0;
ADMBitstream bitstream(0);
uint32_t audioSum=0;
DIA_encoding  *encoding;
int reuse = 0;

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

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

      encoder->setLogFile(twoPass,total);

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

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

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

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

      ADM_assert(  _buffer);
      ADM_assert(  _outbuffer);

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



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

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

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

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

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

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

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

        delete encoder;

		if (audio)
			deleteAudioFilter(audio);

        return ret;
}
uint8_t mpeg_passthrough(const char *name,ADM_OUT_FORMAT format )
{
  uint32_t len, flags;
  AVDMGenericAudioStream *audio=NULL;
  uint32_t audiolen;
  
  DIA_encoding *work;
  ADM_MUXER_TYPE mux;
  
  double total_wanted=0;
  uint32_t total_got=0;
  uint8_t ret=0;
 
  ADMMpegMuxer *muxer=NULL;
  ADMBitstream bitstream(0);
  
  	printf("Saving as mpg PS to file %s\n",name);
  
  	// First we check it is mpeg
	if(!isMpeg12Compatible(avifileinfo->fcc))
  	{
          GUI_Error_HIG(QT_TR_NOOP("This is not MPEG compatible"), QT_TR_NOOP("You can't use the Copy codec."));
		return 0 ;
  	}
  	if(!currentaudiostream)
  	{
          GUI_Error_HIG(QT_TR_NOOP("There is no audio track"), NULL);
		return 0;
  	}
  
	ADM_assert (video_body->getFlags (frameStart, &flags));
        if(!(flags&AVI_KEY_FRAME))
        {
          GUI_Error_HIG(QT_TR_NOOP("The first frame is not intra frame"), QT_TR_NOOP("Use the &lt;&lt; and the &gt;&gt; buttons to move using Intra frames."));
                return 0;
        }
	
  	audio=mpt_getAudioStream();
	
	// Have to check the type
	// If it is mpeg2 we use DVD-PS
	// If it is mpeg1 we use VCD-PS
	// Later check if it is SVCD
	if(!audio)
	{
          GUI_Error_HIG(QT_TR_NOOP("Audio track is not suitable"), NULL);
		return 0;
	}
	// Check
	WAVHeader *hdr=audio->getInfo();
	uint32_t isMpeg1;
	uint32_t isLav;
	if(!prefs->get(FEATURE_USE_LAVCODEC_MPEG2, &isLav))
		{
		 isLav=0;
		}

	if(!isLav)
	{
		decoderMpeg *mpeghdr;
	
		mpeghdr=(decoderMpeg *)video_body->rawGetDecoder(0);
		isMpeg1=mpeghdr->isMpeg1();
	}
	else
	{
		// How to know if it is mpeg 1?
		// Assume it is not
		/*
		decoderFFMpeg12 *mpeghdr;
	
		mpeghdr=(decoderFFMpeg12 *)video_body->rawGetDecoder(0);
		isMpeg1=mpeghdr->isMpeg1();
		*/
		isMpeg1=0;
	
	}
	
	switch(format)
        {
        case ADM_PS:	
                if(isMpeg1)
                {
                        if(hdr->frequency!=44100 ||  hdr->encoding != WAV_MP2)
                        {
                          GUI_Error_HIG(QT_TR_NOOP("Incompatible audio"), QT_TR_NOOP("For VCD, audio must be 44.1 kHz MP2."));
                                return 0 ;
                        }
                        mux=MUXER_VCD;
                        printf("PassThrough: Using VCD PS\n");        
                }else
                {    // Mpeg2 
                        aviInfo info;
                        video_body->getVideoInfo(&info);
                        if(hdr->frequency==44100 && info.width==480&& hdr->encoding == WAV_MP2 ) // SVCD ?
                        {
                                mux=MUXER_SVCD;
                                printf("PassThrough: Using SVCD PS\n");
                        }
                        else
                        {
                            uint32_t valid=0;
                                if(!prefs->get(FEATURE_MPEG_NO_LIMIT,&valid)) valid=0;
                                 // mpeg2, we do only DVD right now
                                if(hdr->frequency==48000) valid=1;
                                if((hdr->encoding != WAV_MP2 && hdr->encoding!=WAV_AC3 && hdr->encoding!=WAV_LPCM
                                && hdr->encoding!=WAV_DTS))
                                {
                                  valid=0;  
                                }
                    
                                if(!valid)
                                {
                                        deleteAudioFilter(audio);
                                       GUI_Error_HIG(("Incompatible audio"),QT_TR_NOOP( "For DVD, audio must be 48 kHz MP2(stereo), AC3, DTS or LPCM (stereo)."));
                                       return 0;
                                }
                         
                               mux=MUXER_DVD;
                               printf("PassThrough: Using DVD PS\n");
                        }
                }

  	        muxer=new mplexMuxer();
                break;
        case ADM_TS:     
             printf("Using TS output format\n");   
             muxer=new tsMuxer(); //lavMuxer();
             mux=MUXER_TS;
             break;
        default:
                ADM_assert(0);
                break;
        }
        
        if(!muxer)
         {
                 printf("No muxer ?\n");
                 return 0;
        }
	if(!muxer->open(name,0,mux,avifileinfo,audio->getInfo()))
	{
		delete muxer;
		muxer=NULL;
		printf("Muxer init failed\n");
		return 0;
		
	}
        
	// In copy mode it is better to recompute the gop timestamp
	muxer->forceRestamp();
  ///____________________________
  work=new DIA_encoding(avifileinfo->fps1000);
  work->setCodec(QT_TR_NOOP("Copy"));
  work->setAudioCodec(QT_TR_NOOP("---"));
  work->setPhasis(QT_TR_NOOP("Saving"));
  if(!audioProcessMode())
     work->setAudioCodec(QT_TR_NOOP("Copy"));
  else
     work->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding));
  switch(mux)
  {
    case MUXER_TS: work->setContainer(QT_TR_NOOP("MPEG TS"));break;
    case MUXER_VCD: work->setContainer(QT_TR_NOOP("MPEG VCD"));break;
    case MUXER_SVCD: work->setContainer(QT_TR_NOOP("MPEG SVCD"));break;
    case MUXER_DVD: work->setContainer(QT_TR_NOOP("MPEG DVD"));break;
    default:
        ADM_assert(0);
  }
  
  uint32_t cur=0;
  uint32_t target_sample=0;
  double target_time;
  aviInfo info;
        video_body->getVideoInfo(&info);
        target_time=frameEnd-frameStart+1;
        target_time*=1000;
        target_time/=info.fps1000; // target_time in second
        target_time*=audio->getInfo()->frequency;
        target_sample=(uint32_t)floor(target_time);

  uint8_t *buffer = new uint8_t[avifileinfo->width * avifileinfo->height * 3];
  uint8_t *audiobuffer = new uint8_t[4*48000*2]; // 2 sec worth of lpcm
  uint32_t position;
  EncoderCopy *copy=NULL;
        bitstream.data=buffer;
        bitstream.bufferSize=avifileinfo->width * avifileinfo->height * 3;
        
     /***************************
      Special case : Multithreaded
     ***************************/
        if(mux==MUXER_VCD || mux==MUXER_SVCD || mux==MUXER_DVD)
        {
          pthread_t audioThread,videoThread,muxerThread;
          copy=new EncoderCopy(NULL);
          muxerMT context;
          
          copy->configure(NULL);
          // 
          memset(&context,0,sizeof(context));
          context.videoEncoder=copy;
          context.audioEncoder=audio;
          context.muxer=( mplexMuxer *)muxer;
          context.nbVideoFrame=copy->getNbFrame();
          context.audioTargetSample=target_sample;
          context.audioBuffer=audiobuffer;
          context.bitstream=&bitstream;
          context.opaque=(void *)work;

           // start audio thread
          ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioSlave,&context)); 
          ADM_assert(!pthread_create(&videoThread,NULL,(THRINP)copyVideoSlave,&context)); 
          while(1)
          {
            accessMutex.lock();
            if(context.audioDone==2 || context.videoDone==2 || !work->isAlive()) //ERROR
            {
              context.audioAbort=1;
              context.videoAbort=1;
              printf("[Copy] aborting\n");
            }
            if(context.audioDone && context.videoDone)
            {
              printf("[Copy]Both audio & video done\n");
              if(context.audioDone==1 && context.videoDone==1) ret=1;
              else ret=0;
              accessMutex.unlock();
              goto _abt;
            }
             // Update UI
            work->setAudioSize(context.feedAudio);
            context.feedVideo=0;
            accessMutex.unlock();
            ADM_usleep(1000*1000);
             
          }    
    
    
        }
        /**************************************************************************************/
        /* If we get here, it means output is MPEG_TS */ 
        /* We must use the audio packet Queue */
        /**************************************************************************************/
        ADM_assert(mux==MUXER_TS);
        {
            PacketQueue *pq;
            uint32_t mx,sample;
            pthread_t     audioThread;
            copy=new EncoderCopy(NULL);
            audioQueueMT context;
            uint8_t r;
            
            copy->configure(NULL);
            pq=new PacketQueue("TS audioQ",5000,2*1024*1024);
            memset(&context,0,sizeof(context));
            context.audioEncoder=audio;
            context.audioTargetSample=target_sample;
            context.packetQueue=pq;
              // start audio thread
            ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&context));
            // Go!
             
            ADM_usleep(4000);
            mx=copy->getNbFrame();
            printf("Writing %u frames\n",mx);
            for(int frame=0;frame<mx;frame++)
            {
              while(muxer->needAudio())
              {
                if(pq->Pop(audiobuffer,&audiolen,&sample))
                {
                  if(audiolen)
                  {
                    muxer->writeAudioPacket(audiolen,audiobuffer);
                    //work->feedAudioFrame(audiolen);
                  }
                }else break;
              }
              ADM_assert(copy);
              bitstream.cleanup(frame);
              r=copy->encode ( frame, &bitstream);
              if(!r)
              {
                printf("TS:Frame %u error\n",frame);
                GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL);
                goto  stopit;
              }
              muxer->writeVideoPacket( &bitstream);

              work->setFrame(frame,bitstream.len,bitstream.out_quantizer,mx);
//              work->feedFrame(bitstream.len);
              if(!work->isAlive())
              {
                goto stopit;
              }
            }
        
    ret=1;
stopit:
    context.audioAbort=1;
    pq->Abort();
    // Wait for audio slave to be over
    while(!context.audioDone)
    {
      printf("Waiting Audio thread\n");
      ADM_usleep(500000); 
    }
    delete pq;
  } // End ts case 
  /************************************** TS End *********************************/
_abt:
  delete work;
  muxer->close();
  delete muxer;
  delete [] buffer;
  delete [] audiobuffer;
  deleteAudioFilter(audio);
  if(copy) delete copy;
  return ret;

}
//__________________________________________________
uint8_t		ADM_ogmWrite::initAudio(void)
{
uint32_t 	tstart;
WAVHeader	*info=NULL;
                audioStream=NULL;
		if(!currentaudiostream)
		{
			audioFilter=NULL;	
			_audioBuffer=NULL;
			encoding_gui->setAudioCodec("None");
			return 1;
		}
		if(audioProcessMode() && currentaudiostream->isCompressed() 
                        && !currentaudiostream->isDecompressable())
		{
                    return 0;
		}
                audioStream=new ogm_page(_fd,2);		//
                audioFilter=buildAudioFilter(currentaudiostream, video_body->getTime (frameStart));
                if(!audioFilter) return 0;
		if(audioProcessMode())
		{
			uint16_t fcc;
			
			fcc=audioFilter->getInfo()->encoding;
			encoding_gui->setAudioCodec(getStrFromAudioCodec(fcc));
		}
		else	// Copymode
		{
			encoding_gui->setAudioCodec("Copy");
			
		}
		//______________ Write headers/ Audio..._____________________
		
		
		_audioBuffer=new uint8_t[OGM_AUDIO_BUFFER*2]; 
		
		char string[40];
		stream_header header;
		
		info=audioFilter->getInfo();
		
		if(audioFilter->getInfo()->encoding!=WAV_OGG)
		{
		
			memset(&header,0,sizeof(header));
		
			uint64_t d64;
			uint32_t d32;
			uint16_t d16;
			
			memcpy(&(header.streamtype),"audio\0\0\0",8);
			memset(&(header.subtype),0,4);
			sprintf(string,"%04X",info->encoding);
			//memcpy(&(header.subtype),&(info->encoding),2);
			memcpy(&(header.subtype),string,4);
			printf("audio encoding:%x\n",info->encoding);
			
			
#define DO(x,y,z) {d##z=y;MEMCPY(&header.x,&d##z,z>>3);}
			DO(size,sizeof(header),32);
			//header.size=sizeof(header);
			//header.audio.channels=info->channels;
			DO(audio.channels,info->channels,16);
			// not reliable header.audio.blockalign=info->blockalign;
			uint16_t bps;
			uint16_t blkalign;
			switch(info->encoding)
			{
				case WAV_MP3:
				case WAV_MP2:
					bps=0;
					blkalign=1152;break;
				case WAV_AC3:	
					bps=2;
					blkalign=1536;break;
				default:
					blkalign=info->blockalign;
					bps=0;
					break;
			}
		
			DO(audio.blockalign,blkalign,16);
			DO(bits_per_sample,bps,16);
			
			//header.audio.avgbytespersec=info->byterate;
			DO(audio.avgbytespersec,info->byterate,32);
		
			//header.time_unit=(int64_t)10000000;
			DO(time_unit,10000000LL,64);
			//header.samples_per_unit=info->frequency;
			DO(samples_per_unit,info->frequency,64);
		
			//header.buffersize=info->frequency; // half a sec
			DO(buffersize,info->frequency,32); // half a sec
			
			//header.default_len=1;
			DO(default_len,1,32);
			audioStream->writeHeaders(sizeof(header),(uint8_t *)&header); // +4 ?
			_audioTarget=_audioCurrent=0;
			return 1;	

		}
		else
		{
			uint32_t exlen;
			uint8_t  *exdata;
			if(!audioProcessMode())
			{
			currentaudiostream->extraData(&exlen,&exdata);
			}
			else
			{
			audioFilter->extraData(&exlen,&exdata);
			}
			uint32_t *p;
			p=(uint32_t *)exdata;
			
			if(!exlen || !exdata)
			{
				delete audioFilter;
				audioFilter=NULL;
				delete audioStream;
				audioStream=NULL;
				printf("Vorbis audio setup failed (len:%lu)\n",exlen);
				return 0;
			}
			
			exdata+=3*sizeof(uint32_t);
			
			audioStream->writeDirect(p[0],exdata); // Header
			
			exdata+=p[0];
			audioStream->writeDirect(p[1],exdata); // Comment
			
			exdata+=p[1];
			audioStream->writeDirect(p[2],exdata); // Codebook
			_audioTarget=_audioCurrent=0;
			return 1;	
		
		}
		
	
}
uint8_t oplug_mp4(const char *name, ADM_OUT_FORMAT type)
{
AVDMGenericVideoStream *_incoming=NULL;
AVDMGenericAudioStream  *audio=NULL;

uint8_t		audioBuffer[48000];
uint8_t         *videoBuffer=NULL;

uint32_t alen;//,flags;
uint32_t size;

uint8_t   ret=0;

uint32_t  sample_got=0,sample;
uint32_t  extraDataSize=0;
uint8_t   *extraData=NULL;
lavMuxer  *muxer=NULL;
aviInfo      info;
uint32_t   width,height;
DIA_encoding *encoding_gui=NULL;
Encoder         *_encode=NULL;
char            *TwoPassLogFile=NULL;
uint32_t total=0;
uint32_t videoExtraDataSize=0;
uint8_t  *videoExtraData=NULL;
uint8_t *dummy,err;
WAVHeader *audioinfo=NULL;
int prefill=0;
uint32_t displayFrame=0;
ADMBitstream    bitstream;
uint32_t        frameWrite=0;
ADM_MUXER_TYPE muxerType=MUXER_MP4;
uint8_t dualPass=0;
uint8_t r=0;
uint32_t skipping=1;
           if(type==ADM_PSP)
               muxerType=MUXER_PSP;
           else
               muxerType=MUXER_MP4;
        // Setup video
        
        if(videoProcessMode())
        {
             _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
        }else
        {
             _incoming = getFirstVideoFilter (frameStart,frameEnd-frameStart);
        }

           videoBuffer=new uint8_t[_incoming->getInfo()->width*_incoming->getInfo()->height*3];
                // Set global header encoding, needed for H264
           _encode = getVideoEncoder (_incoming->getInfo()->width,
                        _incoming->getInfo()->height,1);
           total= _incoming->getInfo()->nb_frames;

           encoding_gui=new DIA_encoding(_incoming->getInfo()->fps1000);

           if (!_encode)
                {
                  GUI_Error_HIG (_("Cannot initialize the video stream"), NULL);
                        goto  stopit;
                }

                // init compressor
                encoding_gui->setContainer("MP4");
                encoding_gui->setAudioCodec("None");
                if(!videoProcessMode())
                        encoding_gui->setCodec("Copy");
                else
                        encoding_gui->setCodec(_encode->getDisplayName());
                TwoPassLogFile=new char[strlen(name)+6];
                strcpy(TwoPassLogFile,name);
                strcat(TwoPassLogFile,".stat");
                _encode->setLogFile(TwoPassLogFile,total);

                if (!_encode->configure (_incoming))
                {
                      GUI_Error_HIG (_("Filter init failed"), NULL);
                     goto  stopit;
                };

                dualPass=_encode->isDualPass();
                if(dualPass)
                {
                       
                        if(!prepareDualPass(videoBuffer,TwoPassLogFile,encoding_gui,_encode,total))
                                goto stopit;
                }else
                {
                        encoding_gui->setPhasis ("Encoding");
                }
                
                info.width=_incoming->getInfo()->width;
                info.height=_incoming->getInfo()->height;
                info.nb_frames=_incoming->getInfo()->nb_frames;
                info.fps1000=_incoming->getInfo()->fps1000;
                info.fcc=*(uint32_t *)_encode->getCodecName(); //FIXME
                _encode->hasExtraHeaderData( &videoExtraDataSize,&dummy);
                if(videoExtraDataSize)
                {
                        printf("We have extradata for video in copy mode (%d)\n",videoExtraDataSize);
                        videoExtraData=new uint8_t[videoExtraDataSize];
                        memcpy(videoExtraData,dummy,videoExtraDataSize);
                }
        // _________________Setup video (cont) _______________
        // ___________ Read 1st frame _________________
             
             ADM_assert(_encode);
             bitstream.data=videoBuffer;
             
preFilling:
             bitstream.cleanup(0);
             if(!(err=_encode->encode ( prefill, &bitstream)))//&len, videoBuffer, &flags,&displayFrame))
             {
                        printf("MP4:First frame error\n");
                        GUI_Error_HIG (_("Error while encoding"), NULL);
                        goto  stopit;
              }
              if(!bitstream.len)
              {
                prefill++;
                goto preFilling;
              }
              if(!bitstream.flags & AVI_KEY_FRAME)
              {
                GUI_Error_HIG (_("KeyFrame error"),_( "The beginning frame is not a key frame.\nPlease move the A marker."));
                  goto  stopit; 
              }
           //len=bitstream.len;
           // If needed get VOL header
           if(isMpeg4Compatible(info.fcc) && !videoExtraDataSize && bitstream.len)
           {
                // And put them as extradata for esds atom
                uint32_t voslen=0;
               
                if(extractVolHeader(videoBuffer,bitstream.len,&voslen))
                {
                        if(voslen)
                        {
                                videoExtraDataSize=voslen;
                                videoExtraData=new uint8_t[videoExtraDataSize];
                                memcpy(videoExtraData,videoBuffer,videoExtraDataSize);
                        }
                } else  printf("Oops should be settings data for esds\n");
            }

// ____________Setup audio__________________
          if(currentaudiostream)
          {
                audio=mpt_getAudioStream();
                if(!audio)
                {
                        GUI_Error_HIG (_("Cannot initialize the audio stream"), NULL);
                        goto  stopit;
                }
          } 
          if(audio)
          {
                audioinfo=audio->getInfo();
                audio->extraData(&extraDataSize,&extraData);
                if(audioProcessMode())
                        encoding_gui->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding));
                else
                         encoding_gui->setAudioCodec("Copy");

           }else
           {
                encoding_gui->setAudioCodec("None");
           }
// ____________Setup Muxer _____________________
           muxer= new lavMuxer;
           
           if(!muxer->open(
                name,
                2000000, // Muxrate
                MUXER_MP4,
                &info,videoExtraDataSize,videoExtraData,
                audioinfo,extraDataSize,extraData))
                         goto stopit;
           //_____________ Loop _____________________
          
          encoding_gui->setContainer("MP4");
          if(audio)
                encoding_gui->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding));
          if(!videoProcessMode())
                encoding_gui->setCodec("Copy");
          else
                encoding_gui->setCodec(_encode->getDisplayName());
           //
          if(bitstream.len)
          {
            muxer->writeVideoPacket( &bitstream);
            frameWrite++;
          }

           

           for(int frame=1;frame<total;frame++)
           {
                while(muxer->needAudio())
               {
                     if(!audio->getPacket(audioBuffer,&alen,&sample)) break;
                     if(alen)
                     {
                        muxer->writeAudioPacket(alen,audioBuffer,sample_got);
                        encoding_gui->feedAudioFrame(alen);
                        sample_got+=sample;
                     }
               }
               ADM_assert(_encode);
               bitstream.cleanup(frameWrite);
               if(!prefill || frame+prefill<total) 
               {
                  r=_encode->encode ( prefill+frame, &bitstream);
               }
                else
                {
                    r=_encode->encode ( total-1, &bitstream);
                }
               if(!r)
               {
                        printf("MP4:Frame %u error\n",frame);
                        GUI_Error_HIG (_("Error while encoding"), NULL);
                        goto  stopit;
                }
                if(!bitstream.len && skipping)
                {
                    printf("Frame skipped (xvid ?)\n");
                    continue;
                }
                skipping=0;
            //    printf("Prefill %u FrameWrite :%u Frame %u PtsFrame :%u\n",prefill,frameWrite,frame,bitstream.ptsFrame);
                frameWrite++;
                muxer->writeVideoPacket( &bitstream);

               encoding_gui->setFrame(frame,total);
               encoding_gui->feedFrame(bitstream.len);
               if(!encoding_gui->isAlive())
                {
                  if(GUI_YesNo(_("Stop Request"), _("Do you want to abort encoding ?")))
                                goto stopit;
                }
               
           }
           ret=1;
           
stopit:
           if(muxer) muxer->close();
           if(encoding_gui) delete encoding_gui;
           if(TwoPassLogFile) delete [] TwoPassLogFile;
           if(videoBuffer) delete [] videoBuffer;
           if(muxer) delete muxer;
           if(_encode) delete _encode;	
           if(videoExtraData) delete [] videoExtraData;
           // Cleanup
           deleteAudioFilter (audio);
           return ret;
}
/*
 * 		\fn    Oplug_flv
		\brief Main function to save in flv format.
		It is very close to oplug_mp4 but somehow simplified as the following assumptions are made :
				* No b frame
				* No 2 pass encoding

*/
uint8_t oplug_flv(const char *name)
{
AVDMGenericVideoStream *_incoming=NULL;
AVDMGenericAudioStream  *audio=NULL;

uint8_t		audioBuffer[48000];
uint8_t         *videoBuffer=NULL;

uint32_t alen;//,flags;
uint32_t size;

uint32_t  sample_got=0,sample;
uint32_t  extraDataSize=0;
uint8_t   *extraData=NULL;
lavMuxer  *muxer=NULL;
aviInfo      info;
uint32_t   width,height;
DIA_encoding *encoding_gui=NULL;
Encoder         *_encode=NULL;
uint32_t total=0;
uint32_t videoExtraDataSize=0;
uint8_t  *videoExtraData=NULL;
uint8_t *dummy,err;
WAVHeader *audioinfo=NULL;
int prefill=0;
uint32_t displayFrame=0;
ADMBitstream    bitstream(0);
uint8_t r=0;
pthread_t     audioThread;
audioQueueMT context;
PacketQueue   *pq=NULL;//("MP4 audioQ",50,2*1024*1024);
uint32_t    totalAudioSize=0;
int frameDelay = 0;
bool receivedFrame = false;

        // Setup video

        if(videoProcessMode())
        {
             _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
        }else
        {
             _incoming = getFirstVideoFilter (frameStart,frameEnd-frameStart);
        }

           videoBuffer=new uint8_t[_incoming->getInfo()->width*_incoming->getInfo()->height*3];
                // Set global header encoding, needed for H264
           _encode = getVideoEncoder (_incoming->getInfo()->width,  _incoming->getInfo()->height,1);
           total= _incoming->getInfo()->nb_frames;

           info.fcc=*(uint32_t *)_encode->getCodecName(); //FIXME
           //
           int supported=0;
           if(isVP6Compatible(info.fcc)) supported=1;
           if(fourCC::check(info.fcc,(const uint8_t *)"FLV1")) supported=1;
           if(!supported)
           {
        	   GUI_Error_HIG(QT_TR_NOOP("Unsupported video"),QT_TR_NOOP("Only FLV1 and VP6 video are supported"));
        	   goto stopit;
           }
           /* Check audio, we support only mp3 right now
            * 44100, 22050, 11025 only!
            *  */
           if(currentaudiostream)
           {
        	   uint32_t audioCodec=0;
        	   uint32_t fq=currentaudiostream->getInfo()->frequency;

        	   	if(audioProcessMode())
        	   	{
        	   		audioCodec=audioFilter_getOuputCodec();
        	   		fq=audioFilter_getOuputFrequency(fq);

        	   	}else
        	   	{	// copy
        	   		audioCodec=currentaudiostream->getInfo()->encoding;
        	   	}
        	   	if(audioCodec!=WAV_MP3 )
        	   		{
        	   			GUI_Error_HIG(QT_TR_NOOP("Unsupported audio"),QT_TR_NOOP("Audio must be mp3 for flv output."));
        	   			goto stopit;
        	   		}
        	   	if(fq!=44100 && fq!=22050 && fq!=11025)
        	   	{
    	   			GUI_Error_HIG(QT_TR_NOOP("Unsupported audio"),QT_TR_NOOP("Frequency must be 44100, 22050 or 11025 Hz."));
    	   			goto stopit;

        	   	}
           }


           encoding_gui=new DIA_encoding(_incoming->getInfo()->fps1000);
           bitstream.bufferSize=_incoming->getInfo()->width*_incoming->getInfo()->height*3;
           if (!_encode)
                {
                  GUI_Error_HIG ("[FLV]",QT_TR_NOOP("Cannot initialize the video stream"));
                        goto  stopit;
                }

                // init compressor
                encoding_gui->setContainer(QT_TR_NOOP("FLV"));
                encoding_gui->setAudioCodec(QT_TR_NOOP("None"));
                if(!videoProcessMode())
                        encoding_gui->setCodec(QT_TR_NOOP("Copy"));
                else
                        encoding_gui->setCodec(_encode->getDisplayName());

                if (!_encode->configure (_incoming))
                {
                      GUI_Error_HIG (QT_TR_NOOP("Filter init failed"), NULL);
                     goto  stopit;
                };

                encoding_gui->setPhasis (QT_TR_NOOP("Encoding"));


                info.width=_incoming->getInfo()->width;
                info.height=_incoming->getInfo()->height;
                info.nb_frames=_incoming->getInfo()->nb_frames;
                info.fps1000=_incoming->getInfo()->fps1000;

                _encode->hasExtraHeaderData( &videoExtraDataSize,&dummy);
                if(videoExtraDataSize)
                {
                        printf("[FLV]We have extradata for video in copy mode (%d)\n",videoExtraDataSize);
                        videoExtraData=new uint8_t[videoExtraDataSize];
                        memcpy(videoExtraData,dummy,videoExtraDataSize);
                }

             ADM_assert(_encode);
             bitstream.data=videoBuffer;

// ____________Setup audio__________________
          if(currentaudiostream)
          {
                audio=mpt_getAudioStream();
                if(!audio)
                {
                        GUI_Error_HIG ("[FLV]",QT_TR_NOOP("Cannot initialize the audio stream"));
                        goto  stopit;
                }
          }
          if(audio)
          {
                audioinfo=audio->getInfo();
                audio->extraData(&extraDataSize,&extraData);
                if(audioProcessMode())
                        encoding_gui->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding));
                else
                         encoding_gui->setAudioCodec(QT_TR_NOOP("Copy"));

           }else
           {
                encoding_gui->setAudioCodec(QT_TR_NOOP("None"));
           }
// ____________Setup Muxer _____________________
           muxer= new lavMuxer;

           if(!muxer->open(
                name,
                2000000, // Muxrate
                MUXER_FLV,
                &info,videoExtraDataSize,videoExtraData,
                audioinfo,extraDataSize,extraData))
                         goto stopit;
//_____________ Loop _____________________

          encoding_gui->setContainer(QT_TR_NOOP("FLV"));

          if(!videoProcessMode())
                encoding_gui->setCodec(QT_TR_NOOP("Copy"));
          else
                encoding_gui->setCodec(_encode->getDisplayName());
           //
          UI_purge();

//_____________ Start Audio thread _____________________
          if(audio)
          {
            pq=new PacketQueue("[FLV] audioQ",5000,2*1024*1024);
            memset(&context,0,sizeof(context));
            context.audioEncoder=audio;
            context.audioTargetSample=0xFFFF0000; ; //FIXME
            context.packetQueue=pq;
            // start audio thread
            ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&context));
            ADM_usleep(4000);
          }
//_____________GO !___________________

			 for (uint32_t frame = 0; frame < total; frame++)
			 {
				 if (!encoding_gui->isAlive())
				 {
					 r = 0;
					 break;
				 }

				 while(muxer->needAudio())
				 {
					 if(pq->Pop(audioBuffer,&alen,&sample))
					 {
						 if(alen)
						 {
							 muxer->writeAudioPacket(alen,audioBuffer,sample_got);
							 totalAudioSize+=alen;
							 encoding_gui->setAudioSize(totalAudioSize);
							 sample_got+=sample;
						 }
					 }
					 else
					 {
						 r = 0;
						 break;
					 }
				 }

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

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

					 if (!r)
					 {
						 printf("Encoding of frame %lu failed!\n", frame);
						 GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL);
						 break;
					 }
					 else if (!receivedFrame && bitstream.len > 0)
					 {
						 if (!(bitstream.flags & AVI_KEY_FRAME))
						 {
							 GUI_Error_HIG (QT_TR_NOOP("KeyFrame error"), QT_TR_NOOP("The beginning frame is not a key frame.\nPlease move the A marker."));
							 r = 0;
							 break;
						 }
						 else
							 receivedFrame = true;
					 }

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

				 if (!r)
					 break;

				 muxer->writeVideoPacket(&bitstream);
				 encoding_gui->setFrame(frame, bitstream.len, bitstream.out_quantizer, total);
			 }

stopit:

    // Flush slave Q
    if(audio&& pq)
    {
        context.audioAbort=1;
        pq->Abort();
        // Wait for audio slave to be over
        while(!context.audioDone)
        {
          printf("[FLV]Waiting Audio thread\n");
          ADM_usleep(500000);
        }
        delete pq;
    }
    //
           if(muxer) muxer->close();
           if(encoding_gui) delete encoding_gui;
           if(videoBuffer) delete [] videoBuffer;
           if(muxer) delete muxer;
           if(_encode) delete _encode;
           if(videoExtraData) delete [] videoExtraData;
           // Cleanup
           deleteAudioFilter (audio);
           return r;
}
uint8_t oplug_mp4(const char *name, ADM_OUT_FORMAT type)
{
AVDMGenericVideoStream *_incoming=NULL;
AVDMGenericAudioStream  *audio=NULL;

uint8_t		audioBuffer[48000];
uint8_t         *videoBuffer=NULL;

uint32_t alen;//,flags;
uint32_t size;

uint8_t   ret=0;

uint32_t  sample_got=0,sample;
uint32_t  extraDataSize=0;
uint8_t   *extraData=NULL;
lavMuxer  *muxer=NULL;
aviInfo      info;
uint32_t   width,height;
DIA_encoding *encoding_gui=NULL;
Encoder         *_encode=NULL;
char            *TwoPassLogFile=NULL;
uint32_t total=0;
uint32_t videoExtraDataSize=0;
uint8_t  *videoExtraData=NULL;
uint8_t *dummy,err;
WAVHeader *audioinfo=NULL;
int prefill=0;
uint32_t displayFrame=0;
ADMBitstream    bitstream(0);
uint32_t        frameWrite=0;
ADM_MUXER_TYPE muxerType=MUXER_MP4;
uint8_t dualPass=0;
uint8_t r=0;
uint32_t skipping=1;
pthread_t     audioThread;
audioQueueMT context;
PacketQueue   *pq;//("MP4 audioQ",50,2*1024*1024);
uint32_t    totalAudioSize=0;
uint32_t sent=0;
const char *containerTitle;
           switch(type)
           {
             case ADM_PSP:muxerType=MUXER_PSP;containerTitle="PSP";break;
             case ADM_MP4:muxerType=MUXER_MP4;containerTitle="MP4";break;
             case ADM_MATROSKA:muxerType=MUXER_MATROSKA;containerTitle="MKV";break;
             default:
                ADM_assert(0);
           }
        // Setup video
        
        if(videoProcessMode())
        {
             _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
        }else
        {
             _incoming = getFirstVideoFilter (frameStart,frameEnd-frameStart);
        }

           videoBuffer=new uint8_t[_incoming->getInfo()->width*_incoming->getInfo()->height*3];
                // Set global header encoding, needed for H264
           _encode = getVideoEncoder (_incoming->getInfo()->width,
                        _incoming->getInfo()->height,1);
           total= _incoming->getInfo()->nb_frames;

           encoding_gui=new DIA_encoding(_incoming->getInfo()->fps1000);
           bitstream.bufferSize=_incoming->getInfo()->width*_incoming->getInfo()->height*3;
           if (!_encode)
                {
                  GUI_Error_HIG (QT_TR_NOOP("Cannot initialize the video stream"), NULL);
                        goto  stopit;
                }

                // init compressor
               
                  encoding_gui->setContainer(containerTitle);
               
                encoding_gui->setAudioCodec("None");
                if(!videoProcessMode())
                        encoding_gui->setCodec("Copy");
                else
                        encoding_gui->setCodec(_encode->getDisplayName());
                TwoPassLogFile=new char[strlen(name)+6];
                strcpy(TwoPassLogFile,name);
                strcat(TwoPassLogFile,".stat");
                _encode->setLogFile(TwoPassLogFile,total);

                if (!_encode->configure (_incoming))
                {
                      GUI_Error_HIG (QT_TR_NOOP("Filter init failed"), NULL);
                     goto  stopit;
                };

                dualPass=_encode->isDualPass();
                if(dualPass)
                {
                       
                        if(!prepareDualPass(bitstream.bufferSize,videoBuffer,TwoPassLogFile,encoding_gui,_encode,total))
                                goto stopit;
                }else
                {
                        encoding_gui->setPhasis ("Encoding");
                }
                
                info.width=_incoming->getInfo()->width;
                info.height=_incoming->getInfo()->height;
                info.nb_frames=_incoming->getInfo()->nb_frames;
                info.fps1000=_incoming->getInfo()->fps1000;
                info.fcc=*(uint32_t *)_encode->getCodecName(); //FIXME
                _encode->hasExtraHeaderData( &videoExtraDataSize,&dummy);
                if(videoExtraDataSize)
                {
                        printf("We have extradata for video in copy mode (%d)\n",videoExtraDataSize);
                        videoExtraData=new uint8_t[videoExtraDataSize];
                        memcpy(videoExtraData,dummy,videoExtraDataSize);
                }
        // _________________Setup video (cont) _______________
        // ___________ Read 1st frame _________________
             
             ADM_assert(_encode);
             bitstream.data=videoBuffer;
             
preFilling:
             bitstream.cleanup(0);
             if(!(err=_encode->encode ( prefill, &bitstream)))//&len, videoBuffer, &flags,&displayFrame))
             {
                        printf("MP4:First frame error\n");
                        GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL);
                        goto  stopit;
              }
              sent++;
              if(!bitstream.len)
              {
                prefill++;
                goto preFilling;
              }
              printf("Pass 2 prefill : %u\n",prefill);
              if(!bitstream.flags & AVI_KEY_FRAME)
              {
                GUI_Error_HIG (QT_TR_NOOP("KeyFrame error"),QT_TR_NOOP( "The beginning frame is not a key frame.\nPlease move the A marker."));
                  goto  stopit; 
              }
           //len=bitstream.len;
           // If needed get VOL header
           if(isMpeg4Compatible(info.fcc) && !videoExtraDataSize && bitstream.len)
           {
                // And put them as extradata for esds atom
                uint32_t voslen=0;
               
                if(extractVolHeader(videoBuffer,bitstream.len,&voslen))
                {
                        if(voslen)
                        {
                                videoExtraDataSize=voslen;
                                videoExtraData=new uint8_t[videoExtraDataSize];
                                memcpy(videoExtraData,videoBuffer,videoExtraDataSize);
                        }
                } else  printf("Oops should be settings data for esds\n");
            }

// ____________Setup audio__________________
          if(currentaudiostream)
          {
                audio=mpt_getAudioStream();
                if(!audio)
                {
                        GUI_Error_HIG (QT_TR_NOOP("Cannot initialize the audio stream"), NULL);
                        goto  stopit;
                }
          } 
          if(audio)
          {
                audioinfo=audio->getInfo();
                audio->extraData(&extraDataSize,&extraData);
                if(audioProcessMode())
                        encoding_gui->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding));
                else
                         encoding_gui->setAudioCodec("Copy");

           }else
           {
                encoding_gui->setAudioCodec("None");
           }
// ____________Setup Muxer _____________________
           muxer= new lavMuxer;
           
           if(!muxer->open(
                name,
                2000000, // Muxrate
                muxerType,
                &info,videoExtraDataSize,videoExtraData,
                audioinfo,extraDataSize,extraData))
                         goto stopit;
//_____________ Loop _____________________
          
          encoding_gui->setContainer(containerTitle);
         
          if(!videoProcessMode())
                encoding_gui->setCodec("Copy");
          else
                encoding_gui->setCodec(_encode->getDisplayName());
           //
          UI_purge();
          if(bitstream.len)
          {
            muxer->writeVideoPacket( &bitstream);
            frameWrite++;
          }
//_____________ Start Audio thread _____________________
          if(audio)
          {          
            pq=new PacketQueue("MP4 audioQ",5000,2*1024*1024);
            memset(&context,0,sizeof(context));
            context.audioEncoder=audio;
            context.audioTargetSample=0xFFFF0000; ; //FIXME
            context.packetQueue=pq;
            // start audio thread
            ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioQueueSlave,&context)); 
            ADM_usleep(4000);
          }
//_____________GO !___________________
           for(int frame=1;frame<total;frame++)
           {
               while(muxer->needAudio())
               {
                    if(pq->Pop(audioBuffer,&alen,&sample))
                    {
                     if(alen)
                     {
                        muxer->writeAudioPacket(alen,audioBuffer,sample_got);
                        totalAudioSize+=alen;
                        encoding_gui->setAudioSize(totalAudioSize);
                        sample_got+=sample;
                     }
                    }else break;
               }
               ADM_assert(_encode);
               bitstream.cleanup(frameWrite);
               if(!prefill || frame+prefill<total) 
               {
                  
                  r=_encode->encode ( prefill+frame, &bitstream);
               }
                else
                {
                    r=_encode->encode ( total-1, &bitstream);
                }
               if(!r && frame<total-2)
               {
                        printf("MP4:Frame %u error\n",frame);
                        GUI_Error_HIG (QT_TR_NOOP("Error while encoding"), NULL);
                        goto  stopit;
                }
                if(!bitstream.len && skipping)
                {
                    printf("Frame skipped (xvid ?)\n");
                    continue;
                }
                sent++;
                skipping=0;
            //    printf("Prefill %u FrameWrite :%u Frame %u PtsFrame :%u\n",prefill,frameWrite,frame,bitstream.ptsFrame);
                frameWrite++;
                muxer->writeVideoPacket( &bitstream);
                encoding_gui->setFrame(frame,bitstream.len,bitstream.out_quantizer,total);
               if(!encoding_gui->isAlive())
                {
                    
                    goto stopit;
                }
               
           }
           ret=1;
           
stopit:
    printf("2nd pass, sent %u frames\n",sent);
    // Flush slave Q
    if(audio)
    {
        context.audioAbort=1;
        pq->Abort();
        // Wait for audio slave to be over
        while(!context.audioDone)
        {
          printf("Waiting Audio thread\n");
          ADM_usleep(500000); 
        }
        delete pq;
    }
    //
           if(muxer) muxer->close();
           if(encoding_gui) delete encoding_gui;
           if(TwoPassLogFile) delete [] TwoPassLogFile;
           if(videoBuffer) delete [] videoBuffer;
           if(muxer) delete muxer;
           if(_encode) delete _encode;	
           if(videoExtraData) delete [] videoExtraData;
           // Cleanup
           deleteAudioFilter (audio);
           return ret;
}
/*
	Save as with the external mpeg2enc

*/
uint8_t
mpegWritter::save_regular (const char *name, ADM_MPEGTYPE mpegtype, int qz, int bitrate, int matrix, uint8_t interlaced, uint8_t bff,	// WLA
			   uint8_t widescreen)
{
  uint32_t size;
  AVDMGenericVideoStream *incoming;

  FILE *fd = NULL;
  uint64_t total_size = 0;
  uint32_t len, flags;
  uint32_t outquant;
  uint32_t audiolen = 0;
  DIA_encoding *encoding;
  uint32_t sample_target = 0;
  double sample_time;
  ADMBitstream bitstream;
  incoming = getLastVideoFilter (frameStart, frameEnd - frameStart);
  _total = incoming->getInfo ()->nb_frames;
  _fps1000 = incoming->getInfo ()->fps1000;
  if (!_total)
    {
      GUI_Error_HIG (_("No frames to encode"),
                     _("Please check markers. Is \"A>\" == \">B\"?"));
      return 0;
    }

  printf ("Br:%d, qz:%d\n", bitrate, qz);
  if (!_audio)
    {
      if (!(fd = qfopen (name, "wb")))
	return 0;
    }
  else
    {
      ADM_assert (_muxer);
      sample_time = _total;
      sample_time *= 1000;
      sample_time /= _fps1000;	// target_time in second
      sample_time *= _audio->getInfo ()->frequency;
      sample_target = (uint32_t) floor (sample_time);

    }


  _w = incoming->getInfo ()->width;
  _h = incoming->getInfo ()->height;


  _page = _w * _h;
  _page += _page >> 1;

//                      if(!init(name,ADM_VCD,interlaced,widescreen)) return 0;
  if (!init (name, ADM_VCD, interlaced, bff, widescreen))
    return 0;			//WLA
  printf ("\n mpeg2enc init done \n");


  //_buffer       =new uint8_t[_w*_h*2];
  aImage = new ADMImage (_w, _h);
  _buffer_out = new uint8_t[_w * _h * 2];

  ADM_assert (aImage);
  ADM_assert (_buffer_out);

  encoding = new DIA_encoding (_fps1000);

  encoding->setPhasis ("Encoding.");
  encoding->setFrame (0, _total);
//      printf("Br:%d, qz:%d\n",bitrate,qz);

  switch (mpegtype)
    {
    case ADM_VCD:
      {
	encoding->setCodec ("VCD.");
	Mpeg2encVCD *dec;
	dec = new Mpeg2encVCD (_w, _h);
//                                      dec->init(1,0,_fps1000,interlaced,widescreen);
	dec->init (1, 0, _fps1000, interlaced, bff, widescreen, 0);	// WLA
	_codec = dec;
      }
      break;
    case ADM_SVCD:

      Mpeg2encSVCD * dec;
      dec = new Mpeg2encSVCD (_w, _h);
      dec->setMatrix (matrix);
//                                      dec->init(qz,bitrate,_fps1000,interlaced,widescreen);
      dec->init (qz, bitrate, _fps1000, interlaced, bff, widescreen, 0);
      // WLA
      _codec = dec;
      encoding->setCodec ("SVCD.");

      break;

    case ADM_DVD:
      {
	Mpeg2encDVD *dec;
	dec = new Mpeg2encDVD (_w, _h);
	dec->setMatrix (matrix);
//                                      dec->init(qz,bitrate,_fps1000,interlaced,widescreen);
	dec->init (qz, bitrate, _fps1000, interlaced, bff, widescreen, 0);
	// WLA
	_codec = dec;
	encoding->setCodec ("DVD.");

      }
      break;
    default:
      ADM_assert (0);
    }

  printf ("\n--encoding started--\n");
  if (_muxer)
    {
      if (audioProcessMode ())
	encoding->
	  setAudioCodec (getStrFromAudioCodec (_audio->getInfo ()->encoding));
      else
	encoding->setAudioCodec ("Copy");
      switch (_outputAs)
	{

	case MUXER_TS:
	  encoding->setContainer ("Mpeg TS");
	  break;
	case MUXER_VCD:
	  encoding->setContainer ("Mpeg VCD");
	  break;
	case MUXER_SVCD:
	  encoding->setContainer ("Mpeg SVCD");
	  break;
	case MUXER_DVD:
	  encoding->setContainer ("Mpeg DVD");
	  break;
	default:
	  ADM_assert (0);
	}

    }
  else
    encoding->setContainer ("Mpeg ES");
  bitstream.data = _buffer_out;
  for (uint32_t i = 0; i < _total; i++)
    {
      if (!incoming->getFrameNumberNoAlloc (i, &size, aImage, &flags))
	{
	  delete encoding;
          GUI_Error_HIG (_("Encoding error"), NULL);
	  if (fd)
	    qfclose (fd);
	  end ();
	  return 0;
	}
      bitstream.cleanup (i);
      bitstream.in_quantizer=0;
      _codec->encode (aImage, &bitstream);
      //_buffer_out , &len,&flags,&outquant);
      total_size += bitstream.len;
      encoding->feedFrame (bitstream.len);
      encoding->setQuant (bitstream.out_quantizer);
      encoding->setFrame (i, _total);
      // Null frame are only possible
      // when in prefill state for mpeg-X
      if (!len)
	continue;
      if (_muxer)
	{
#warning FIXME
#warning FIXME
#warning FIXME
#warning FIXME
	  _muxer->writeVideoPacket (&bitstream);
	  PACK_AUDIO;

	}
      else
	{
            qfwrite (_buffer_out, bitstream.len, 1, fd);
	  fflush (fd);
	}

      aprintf (" outquant %02d  size :%d flags %x\n", outquant, len, flags);

      if (!encoding->isAlive ())
	{
	  delete encoding;
	  end ();
	  if (fd)
	    qfclose (fd);
	  return 0;
	}
    }
  encoding->setPhasis ("Finishing");
  bitstream.data = _buffer_out;
  for (uint32_t i = 0; i < MPEG_PREFILL; i++)
    {
      bitstream.cleanup (i);
      _codec->encode (aImage, &bitstream);	//_buffer_out , &len,&flags);
      total_size += bitstream.len;
      encoding->feedFrame (bitstream.len);
      if (!_muxer)
          qfwrite (_buffer_out, bitstream.len, 1, fd);
      else
	{
            _muxer->writeVideoPacket (&bitstream);
	  PACK_AUDIO;
	}

      //      printf("\n pipe opened %ld\n",i);
      encoding->setFrame (i, _total);

    }
  delete encoding;

  if (!_muxer)
    qfclose (fd);
  else
    {
      _muxer->close ();
      delete _muxer;
      _muxer = NULL;
      deleteAudioFilter (_audio);
      _audio = NULL;
    }
  end ();
  return 1;

}
uint32_t audioFilter_getOuputFrequency(uint32_t inputFrequency)
{
	if(!audioProcessMode()) return inputFrequency;
	if(audioResampleMode == RESAMPLING_NONE) return inputFrequency;
	return audioFreq;
}
AVDMGenericAudioStream *buildAudioFilter(AVDMGenericAudioStream *currentaudiostream,  uint32_t starttime)
{
  AUDMAudioFilter         *lastFilter=NULL;
  AVDMGenericAudioStream  *output=NULL;
  AUDMEncoder             *tmpfilter=NULL;
  ch_route.mode = 0;

	// if audio is set to copy, we just return the first filter
  if(!audioProcessMode())
  {
    int32_t timeShiftMs=audioDelay*audioShift;
    deleteAudioFilter(NULL);
    output = new AVDMProcessAudio_RawShift(currentaudiostream, starttime, timeShiftMs);
    return output;

  }



// else we build the full chain
  lastFilter=buildInternalAudioFilter(currentaudiostream,starttime);
  
// and add encoder...


//_______________________________________________________
  uint8_t init;
  ADM_audioEncoderDescriptor *descriptor=getAudioDescriptor( activeAudioEncoder);
  
  if(!lastFilter)
  {
    printf(" buildInternalAudioFilter failed\n");
    return 0;
  }
  if(lastFilter->getInfo()->channels > descriptor->maxChannels)
  {
    GUI_Error_HIG(_("Codec Error"),_("The number of channels is greater than what the selected audio codec can do.\n"
        "Either change codec or use the mixer filter to have less channels."));
    deleteAudioFilter(NULL);
    return 0; 
  }
  switch(activeAudioEncoder)
  {

                  case AUDIOENC_LPCM:
                  case AUDIOENC_NONE:
                  {
                    AUDMEncoder_PCM *pcm;
                    uint32_t fourcc,revert=0;
                    
                    if(activeAudioEncoder==AUDIOENC_LPCM) fourcc=WAV_LPCM;
                    else          fourcc=WAV_PCM;
                    
#ifdef ADM_BIG_ENDIAN                    
                    if(fourcc==WAV_PCM)
#else
                    if(fourcc==WAV_LPCM)
#endif
                        revert=1;
                    pcm = new AUDMEncoder_PCM(revert,fourcc,lastFilter);
                    tmpfilter=pcm;
                  }
                  break;
#ifdef USE_VORBIS
             case AUDIOENC_VORBIS:
                {
                  AUDMEncoder_Vorbis *vorbis;
                  vorbis = new AUDMEncoder_Vorbis(lastFilter);
                  tmpfilter=vorbis;
                  break;
                }
#endif		
#ifdef USE_FAAC
    case AUDIOENC_FAAC:
                  {
                      AUDMEncoder_Faac *faac;
                          faac = new AUDMEncoder_Faac(lastFilter);
                          tmpfilter=faac;
                  }
                  break;
#endif		

#ifdef HAVE_LIBMP3LAME
    case AUDIOENC_MP3:
              {
                AUDMEncoder_Lame *plame = NULL;

                            plame = new AUDMEncoder_Lame(lastFilter);
                            tmpfilter=plame;
                }
              break;
#endif
    case AUDIOENC_AC3:
    case AUDIOENC_MP2:
                    {
                      AUDMEncoder_Lavcodec *lavcodec = NULL;
                      uint32_t fourc;
                      
                      if(activeAudioEncoder==AUDIOENC_AC3) fourc=WAV_AC3;
                      else fourc=WAV_MP2;
                    
                      lavcodec = new AUDMEncoder_Lavcodec(fourc,lastFilter);
                      tmpfilter=lavcodec;
                    }
              break;
    case  AUDIOENC_2LAME:
              {
                  AUDMEncoder_Twolame *toolame_enc = NULL;
                          toolame_enc = new AUDMEncoder_Twolame(lastFilter);
                          tmpfilter=toolame_enc;
              }
    	  break;

    default:
      ADM_assert(0);
  }
//_______________________________________________________

  if(!tmpfilter->init(descriptor))
  {
    delete tmpfilter;
    tmpfilter=NULL;
    GUI_Error_HIG("Encoder initialization failed", "Not activated."); 
  }
  output=tmpfilter;

  currentaudiostream->beginDecompress();

  return output;
}