/***************************************************************************
                          adm_encdivx.cpp  -  description
                             -------------------
    begin                : Sun Jul 14 2002
    copyright            : (C) 2002 by mean
    email                : fixounet@free.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>

#include <time.h>
#include <sys/time.h>
#include "config.h"
#ifdef USE_DIVX

#include "fourcc.h"
#include "avi_vars.h"
#include "ADM_toolkit/toolkit.hxx"

#include "ADM_encoder/ADM_vidEncode.hxx"

//#include "ADM_video/ADM_vidEncode.hxx"

#include "ADM_codecs/ADM_divxInc.h"
#include "ADM_video/ADM_genvideo.hxx"
#include "ADM_encoder/adm_encoder.h"
#include "ADM_codecs/ADM_divxEncode.h"
#include "ADM_encoder/adm_encdivx.h"

extern  int getCompressParams(COMPRESSION_MODE * mode, uint32_t * qz,
		      uint32_t * br,uint32_t *fs);

/*_________________________________________________*/
EncoderDivx::EncoderDivx	(DIVXConfig *config  )
		{
			 	_codec=NULL;
				fd=NULL;
				entries=NULL;
				strcpy(_logname,"");
       				_frametogo=0;
				memcpy(&_param,&(config->generic),sizeof(_param));           
		} ;
//--------------------------------
uint8_t EncoderDivx::configure( AVDMGenericVideoStream *instream)

{
     //  COMPRES_PARAMS par;

		ADM_assert(instream);
        ADV_Info 			*info;

		info=instream->getInfo(  );
		_w=info->width;
		_h=info->height;
		_vbuffer=new uint8_t[_w*_h*3];
		ADM_assert(_vbuffer);


		switch(_param.mode)
		{
		case COMPRESS_CQ :	_state=	enc_CQ;
					    					_codec=new divxEncoderCQ(_w,_h);
										_codec->init( _param.qz,info->fps1000);
										break;
		case COMPRESS_CBR :	_state=	enc_CBR;
					    					_codec=new divxEncoderCBR(_w,_h);
										_codec->init( _param.bitrate,info->fps1000);           //qz,bitrate,finalsize;
										break;
		case COMPRESS_2PASS: _state=	enc_Pass1;
                     								_codec=new divxEncoderCQ(_w,_h);
                     								_codec->init( 2,info->fps1000);
										break;
		default:
					ADM_assert(0);

        }
       		_in=instream;
		printf("\n Divx Encoder , w: %lu h:%lu mode:%d",_w,_h, _state);
		return 1;

}



uint8_t EncoderDivx::startPass1( void )
{
		   	ADM_assert(_state==  enc_Pass1);
			_frametogo=0;
			printf("\n Starting pass 1\n");
			printf(" Creating logfile :%s\n",_logname);
        		fd=fopen(_logname,"wt");
                   	if(!fd)
			{
					printf("\n cannot create logfile !\n");
                    			return 0;
			}
			return 1;
}


uint8_t EncoderDivx::isDualPass( void )
{
 		if((_state==enc_Pass1) ||(_state==enc_Pass2))
		{
        	return 1;
		}
		return 0;

}
uint8_t EncoderDivx::setLogFile( const char *lofile,uint32_t nbframe )
{
	strcpy(_logname,lofile);
	_frametogo=nbframe;
	return 1;

}

//______________________________
uint8_t EncoderDivx::encode( uint32_t frame,uint32_t *len,uint8_t *out,uint32_t *flags)
{
uint32_t l,f;
myENC_RESULT enc;

		ADM_assert(_codec);
		ADM_assert(_in);

		if(!_in->getFrameNumberNoAlloc(frame,&l,_vbuffer,&f))
		{
				printf("\n Error : Cannot read incoming frame !");
				return 0;
		}

 		switch(_state)
		{
    				case enc_CBR:
				case enc_CQ:
							return _codec->encode(   _vbuffer,out,len,flags);
							break;
				case enc_Pass1:

                              break;

				default:
							ADM_assert(0);
        }
		return 0;
}

//_______________________________
uint8_t EncoderDivx::stop( void)
{
 	delete _codec;
	_codec=0;
	return 1;

}

uint8_t EncoderDivx::startPass2( void )
{

	return 0;
}

#endif
