/**
    \fn saveAsJpg
    \brief save current image into filename, into jpg format
*/
uint8_t  ADMImage::saveAsJpg(const char *filename)
{
 ffmpegEncoderFFMjpeg *codec=NULL;
  FILE *fd;
  uint8_t *buffer=NULL;
  uint32_t sz;
  

        sz = _width*_height*3;
        ADMBitstream bitstream(sz);
        buffer=new uint8_t[sz];
        bitstream.data=buffer;
        codec=new  ffmpegEncoderFFMjpeg(_width,_height,FF_MJPEG)  ;
        codec->init( 95,25000);
        if(!codec->encode(this,&bitstream))
        {
                GUI_Error_HIG(QT_TR_NOOP("Cannot encode the frame"), NULL);
                delete [] buffer;
                delete codec;
                return 0;
        }
        delete codec;
        fd=fopen(filename,"wb");
        if(!fd)
        {
                GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP( "Cannot open \"%s\" for writing."), filename);
                delete [] buffer;
                return 0;
        }
        fwrite (buffer, bitstream.len, 1, fd);
        fclose(fd);
        delete [] buffer;
        return 1;
}
Beispiel #2
0
static inline void emulateSingleFrameBroadcastTransfer(CanDriver& can, uavcan::NodeID node_id,
                                                       const MessageType& message, uavcan::TransferID tid)
{
    uavcan::StaticTransferBuffer<100> buffer;
    uavcan::BitStream bitstream(buffer);
    uavcan::ScalarCodec codec(bitstream);

    // Manual message publication
    ASSERT_LT(0, MessageType::encode(message, codec));
    ASSERT_GE(8, buffer.getMaxWritePos());

    // DataTypeID data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id,
    // uint_fast8_t frame_index, TransferID transfer_id, bool last_frame
    uavcan::Frame frame(MessageType::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast,
                        node_id, uavcan::NodeID::Broadcast, tid);
    frame.setStartOfTransfer(true);
    frame.setEndOfTransfer(true);

    ASSERT_EQ(buffer.getMaxWritePos(), frame.setPayload(buffer.getRawPtr(), buffer.getMaxWritePos()));

    uavcan::CanFrame can_frame;
    ASSERT_TRUE(frame.compile(can_frame));

    can.pushRxToAllIfaces(can_frame);
}
//___________________________________________________
uint8_t	ADM_ogmWriteProcess::writeVideo(uint32_t frame)
{
    uint32_t len,flags;
    uint8_t ret;
    uint32_t page=_incoming->getInfo ()->width*_incoming->getInfo ()->height;
    ADMBitstream bitstream(page*3);
    bitstream.data=_videoBuffer;

    ret= _encode->encode ( frame, &bitstream);
    if(!bitstream.len && _prestoring)
    {
        printf("Frame skipped\n");
        _prestore++;
        return 1;
    }
    _prestoring=0;
    bitstream.dtsFrame=frame-_prestore;
    if(!ret)
    {
        printf("OgmWrite: Error encoding frame %d\n",frame);
        return 0;
    }
    encoding_gui->setFrame(frame,bitstream.len,bitstream.out_quantizer,_togo);
    return videoStream->write(bitstream.len,_videoBuffer,bitstream.flags,bitstream.dtsFrame);
}
void GeneralUtils::configureFabric(std::vector<char> const &buffer) {
    if (GeneralUtils::fileExists("/dev/xdevcfg")) {
        //We are on Kernel 4.6 or lower
        FILE *fd = fopen("/dev/xdevcfg", "w");
        if (fd == NULL) {
            throw std::runtime_error("Could not open /dev/xdevcfg device");
        }
        size_t written = fwrite(buffer.data(), sizeof(char), buffer.size(), fd);
        if (written != buffer.size()) {
            throw std::runtime_error("Could not write complete bitstream to /dev/xdevcfg");
        }
        fclose(fd);
    } else if (GeneralUtils::fileExists("/sys/class/fpga_manager/fpga0/firmware")) {
        const char bitstreamFile[] = "fabric_bitstream.bin";

        std::ofstream bitstream(std::string("/lib/firmware/") + bitstreamFile, std::ios::out | std::ios::binary | std::ios::trunc);
        bitstream.write(buffer.data(), buffer.size());
        bitstream.close();

        std::ofstream firmware("/sys/class/fpga_manager/fpga0/firmware");
        firmware << bitstreamFile;
        firmware.close();
        if (!firmware.good()) {
            throw std::runtime_error("Fabric configuration through fpga_manager failed!");
        }
        // Loading was successful, wait for half a second before using the fpga!
        // or else the board is gone... praise the fpga_manager
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    } else {
        // TODO load AWS bitstream
    }
}
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;

}
	//we receive all the packets here
	void packetReceiver::receive() {
		RakNet::Packet *packet;
		for (packet = this->nethandler->peer->Receive(); packet; this->nethandler->peer->DeallocatePacket(packet), packet = this->nethandler->peer->Receive()) {
			RakNet::BitStream bitstream(packet->data, packet->length, false); // The false is for efficiency so we don't make a copy of the passed data
			basePacket base;
			//we can receive bitstreams or something else
			if ((unsigned char)packet->data[0] == ID_TIMESTAMP) {
				bitstream.Read(base.useTimeStamp);
				bitstream.Read(base.timeStamp);
				bitstream.Read(base.typeId);
			} else {
				base.typeId = (unsigned char) packet->data[0];
			}
			
			switch (base.typeId)		//this is the packet's id (packetTypes.h)
			{
				//we receive the initial packet when connecting to a server
				case ID_CONNECTION_REQUEST_ACCEPTED:
					{
						FILE_LOG(logINFO) << "connection accepted";
						this->nethandler->server = packet->systemAddress;
					}
					break;
				case INIT_CONNECTOR_PACKET:
					{
						RakNet::RakString receivedMap;
						bitstream.Read(receivedMap);
						const char* mapCStr = receivedMap.C_String();
						std::stringstream s;
						s << mapCStr;
						unsigned long uniqueid;
						bitstream.Read(uniqueid);
						FILE_LOG(logINFO) << "received init connector: " << uniqueid;	
						this->nethandler->client->uniqueid = uniqueid;
						this->nethandler->client->gameHandler.setMapFromStream(s);
					}
					break;
				case NEWPLAYER_PACKET:
					{
						unsigned long uniqueid;
						bitstream.Read(uniqueid);
						RakNet::RakString name;
						bitstream.Read(name);
						FILE_LOG(logINFO) << "NEW PLAYER RECEIVED " << uniqueid;

						World *world = &this->nethandler->client->gameHandler.currentWorld;
						world->addPlayer(uniqueid);
					}
					break;
				case PLAYERMOVE_PACKET:
					{
						//FILE_LOG(logDEBUG) << "RECEIVED PLAYER MOVE PACKET";
						basePacket base;
						unsigned long uniqueid;
						bitstream.Read(uniqueid);
						float x;
						bitstream.Read(x);
						float y;
						bitstream.Read(y);
						float velx;
						bitstream.Read(velx);
						float vely;
						bitstream.Read(vely);
						int inputDirection;
						bitstream.Read(inputDirection);
						bool inputJump;
						bitstream.Read(inputJump);

						World *world = &this->nethandler->client->gameHandler.currentWorld;
						//world->playerMoveFromServer(uniqueid, x, y, velx, vely, inputDirection, inputJump);

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

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

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

        if(!_encode->startPass2 ())
        {
                printf("Pass2 ignition failed\n");
                return 0;
        }
        printf("First pass : send %u frames\n",sent);
        encoding_gui->setPhasis ("2nd Pass");
        return 1;
}
//________________________________________________
uint8_t	ADM_ogmWriteProcess::initVideo(const char *name)
{
    uint32_t w,h,fps1000,fcc;
    _prestore=0;
    _prestoring=1;
    _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
    _togo=_incoming->getInfo()->nb_frames;
    _encode = getVideoEncoder (_incoming->getInfo()->width,_incoming->getInfo()->height);
    if (!_encode)
        return 0;

    TwoPassLogFile=new char[strlen(name)+6];
    strcpy(TwoPassLogFile,name);
    strcat(TwoPassLogFile,".stat");

    _encode->setLogFile(TwoPassLogFile,_togo);

    if (!_encode->configure (_incoming))
    {
        delete 	_encode;
        _encode = NULL;
        GUI_Error_HIG (QT_TR_NOOP("Filter init failed"), NULL);
        return 0;
    };
    w= _incoming->getInfo ()->width;
    h=_incoming->getInfo ()->height;
    fps1000=_incoming->getInfo ()->fps1000;
    _fps1000=fps1000;
    fcc= fourCC::get((uint8_t *)_encode->getCodecName());
    _videoBuffer=new uint8_t[w*h*3];
    encoding_gui->setCodec(_encode->getDisplayName());

//-----------------------VBR--------------------------------------
    if (_encode->isDualPass ())
    {
        uint8_t *buffer;
        uint32_t len, flag;
        FILE *tmp;
        uint8_t reuse=0;

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

        if((tmp=fopen(TwoPassLogFile,"rt")))
        {
            fclose(tmp);
            if(GUI_Question(QT_TR_NOOP("\n Reuse the existing log-file ?")))
            {
                reuse=1;
            }
        }

        if(!reuse)
        {
            aprintf("**Pass 1:%lu\n",_togo);
            _encode->startPass1 ();
            encoding_gui->setCodec((char *)_encode->getCodecName());
            encoding_gui->setPhasis("Pass one");
            ADMBitstream bitstream(w*h*3);
            bitstream.data=_videoBuffer;
            //__________________________________
            //   now go to main loop.....
            //__________________________________
            for (uint32_t cf = 0; cf < _togo; cf++)
            {
                bitstream.cleanup(cf);
                if (!_encode->encode (cf, &bitstream))
                {
                    printf("\n Encoding of frame %lu failed !\n",cf);
                    return 0;
                }
                encoding_gui->setFrame(cf,bitstream.len,bitstream.out_quantizer,_togo);
                if(!encoding_gui->isAlive())
                {
                    return 0;
                }
            }
            aprintf("**Pass 1:done\n");
        }// End of reuse

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

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


    stream_header header;
    int64_t dur64;
    uint32_t dur32;
    uint16_t dur16;

    memset(&header,0,sizeof(header));

    memcpy(&(header.streamtype),"video\0\0\0",8);
    MEMCPY(&(header.subtype),&fcc,4);

    //header.size=sizeof(header);
    dur32=sizeof(header);
    MEMCPY(&header.size,&dur32,4);
    MEMCPY(&(header.video.width),&w,4);
    MEMCPY(&(header.video.height),&h,4);
    // Timing ..
    double duration; // duration in 10us
    duration=fps1000;
    duration=1000./duration;
    duration*=1000*1000;
    duration*=10;

    dur64=(int64_t)duration;

    MEMCPY(&header.time_unit,&dur64,8);
    dur64=1;
    MEMCPY(&header.samples_per_unit,&dur64,8);

    dur32=0x10000;
    MEMCPY(&header.buffersize,&dur32,4);

    dur16=24;
    MEMCPY(&header.bits_per_sample,&dur16,2);


    //header.default_len=1;
    dur32=1;
    MEMCPY(&header.default_len,&dur32,4);

    return videoStream->writeHeaders(sizeof(header),(uint8_t *)&header); // +4 ?

}
/*
===================
idSWF::LoadSWF
===================
*/
bool idSWF::LoadSWF( const char* fullpath )
{

	idFile* rawfile = fileSystem->OpenFileRead( fullpath );
	if( rawfile == NULL )
	{
		idLib::Printf( "SWF File not found %s\n", fullpath );
		return false;
	}
	
	swfHeader_t header;
	rawfile->Read( &header, sizeof( header ) );
	
	if( header.W != 'W' || header.S != 'S' )
	{
		idLib::Warning( "Wrong signature bytes" );
		delete rawfile;
		return false;
	}
	
	if( header.version > 9 )
	{
		idLib::Warning( "Unsupported version %d", header.version );
		delete rawfile;
		return false;
	}
	
	bool compressed;
	if( header.compression == 'F' )
	{
		compressed = false;
	}
	else if( header.compression == 'C' )
	{
		compressed = true;
	}
	else
	{
		idLib::Warning( "Unsupported compression type %c", header.compression );
		delete rawfile;
		return false;
	}
	idSwap::Little( header.fileLength );
	
	// header.fileLength somewhat annoyingly includes the size of the header
	uint32 fileLength2 = header.fileLength - ( uint32 )sizeof( swfHeader_t );
	
	// slurp the raw file into a giant array, which is somewhat atrocious when loading from the preload since it's already an idFile_Memory
	byte* fileData = ( byte* )Mem_Alloc( fileLength2, TAG_SWF );
	size_t fileSize = rawfile->Read( fileData, fileLength2 );
	delete rawfile;
	
	if( compressed )
	{
		byte* uncompressed = ( byte* )Mem_Alloc( fileLength2, TAG_SWF );
		if( !Inflate( fileData, ( int )fileSize, uncompressed, fileLength2 ) )
		{
			idLib::Warning( "Inflate error" );
			Mem_Free( uncompressed );
			return false;
		}
		Mem_Free( fileData );
		fileData = uncompressed;
	}
	idSWFBitStream bitstream( fileData, fileLength2, false );
	
	swfRect_t frameSize;
	bitstream.ReadRect( frameSize );
	
	if( !frameSize.tl.Compare( vec2_zero ) )
	{
		idLib::Warning( "Invalid frameSize top left" );
		Mem_Free( fileData );
		return false;
	}
	
	frameWidth = frameSize.br.x;
	frameHeight = frameSize.br.y;
	frameRate = bitstream.ReadU16();
	
	// parse everything
	mainsprite->Load( bitstream, true );
	
	// now that all images have been loaded, write out the combined image
	idStr atlasFileName = "generated/";
	atlasFileName += fullpath;
	atlasFileName.SetFileExtension( ".tga" );
	
	WriteSwfImageAtlas( atlasFileName );
	
	Mem_Free( fileData );
	
	return true;
}
bool FeatureDetector::match(Image image)
{
	ImageBitstream bitstream(image);

	return match(bitstream);
}