/*********************************************************************************
*																				
* Copyright (c) 2008 Samsung System LSI 										
* All rights reserved.															
*																				
* This software is test sample code for MFC v5.0					
*																				
* Author : Jiyoung Shin 								    						
* Last Changed : 2008.08.05 													
*********************************************************************************/

#include <windows.h>

#include "SsbSipMfcApi.h"
#include "MfcParser.h"
#include "MfcRender.h"
#include "CMMAPI.h"
#include "SsbSipMfcConfig.h"


int MFCParseEncoderCFG(HANDLE *hFile, void *param, int *NumOfFrame, char *inputPath, char *outputPath, char *refPath,  
					SSBSIP_MFC_CODEC_TYPE *codec_type, int *width, int *height);
SSBSIP_MFC_CODEC_TYPE GetCodecType(char *ext);


int SsbSipMfcDecoderTest(MFCExeMode exeMode, int *ForceExit)
{
	void *hOpen, *hParser;
	void *virInBuf, *phyInBuf;
	int nFrameLeng;
	int isFirstFrame;
	unsigned int frame_num = 0;
	unsigned int display_num = 0;
	int isLastFrame;

	SSBSIP_MFC_DEC_OUTBUF_STATUS status;
	SSBSIP_MFC_CODEC_TYPE codec_type;
	SSBSIP_MFC_DEC_OUTPUT_INFO output_info;
	SSBSIP_MFC_ERROR_CODE	ret;

	FILE	*fp_cfg;
	char	InputPath[512];
	char	OutputPath[512];
	char	ext[8];
	char	*divider;
	int		set_conf_val;
	int		decodingTime, totalDecodingTime, totalDisplayTime, totalParsingTime;
#if defined(FILE_DUMP_TILE_NV12)
	FILE	*fp;
	char	*YBuf, *CbBuf, *CrBuf;
	int		i, j;
	unsigned int uImgEndAddr;
	HANDLE	hCMM;
	CMM_ALLOC_PRAM_T	CMMParam;
	int 				phyYUV420Buf;
	int					virYUV420Buf;
	BOOL				r;
#endif
	FILE	*fp;
	
	if( (fp_cfg = fopen(DECODER_CONFIG_FILE, "rt"))==NULL )
	{
		printf("Cfg open error(%s)\n", DECODER_CONFIG_FILE);
		return 0;
	}

	do{
		if(*ForceExit)
			break;
		
		printf("SsbSipMfcDecoderTest\n");
		memset(InputPath, 0x00, sizeof(InputPath));
		memset(OutputPath, 0x00, sizeof(OutputPath));
		fgets(InputPath, sizeof(InputPath)-1, fp_cfg);
		memcpy(OutputPath, InputPath, strlen(InputPath));
		divider = strchr(OutputPath, '.');
		strncpy(ext, divider, 4);
		*divider = '\0';
		strcat(OutputPath, ".nv12");

		divider = strchr(InputPath, '.');
		divider += 4;
		*divider = '\0';

		codec_type = GetCodecType(ext);

		printf("---------------------------------------------------------\n");
		printf("Start Decoding..................................\n");
		printf("- exeMode : %d CodecType : %d\n- inFile : %s\n- outFile : %s\n\n", exeMode, codec_type, InputPath, OutputPath);

		if((hParser = SsbSipParserInit(codec_type,InputPath ,MAX_DECODER_INPUT_BUFFER_SIZE)) == NULL)
		{
			printf("SsbSipParserInit Failed\n");
			return MFC_RET_FAIL;
		}


		if(!SsbSipDisplayInit(exeMode))
		{
			printf("SsbSipDisplayInit Failed\n");
			return MFC_RET_FAIL;
		}


		hOpen = SsbSipMfcDecOpen();
		if(hOpen == NULL)
		{
			printf("SsbSipMfcDecOpen Failed\n");
			return MFC_RET_FAIL;
		}

		virInBuf = SsbSipMfcDecGetInBuf(hOpen, &phyInBuf, MAX_DECODER_INPUT_BUFFER_SIZE);
		if(virInBuf == NULL)
		{
			printf("SsbSipMfcDecGetInBuf Failed\n");
			return MFC_RET_FAIL;
		}

#ifdef _SLICE_BASED_INTERFACE_
		set_conf_val = 1;
		SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_SLICE_ENABLE, &set_conf_val);
#endif

		set_conf_val = 3;
		SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &set_conf_val);

		if(codec_type == H264_DEC){
			set_conf_val = 4;
			SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_DISPLAY_DELAY, &set_conf_val);
		}

	#if defined(FILE_DUMP_TILE_NV12)	
		fp = fopen(OutputPath, "wb");
		if(fp == NULL){
			printf("file open error : %s\n", OutputPath);
			goto END_OF_DEC;
		}
	#endif

		isFirstFrame = 1;
		isLastFrame = 0;
		frame_num = 0;
		display_num = 0;
		status = MFC_GETOUTBUF_STATUS_NULL;
		totalDecodingTime = 0;
		totalDisplayTime = 0;
		totalParsingTime = GetTickCount();
		do
		{

			if(*ForceExit){
				printf("\nSsbSipMfcDecoderTest Exit by User\n");
				break;
			}

			if((!isLastFrame) && (status != MFC_GETOUTBUF_DISPLAY_ONLY)){
				nFrameLeng = SsbSipParserFrameGet(hParser, frame_num, virInBuf, &isLastFrame);
				if(nFrameLeng != 0)
					frame_num++;
			}

			if(isFirstFrame)
			{
				isFirstFrame = 0;

				if(SsbSipMfcDecInit(hOpen, codec_type, nFrameLeng) != MFC_RET_OK){
					printf("SsbSipMfcDecInit Failed\n");
					break;
				}

				if(codec_type != H263_DEC)
					continue;
			}



			if(isLastFrame){
				set_conf_val = 1;
				SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_IS_LAST_FRAME, &set_conf_val);
				isLastFrame = 0;
			}

			decodingTime = GetTickCount();
			ret = SsbSipMfcDecExe(hOpen, nFrameLeng);
			if(ret != MFC_RET_OK){
				printf("SsbSipMfcDecExe Failed(frame_num : %d ret : %d)\n", frame_num, ret);
				break;
			}

			status = SsbSipMfcDecGetOutBuf(hOpen, &output_info);
			totalDecodingTime += (GetTickCount() - decodingTime);

			if((status == MFC_GETOUTBUF_DISPLAY_DECODING) || (status == MFC_GETOUTBUF_DISPLAY_ONLY))
			{
	#if defined(FILE_DUMP_TILE_NV12)
				if(display_num == 0){
					fwrite(output_info.YVirAddr, 1, output_info.buf_width*output_info.buf_height, fp);
					fwrite(output_info.CVirAddr, 1, output_info.buf_width*output_info.buf_height>>1, fp);
				}
	#endif

				
				SsbSipDisplayStart(exeMode, (int)output_info.YPhyAddr, (int)output_info.CPhyAddr, output_info.buf_width, output_info.buf_height);
				display_num++;
				//printf("consumed byte num : %d  res_change : %d \n", output_info.consumedByte, output_info.res_change);


			}
			totalDisplayTime += (GetTickCount() - decodingTime);
	
		}while(status != MFC_GETOUTBUF_DISPLAY_END);
		totalParsingTime = GetTickCount() - totalParsingTime;

END_OF_DEC :printf("Decoding Finished!(%d)\n", status);
			printf("%d frame parsed, %d frame displayed\n\n", frame_num, display_num);
			printf("img_width : %d img_height : %d\n", output_info.img_width, output_info.img_height);
			printf("buf_width : %d buf_height : %d\n", output_info.buf_width, output_info.buf_height);
			printf("--------------< Performance >--------------------------------------------\n");
			printf("Decoding                     : %.2f fps / %d msec\n", (float)(display_num*1000.0/totalDecodingTime), totalDecodingTime);
			printf("Decoding & Display           : %.2f fps / %d msec\n", (float)(display_num*1000.0/totalDisplayTime), totalDisplayTime);
			printf("Decoding & Display & Parsing : %.2f fps / %d msec\n", (float)(display_num*1000.0/totalParsingTime), totalParsingTime);
		SsbSipParserDeInit(hParser);
		SsbSipDisplayDeInit(exeMode);
		SsbSipMfcDecClose(hOpen);

	#if defined(FILE_DUMP_TILE_NV12)
		fclose(fp);
	#endif
	}while(!feof(fp_cfg));

	fclose(fp_cfg);
	printf("---------------------------------------------------------\n");
	return MFC_RET_OK;
}


SSBSIP_MFC_CODEC_TYPE GetCodecType(char *ext)
{

	if((strncmp(ext, ".264", 4) == 0) || (strncmp(ext, ".26l", 4) == 0))
		return H264_DEC;
	if(strncmp(ext, ".263", 4) == 0)
		return H263_DEC;
	if(strncmp(ext, ".m4v", 4) == 0)
		return MPEG4_DEC;
	if(strncmp(ext, ".dvx", 4) == 0)
		return DIVX502_DEC;
	if(strncmp(ext, ".xvd", 4) == 0)
		return XVID_DEC;
	if(strncmp(ext, ".m2v", 4) == 0)
		return MPEG2_DEC;
	if(strncmp(ext, ".rcv", 4) == 0)
		return VC1RCV_DEC;
	if((strncmp(ext, ".vc1", 4) == 0) || (strncmp(ext, ".VC1", 4) == 0))
		return VC1_DEC;
	if(strncmp(ext, ".avi", 4) == 0)
		return MPEG4_DEC;
	
	return UNKNOWN_TYPE;
}


int SsbSipMfcEncoderTest(MFCExeMode exeMode, int *ForceExit)
{

	void *hOpen;
	void *phyInbuf, *virInbuf;
	void *phyOutbuf, *virtOutbuf;
	void *param;
	int width, height;
	int readSize, frame;
	char InputPath[512];
	char OutputPath[512];
	char RefPath[256];
	char* CbCrBuf;
	char *p_nv12, *p_cb, *p_cr;
	int NumOfFrames;
	char *outbuf, *tmpbuf;
	long total_size;
	int	i;

	SSBSIP_MFC_CODEC_TYPE codec_type;
	SSBSIP_MFC_ENC_INPUT_INFO input_info;
	SSBSIP_MFC_ENC_OUTPUT_INFO output_info;
	SSBSIP_MFC_ERROR_CODE	ret = MFC_RET_OK;
	HANDLE	hCfgFile = NULL;
	int		set_conf_val;
	FILE	*fp_yuv, *fp_strm;
	int r;
	int encodingTime, totalTime;

	param = malloc(sizeof(SSBSIP_MFC_ENC_H264_PARAM));
	CbCrBuf = (char *)malloc(2*1024*1024);

//start loop
	while(1)
	{


		if(*ForceExit)
			break;

		memset(param, 0 , sizeof(SSBSIP_MFC_ENC_H264_PARAM));
		r = MFCParseEncoderCFG(&hCfgFile, param, &NumOfFrames, InputPath, OutputPath, RefPath,
			&codec_type, &width, &height);
		if(r==0)
			break;

		printf("\n--------------------------------------------------------\n");
		printf("Start Encoding.........(codec_type:%d)(width:%d)(height:%d)\n", codec_type, width, height);
		printf("- inFile : %s\n", InputPath);
		printf("- outFile : %s\n", OutputPath);
		printf("- refFile : %s\n", RefPath);

		fp_yuv = fopen(InputPath, "rb");
		if (fp_yuv == NULL) {
			printf("Cannot open input YUV file.(%s)\n", InputPath);
			ret = MFC_RET_FAIL;
			break;
		}
		fp_strm = fopen(OutputPath, "wb");
		if (fp_strm == NULL) {
			printf("Cannot open output stream file.(%s)\n", OutputPath);
			ret = MFC_RET_FAIL;
			break;
		}

		hOpen = SsbSipMfcEncOpen();
		if(hOpen == NULL)
		{
			printf("SsbSipMfcEncOpen Failed\n");
			ret = MFC_RET_FAIL;
			break;;
		}

		if(SsbSipMfcEncInit(hOpen, param) != MFC_RET_OK)
		{
			printf("SsbSipMfcEncInit Failed\n");
			ret = MFC_RET_FAIL;
			break;
		}

		if(codec_type != H263_ENC)  // no header for H.263
		{
			SsbSipMfcEncGetOutBuf(hOpen, &output_info);
			if(output_info.headerSize <= 0)
			{
				printf("Header Encoding Failed\n");
				ret = MFC_RET_FAIL;
				break;
			}
			fwrite(output_info.StrmVirAddr, 1, output_info.headerSize, fp_strm);
		}

		if(SsbSipMfcEncGetInBuf(hOpen, &input_info) != MFC_RET_OK)
		{
			printf("SsbSipMfcEncGetInBuf Failed\n");
			ret = MFC_RET_FAIL;
			break;
		}
		printf("SsbSipMfcEncGetInBuf:: Yphy(0x%08x) Cphy(0x%08x)\n", input_info.YPhyAddr, input_info.CPhyAddr);

		if((input_info.YVirAddr == NULL) || (input_info.CVirAddr == NULL))
		{
			printf("Buffer is null after SsbSipMfcEncGetInBuf\n");
			printf("SsbSipMfcEncGetInBuf() have to be called after SsbSipMfcEncInit() \n");
			ret = MFC_RET_FAIL;
			break;
		}


		frame = 0;
		total_size = 0;
		totalTime = 0;
		do
		{
			if(*ForceExit){
				printf("\nSsbSipMfcEncoderTest Exit by User\n");
				break;
			}

			readSize = fread(input_info.YVirAddr, 1, width * height, fp_yuv);
			if(readSize == 0){
				printf("Y readSize == 0\n");
				break;	
			}

			readSize = fread(CbCrBuf, 1, (width * height) >> 1, fp_yuv);
			if(readSize == 0){
				printf("CbCr readSize == 0\n");
				break;	
			}

			// convert YV12 -> NV12
			p_nv12 = (char *)input_info.CVirAddr;
			p_cb = CbCrBuf;
			p_cr = CbCrBuf;
			p_cr += ((width * height) >> 2);

			for(i = 0; i < (width * height) >> 2; i++){
				*p_nv12 = *p_cb;
				p_nv12++;
				*p_nv12 = *p_cr;
				p_nv12++;
				p_cb++;
				p_cr++;
			}

			encodingTime = GetTickCount();
			ret = SsbSipMfcEncSetInBuf(hOpen, &input_info);
			if(ret != MFC_RET_OK){
				printf("SsbSipMfcEncSetInBuf Failed(frame_num : %d ret : %d)\n", frame, ret);
				break;
			} 

#if 0 // dynamic change test for frame/bit rate
			if(frame == 22){
				set_conf_val = 15;
				SsbSipMfcEncSetConfig(hOpen, MFC_ENC_SETCONF_CHANGE_FRAME_RATE, &set_conf_val);
				printf("\n\n !!Change Frame Rate .........(%d)\n", set_conf_val);

				//set_conf_val = 70000;
				//SsbSipMfcEncSetConfig(hOpen, MFC_ENC_SETCONF_CHANGE_BIT_RATE, &set_conf_val);
				//printf("\n\n !!Change Bit Rate .........(%d)\n", set_conf_val);

				//set_conf_val = NOT_CODED;
				//SsbSipMfcEncSetConfig(hOpen, MFC_ENC_SETCONF_FRAME_TYPE, &set_conf_val);
				//printf("\n\n !!Change Frame type to NOT_CODED\n");
			}
#endif

			ret = SsbSipMfcEncExe(hOpen);
			if(ret != MFC_RET_OK){
				printf("Encoding Failed(frame_num : %d ret : %d)\n", frame, ret);
				break;
			} 
	
			SsbSipMfcEncGetOutBuf(hOpen, &output_info);
			if(output_info.StrmVirAddr == NULL)
			{
				printf("SsbSipMfcEncGetOutBuf Failed\n");
				ret = MFC_RET_FAIL;
				break;
			}
			totalTime += (GetTickCount() - encodingTime);

			//printf("%d encoded(size : 0x%x)(frametype:%c)\n", frame, output_info.dataSize, (output_info.frameType==1)?'I':'P');
			fwrite(output_info.StrmVirAddr, 1, output_info.dataSize, fp_strm);

			frame++;

		}while(frame < NumOfFrames);

		SsbSipMfcEncClose(hOpen);
		fclose(fp_yuv);
		fclose(fp_strm);
		printf("%d frame encoded (0x%x byte)\n", frame, total_size);
		printf("\n--------------< Performance >--------------------------\n");
		printf("Encoding  : %.2f fps / %d msec\n", (float)(frame*1000.0/totalTime), totalTime);
		printf("\n-------------------------------------------------------\n\n");

	}


	free(param);
	free(CbCrBuf);
	return ret;

	return 1;
}



int SsbSipMfcDecoderUnitTest(MFCExeMode exeMode, int *ForceExit)
{
	void *hOpen, *hParser;
	void *virInBuf, *phyInBuf;
	int nFrameLeng;
	int isFirstFrame;
	unsigned int frame_num = 0;
	unsigned int display_num = 0;
	int isLastFrame;

	SSBSIP_MFC_DEC_OUTBUF_STATUS status;
	SSBSIP_MFC_CODEC_TYPE codec_type;
	SSBSIP_MFC_DEC_OUTPUT_INFO output_info;
	SSBSIP_MFC_ERROR_CODE	ret;

	FILE	*fp_cfg;
	char	InputPath[512];
	char	OutputPath[512];
	char	ext[8];
	char	*divider;
	int		set_conf_val;
	int		get_conf_val[6];
	FILE	*fp_crc;
	FILE	*fp_log;
	char	CRCFilePath[512];
	int		CrcVal[4];

	int		*CrcBuf;
	int		CrcFileSize, readVal, CrcCount, CrcCountMax;

	if( (fp_cfg = fopen(DECODER_CONFIG_FILE, "rt"))==NULL )
	{
		printf("Cfg open error\n");
		return 0;
	}

	CrcBuf = (int *)malloc(32*1024);

	do{
		if(*ForceExit)
			break;
		
		memset(InputPath, 0x00, sizeof(InputPath));
		memset(OutputPath, 0x00, sizeof(OutputPath));
		fgets(InputPath, sizeof(InputPath)-1, fp_cfg);
		memcpy(OutputPath, InputPath, strlen(InputPath));
		divider = strchr(OutputPath, '.');
		strncpy(ext, divider, 4);
		*divider = '\0';
		strcat(OutputPath, ".nv12");


		memset(CRCFilePath, 0x00, sizeof(CRCFilePath));
		memcpy(CRCFilePath, InputPath, strlen(InputPath));
		divider = strchr(CRCFilePath, '.');
		strncpy(ext, divider, 4);
		*divider = '\0';
		strcat(CRCFilePath, ".crc");

		divider = strchr(InputPath, '.');
		divider += 4;
		*divider = '\0';

		codec_type = GetCodecType(ext);

		printf("---------------------------------------------------------\n");
		printf("Start Dec UnitTest..................................\n");
		printf("- exeMode : %d CodecType : %d\n- inFile : %s\n- outFile : %s\n\n", exeMode, codec_type, InputPath, OutputPath);

		if((hParser = SsbSipParserInit(codec_type,InputPath ,MAX_DECODER_INPUT_BUFFER_SIZE)) == NULL)
		{
			printf("SsbSipParserInit Failed\n");
			return MFC_RET_FAIL;
		}

		if(!SsbSipDisplayInit(exeMode))
		{
			printf("SsbSipDisplayInit Failed\n");
			return MFC_RET_FAIL;
		}


		hOpen = SsbSipMfcDecOpen();
		if(hOpen == NULL)
		{
			printf("SsbSipMfcDecOpen Failed\n");
			return MFC_RET_FAIL;
		}

		virInBuf = SsbSipMfcDecGetInBuf(hOpen, &phyInBuf, MAX_DECODER_INPUT_BUFFER_SIZE);
		if(virInBuf == NULL)
		{
			printf("SsbSipMfcDecGetInBuf Failed\n");
			return MFC_RET_FAIL;
		}

#ifdef _SLICE_BASED_INTERFACE_
		printf("_SLICE_BASED_INTERFACE_ have to be disable in compile option for UnitTest.\n");
		goto END_OF_UNIT_DEC;
#endif
		set_conf_val = 5;
		SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &set_conf_val);

		set_conf_val = 1;
		SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_CRC_ENABLE, &set_conf_val);

		if(codec_type == H264_DEC){
			set_conf_val = 16;
			SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_DISPLAY_DELAY, &set_conf_val);
		}

		fp_crc = fopen(CRCFilePath, "rb");
		if(fp_crc == NULL){
			printf("file open error : %s\n", CRCFilePath);
			goto END_OF_UNIT_DEC;
		}

		fseek(fp_crc , 0l, SEEK_END);
		CrcFileSize = ftell(fp_crc);
		fseek(fp_crc , 0l, SEEK_SET);
		CrcCountMax = CrcFileSize/4;
		
		printf("- CRC File : %s\n", CRCFilePath);

		readVal = fread(CrcBuf, 1, CrcFileSize, fp_crc);
		if(readVal != CrcFileSize){
			printf("Crc File Read Fail\n");
			goto END_OF_UNIT_DEC;
		}

		printf("- UnitTest Log file : %s\n", DECODER_UNITTEST_LOG_FILE);
		fp_log = fopen(DECODER_UNITTEST_LOG_FILE, "ab");
		if(fp_crc == NULL){
			printf("file open error : %s\n", DECODER_UNITTEST_LOG_FILE);
			goto END_OF_UNIT_DEC;
		}
		fprintf(fp_log, ">> %s\n",  InputPath);


		isFirstFrame = 1;
		isLastFrame = 0;
		frame_num = 0;
		display_num = 0;
		status = MFC_GETOUTBUF_STATUS_NULL;
		CrcCount = 0;

		do
		{

			if(*ForceExit){
				printf("\nSsbSipMfcDecoderTest Exit by User\n");
				break;
			}

			if((!isLastFrame) && (status != MFC_GETOUTBUF_DISPLAY_ONLY)){
				nFrameLeng = SsbSipParserFrameGet(hParser, frame_num, virInBuf, &isLastFrame);
				if(nFrameLeng != 0)
					frame_num++;
			}

			//printf("nFrameLeng : 0x%x\n", nFrameLeng);
			if(isFirstFrame)
			{
				isFirstFrame = 0;

				if(SsbSipMfcDecInit(hOpen, codec_type, nFrameLeng) != MFC_RET_OK){
					printf("SsbSipMfcDecInit Failed\n");
					break;
				}

				if(codec_type != H263_DEC)
					continue;
			}

			if(isLastFrame){
				set_conf_val = 1;
				SsbSipMfcDecSetConfig(hOpen, MFC_DEC_SETCONF_IS_LAST_FRAME, &set_conf_val);
				isLastFrame = 0;
			}

			ret = SsbSipMfcDecExe(hOpen, nFrameLeng);
			if(ret != MFC_RET_OK){
				printf("SsbSipMfcDecExe Failed(frame_num : %d ret : %d)\n", frame_num, ret);
				break;
			}

			status = SsbSipMfcDecGetOutBuf(hOpen, &output_info);

			//display
			if((status == MFC_GETOUTBUF_DISPLAY_DECODING) || (status == MFC_GETOUTBUF_DISPLAY_ONLY))
			{

				SsbSipDisplayStart(exeMode, (int)output_info.YPhyAddr, (int)output_info.CPhyAddr, output_info.buf_width, output_info.buf_height);
				display_num++;
			}
			//else
			//	printf("#%d frame is delayed(status : %d)\n", frame_num, status);

			// compare CRC
			ret = SsbSipMfcDecGetConfig(hOpen, MFC_DEC_GETCONF_CRC_DATA, &get_conf_val);
			if(ret != MFC_RET_OK){
				printf("MFC_DEC_GETCONF_CRC_DATA Failed(frame_num : %d ret : %d)\n", frame_num, ret);
				break;
			}

			if(get_conf_val[0] == 2){
				CrcVal[0] = CrcBuf[CrcCount++];
				CrcVal[1] = CrcBuf[CrcCount++];

				if(CrcCount >= CrcCountMax)	goto END_OF_UNIT_DEC;  // the last frame will not compare

				if((CrcVal[0] != get_conf_val[1]) || (CrcVal[1] != get_conf_val[2])){
					fprintf(fp_log, "%d-th frame is mismatched\n",  display_num);
					printf("%d-th frame is mismatched\n",  display_num);
					printf("REF :: 0x%x 0x%x\n", CrcVal[0], CrcVal[1]);
					printf("CRC :: 0x%x 0x%x\n", get_conf_val[1], get_conf_val[2]);
					goto END_OF_UNIT_DEC;
				}
				
				
			}
			else if(get_conf_val[0] == 4){
				CrcVal[0] = CrcBuf[CrcCount++];
				CrcVal[1] = CrcBuf[CrcCount++];
				CrcVal[2] = CrcBuf[CrcCount++];
				CrcVal[3] = CrcBuf[CrcCount++];
												
				if(CrcCount >= CrcCountMax)	goto END_OF_UNIT_DEC; // the last frame will not compare
				
				if((CrcVal[0] != get_conf_val[1]) || (CrcVal[1] != get_conf_val[2]) || (CrcVal[2] != get_conf_val[3]) || (CrcVal[3] != get_conf_val[4])){
					fprintf(fp_log, "%d-th frame is mismatched\n",  display_num);
					printf("%d-th frame is mismatched\n",  display_num);
					printf("REF :: 0x%x 0x%x\n", CrcVal[0], CrcVal[1]);
					printf("CRC :: 0x%x 0x%x\n", get_conf_val[1], get_conf_val[2]);
					goto END_OF_UNIT_DEC;
				}


			}


		}while(status != MFC_GETOUTBUF_DISPLAY_END);
		
END_OF_UNIT_DEC :printf("Decoding Finished!\n");
			printf("%d frame parsed, %d frame displayed\n\n", frame_num, display_num);
			printf("img_width : %d img_height : %d\n", output_info.img_width, output_info.img_height);

		SsbSipParserDeInit(hParser);
		SsbSipDisplayDeInit(exeMode);
		SsbSipMfcDecClose(hOpen);


		fprintf(fp_log, "   done(%d frame compared)\n\n", display_num);
		fclose(fp_log);
		fclose(fp_crc);
	}while(!feof(fp_cfg));

	fclose(fp_cfg);
	free(CrcBuf);
	printf("\nDec Unit Test Ends.....\n");
	printf("---------------------------------------------------------\n");
	return MFC_RET_OK;
}

int SsbSipMfcEncoderUnitTest(MFCExeMode exeMode, int *ForceExit)
{

	void *hOpen;
	void *phyInbuf, *virInbuf;
	void *phyOutbuf, *virtOutbuf;
	void *param;
	int width, height;
	int readSize, frame;
	char InputPath[512];
	char OutputPath[512];
	char RefPath[512];
	char* CbCrBuf;
	char *p_nv12, *p_cb, *p_cr;
	int NumOfFrames;

	SSBSIP_MFC_CODEC_TYPE codec_type;
	SSBSIP_MFC_ENC_INPUT_INFO input_info;
	SSBSIP_MFC_ENC_OUTPUT_INFO output_info;
	SSBSIP_MFC_ERROR_CODE	ret = MFC_RET_OK;
	HANDLE	hCfgFile = NULL;
	FILE	*fp_yuv, *fp_strm;
	int r;
	FILE *fp_ref, *fp_log;
	char *RefBuf, *RefPtr, *OutPtr;
	int	i, len;


	param = malloc(sizeof(SSBSIP_MFC_ENC_H264_PARAM));
	RefBuf = (char *)malloc(4096*1024);
	CbCrBuf = (char *)malloc(2*1024*1024);


//start loop
	while(1)
	{


		if(*ForceExit)
			break;

		memset(param, 0 , sizeof(SSBSIP_MFC_ENC_H264_PARAM));
		r = MFCParseEncoderCFG(&hCfgFile, param, &NumOfFrames, InputPath, OutputPath, RefPath,
			&codec_type, &width, &height);
		if(r==0)
			break;

		printf("\n--------------------------------------------------------\n");
		printf("Start Encoding.........(%d)\n", codec_type);
		printf("- inFile : %s\n", InputPath);
		printf("- outFile : %s\n", OutputPath);
		printf("- refFile : %s\n", RefPath);

		fp_yuv = fopen(InputPath, "rb");
		if (fp_yuv == NULL) {
			printf("Cannot open input YUV file.(%s)\n", InputPath);
			ret = MFC_RET_FAIL;
			break;
		}
		fp_strm = fopen(OutputPath, "wb");
		if (fp_strm == NULL) {
			printf("Cannot open output stream file.(%s)\n", OutputPath);
			ret = MFC_RET_FAIL;
			break;
		}

		fp_ref = fopen(RefPath, "rb");
		if (fp_ref == NULL) {
			printf("Cannot open reference file.(%s)\n", RefPath);
			ret = MFC_RET_FAIL;
			break;
		}

		printf("- UnitTest Log file : %s\n", ENCODER_UNITTEST_LOG_FILE);
		fp_log = fopen(ENCODER_UNITTEST_LOG_FILE, "ab");
		if(fp_log == NULL){
			printf("file open error : %s\n", ENCODER_UNITTEST_LOG_FILE);
			ret = MFC_RET_FAIL;
			break;
		}
		fprintf(fp_log, ">> %s\n",  OutputPath);

		hOpen = SsbSipMfcEncOpen();
		if(hOpen == NULL)
		{
			printf("SsbSipMfcEncOpen Failed\n");
			ret = MFC_RET_FAIL;
			break;;
		}

		if(SsbSipMfcEncInit(hOpen, param) != MFC_RET_OK)
		{
			printf("SsbSipMfcEncInit Failed\n");
			ret = MFC_RET_FAIL;
			break;
		}

		if(codec_type != H263_ENC)  // no header for H.263
		{
			SsbSipMfcEncGetOutBuf(hOpen, &output_info);
			if(output_info.headerSize <= 0)
			{
				printf("Header Encoding Failed\n");
				ret = MFC_RET_FAIL;
				break;
			}
			fwrite(output_info.StrmVirAddr, 1, output_info.headerSize, fp_strm);
		}

		if(SsbSipMfcEncGetInBuf(hOpen, &input_info) != MFC_RET_OK)
		{
			printf("SsbSipMfcEncGetInBuf Failed\n");
			ret = MFC_RET_FAIL;
			break;
		}
		
		if((input_info.YVirAddr == NULL) || (input_info.CVirAddr == NULL))
		{
			printf("Buffer is null after SsbSipMfcEncGetInBuf\n");
			printf("SsbSipMfcEncGetInBuf() have to be called after SsbSipMfcEncInit() \n");
			ret = MFC_RET_FAIL;
			break;
		}

		frame = 0;
		do
		{
			if(*ForceExit){
				printf("\nSsbSipMfcEncoderTest Exit by User\n");
				break;
			}

			readSize = fread(input_info.YVirAddr, 1, width * height, fp_yuv);
			if(readSize == 0){
				printf("Y readSize == 0\n");
				break;	
			}

			readSize = fread(CbCrBuf, 1, (width * height) >> 1, fp_yuv);
			if(readSize == 0){
				printf("CbCr readSize == 0\n");
				break;	
			}

			// convert YV12 -> NV12
			p_nv12 = (char *)input_info.CVirAddr;
			p_cb = CbCrBuf;
			p_cr = CbCrBuf;
			p_cr += ((width * height) >> 2);

			for(i = 0; i < (width * height) >> 2; i++){
				*p_nv12 = *p_cb;
				p_nv12++;
				*p_nv12 = *p_cr;
				p_nv12++;
				p_cb++;
				p_cr++;
			}

			ret = SsbSipMfcEncSetInBuf(hOpen, &input_info);
			if(ret != MFC_RET_OK){
				printf("SsbSipMfcEncSetInBuf Failed(frame_num : %d ret : %d)\n", frame, ret);
				break;
			} 

			ret = SsbSipMfcEncExe(hOpen);
			if(ret != MFC_RET_OK){
				printf("Encoding Failed(frame_num : %d ret : %d)\n", frame, ret);
				break;
			} 
	
			SsbSipMfcEncGetOutBuf(hOpen, &output_info);
			if(output_info.StrmVirAddr == NULL)
			{
				printf("SsbSipMfcEncGetOutBuf Failed\n");
				ret = MFC_RET_FAIL;
				break;
			}

			fwrite(output_info.StrmVirAddr, 1, output_info.dataSize, fp_strm);

			len = fread(RefBuf, 1, output_info.dataSize, fp_ref);
			if(len < output_info.dataSize){
				printf("End of ref file\n");
				break;
			}
			RefPtr = RefBuf;
			OutPtr = (char *)output_info.StrmVirAddr;

#if 0 // after EVT1
			for(i = 0; i < output_info.dataSize; i++){
				if(*RefPtr != *OutPtr){
					fprintf(fp_log, "   %d-th frame is mismatched(%d)\n",  frame, i);
					printf("   %d-th frame is mismatched(%dth byte-0x%x-0x%x)\n",  frame, i, *RefPtr, *OutPtr);
					break;
				}
				RefPtr++;
				OutPtr++;
			}
#endif

			frame++;
		}while(frame < NumOfFrames);

		SsbSipMfcEncClose(hOpen);
		fclose(fp_yuv);
		fclose(fp_strm);
		fprintf(fp_log, "   done(%d frame compared)\n", frame);
		fclose(fp_ref);
		fclose(fp_log);
	}

	printf("%d frame encoded\n", frame);
	printf("--------------------------------------------------------\n");
	free(param);
	free(RefBuf);
	free(CbCrBuf);

	return ret;

	return 1;
}

int SsbSipMfcDecDecTest(MFCExeMode exeMode, int *ForceExit)
{
	void *hOpen_1, *hParser_1;
	void *hOpen_2, *hParser_2;
	void *virInBuf_1, *phyInBuf_1;
	void *virInBuf_2, *phyInBuf_2;
	int nFrameLeng_1, nFrameLeng_2;
	int isFirstFrame_1;
	int isFirstFrame_2;
	unsigned int frame_num_1 = 0;
	unsigned int frame_num_2 = 0;
	unsigned int display_num_1 = 0;
	unsigned int display_num_2 = 0;
	int isLastFrame_1;
	int isLastFrame_2;

	SSBSIP_MFC_CODEC_TYPE codec_type_1;
	SSBSIP_MFC_CODEC_TYPE codec_type_2;
	SSBSIP_MFC_DEC_OUTPUT_INFO output_info_1;
	SSBSIP_MFC_DEC_OUTPUT_INFO output_info_2;
	SSBSIP_MFC_ERROR_CODE	ret_1;
	SSBSIP_MFC_ERROR_CODE	ret_2;
	SSBSIP_MFC_DEC_OUTBUF_STATUS status_1;
	SSBSIP_MFC_DEC_OUTBUF_STATUS status_2;

	FILE	*fp_cfg;
	char	InputPath_1[512];
	char	InputPath_2[512];
	char	OutputPath_1[512];
	char	OutputPath_2[512];
	char	ext_1[8];
	char	ext_2[8];
	char	*divider_1;
	char	*divider_2;
	int		set_conf_val_1;
	int		set_conf_val_2;
	
	if( (fp_cfg = fopen(DECODER_CONFIG_FILE, "rt"))==NULL )
	{
		printf("Cfg open error\n");
		return 0;
	}


	if(*ForceExit)
		return MFC_RET_FAIL;
	
	printf("SsbSipMfcDecDecTest\n");
	memset(InputPath_1, 0x00, sizeof(InputPath_1));
	memset(OutputPath_1, 0x00, sizeof(OutputPath_1));
	fgets(InputPath_1, sizeof(InputPath_1)-1, fp_cfg);
	memcpy(OutputPath_1, InputPath_1, strlen(InputPath_1));
	divider_1 = strchr(OutputPath_1, '.');
	strncpy(ext_1, divider_1, 4);
	*divider_1 = '\0';
	strcat(OutputPath_1, ".nv12");
	divider_1 = strchr(InputPath_1, '.');
	divider_1 += 4;
	*divider_1 = '\0';

	codec_type_1 = GetCodecType(ext_1);

	memset(InputPath_2, 0x00, sizeof(InputPath_2));
	memset(OutputPath_2, 0x00, sizeof(OutputPath_2));
	fgets(InputPath_2, sizeof(InputPath_2)-1, fp_cfg);
	memcpy(OutputPath_2, InputPath_2, strlen(InputPath_2));
	divider_2 = strchr(OutputPath_2, '.');
	strncpy(ext_2, divider_2, 4);
	*divider_2 = '\0';
	strcat(OutputPath_2, ".nv12");
	divider_2 = strchr(InputPath_2, '.');
	divider_2 += 4;
	*divider_2 = '\0';

	codec_type_2 = GetCodecType(ext_2);
	
	printf("---------------------------------------------------------\n");
	printf("Start Decoding..................................\n");
	printf("1. CodecType : %d\n- inFile : %s\n- outFile : %s\n\n", codec_type_1, InputPath_1, OutputPath_1);
	printf("2. CodecType : %d\n- inFile : %s\n- outFile : %s\n\n", codec_type_2, InputPath_2, OutputPath_2);

	if((hParser_1 = SsbSipParserInit(codec_type_1,InputPath_1 ,MAX_DECODER_INPUT_BUFFER_SIZE)) == NULL)
	{
		printf("SsbSipParserInit_1 Failed\n");
		return MFC_RET_FAIL;
	}

	if((hParser_2 = SsbSipParserInit(codec_type_2,InputPath_2 ,MAX_DECODER_INPUT_BUFFER_SIZE)) == NULL)
	{
		printf("SsbSipParserInit_2 Failed\n");
		return MFC_RET_FAIL;
	}


	if(!SsbSipDisplayInit(DEC_DEC_DISPLAY_1))
	{
		printf("SsbSipDisplayInit_1 Failed\n");
		return MFC_RET_FAIL;
	}

	if(!SsbSipDisplayInit(DEC_DEC_DISPLAY_2))
	{
		printf("SsbSipDisplayInit_2 Failed\n");
		return MFC_RET_FAIL;
	}


	hOpen_1 = SsbSipMfcDecOpen();
	if(hOpen_1 == NULL)
	{
		printf("SsbSipMfcDecOpen_1 Failed\n");
		return MFC_RET_FAIL;
	}

	virInBuf_1 = SsbSipMfcDecGetInBuf(hOpen_1, &phyInBuf_1, MAX_DECODER_INPUT_BUFFER_SIZE);
	if(virInBuf_1 == NULL)
	{
		printf("SsbSipMfcDecGetInBuf_1 Failed\n");
		return MFC_RET_FAIL;
	}

	set_conf_val_1 = 3;
	SsbSipMfcDecSetConfig(hOpen_1, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &set_conf_val_1);

	if(codec_type_1 == H264_DEC){
		set_conf_val_1 = 16;
		SsbSipMfcDecSetConfig(hOpen_1, MFC_DEC_SETCONF_DISPLAY_DELAY, &set_conf_val_1);
	}

	hOpen_2 = SsbSipMfcDecOpen();
	if(hOpen_2 == NULL)
	{
		printf("SsbSipMfcDecOpen_2 Failed\n");
		return MFC_RET_FAIL;
	}

	virInBuf_2 = SsbSipMfcDecGetInBuf(hOpen_2, &phyInBuf_2, MAX_DECODER_INPUT_BUFFER_SIZE);
	if(virInBuf_2 == NULL)
	{
		printf("SsbSipMfcDecGetInBuf_2 Failed\n");
		return MFC_RET_FAIL;
	}

	set_conf_val_2 = 3;
	SsbSipMfcDecSetConfig(hOpen_2, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &set_conf_val_2);

	if(codec_type_2 == H264_DEC){
		set_conf_val_2 = 16;
		SsbSipMfcDecSetConfig(hOpen_2, MFC_DEC_SETCONF_DISPLAY_DELAY, &set_conf_val_2);
	}

#ifdef FILE_DUMP	
	fp_1 = fopen(OutputPath_1, "wb");
	if(fp_1 == NULL){
		printf("file open error : %s\n", OutputPath_1);
		return -1;
	}

	fp_2 = fopen(OutputPath_2, "wb");
	if(fp_2 == NULL){
		printf("file open error : %s\n", OutputPath_2);
		return -1;
	}
#endif

	isFirstFrame_1 = 1;
	isLastFrame_1 = 0;
	frame_num_1 = 0;
	display_num_1 = 0;
	status_1 = MFC_GETOUTBUF_STATUS_NULL;

	isFirstFrame_2 = 1;
	isLastFrame_2 = 0;
	frame_num_2 = 0;
	display_num_2 = 0;
	status_2 = MFC_GETOUTBUF_STATUS_NULL;

	do
	{

		if(*ForceExit){
			printf("\nSsbSipMfcDecoderTest Exit by User\n");
			break;
		}
		////////////////////////////////////////////////////
		//			DEC_1								  //
		////////////////////////////////////////////////////
		if(status_1 != MFC_GETOUTBUF_DISPLAY_END)
		{
			if((!isLastFrame_1) && (status_1 != MFC_GETOUTBUF_DISPLAY_ONLY)){
				nFrameLeng_1 = SsbSipParserFrameGet(hParser_1, frame_num_1, virInBuf_1, &isLastFrame_1);
				if(nFrameLeng_1 != 0)
					frame_num_1++;
			}

			if(isFirstFrame_1)
			{
				isFirstFrame_1 = 0;

				if(SsbSipMfcDecInit(hOpen_1, codec_type_1, nFrameLeng_1) != MFC_RET_OK){
					printf("SsbSipMfcDecInit Failed\n");
					break;
				}

				if(codec_type_1 != H263_DEC)
					continue;
			}

			if(isLastFrame_1){
				set_conf_val_1 = 1;
				SsbSipMfcDecSetConfig(hOpen_1, MFC_DEC_SETCONF_IS_LAST_FRAME, &set_conf_val_1);
			}

			ret_1 = SsbSipMfcDecExe(hOpen_1, nFrameLeng_1);
			if(ret_1 != MFC_RET_OK){
				printf("SsbSipMfcDecExe_1 Failed(frame_num : %d ret : %d)\n", frame_num_1, ret_1);
				break;
			}

			status_1 = SsbSipMfcDecGetOutBuf(hOpen_1, &output_info_1);

			if((status_1 == MFC_GETOUTBUF_DISPLAY_DECODING) || (status_1 == MFC_GETOUTBUF_DISPLAY_ONLY))
			{
				//display
				SsbSipDisplayStart(DEC_DEC_DISPLAY_1, (int)output_info_1.YPhyAddr, (int)output_info_1.CPhyAddr, output_info_1.buf_width, output_info_1.buf_height);


	#ifdef FILE_DUMP
				fwrite(output_info_1.YVirAddr, 1, output_info_1.width*output_info_1.height, fp_1);
				fwrite(output_info_1.CVirAddr, 1, output_info_1.width*output_info_1.height>>1, fp_1);
	#endif
				display_num_1++;
			}
		}
		////////////////////////////////////////////////////
		//			DEC_2								  //
		////////////////////////////////////////////////////
		if(status_2 != MFC_GETOUTBUF_DISPLAY_END)
		{
			if((!isLastFrame_2) && (status_2 != MFC_GETOUTBUF_DISPLAY_ONLY)){
				nFrameLeng_2 = SsbSipParserFrameGet(hParser_2, frame_num_2, virInBuf_2, &isLastFrame_2);
				if(nFrameLeng_2 != 0)
					frame_num_2++;
			}

			if(isFirstFrame_2)
			{
				isFirstFrame_2 = 0;

				if(SsbSipMfcDecInit(hOpen_2, codec_type_2, nFrameLeng_2) != MFC_RET_OK){
					printf("SsbSipMfcDecInit Failed\n");
					break;
				}

				if(codec_type_2 != H263_DEC)
					continue;
			}

			if(isLastFrame_2){
				set_conf_val_2 = 1;
				SsbSipMfcDecSetConfig(hOpen_2, MFC_DEC_SETCONF_IS_LAST_FRAME, &set_conf_val_2);
			}

			ret_2 = SsbSipMfcDecExe(hOpen_2, nFrameLeng_2);
			if(ret_2 != MFC_RET_OK){
				printf("SsbSipMfcDecExe_2 Failed(frame_num : %d ret : %d)\n", frame_num_2, ret_2);
				break;
			}

			status_2 = SsbSipMfcDecGetOutBuf(hOpen_2, &output_info_2);

			if((status_2 == MFC_GETOUTBUF_DISPLAY_DECODING) || (status_2 == MFC_GETOUTBUF_DISPLAY_ONLY))
			{
				//display
				SsbSipDisplayStart(DEC_DEC_DISPLAY_2, (int)output_info_2.YPhyAddr, (int)output_info_2.CPhyAddr, output_info_2.buf_width, output_info_2.buf_height);


	#ifdef FILE_DUMP
				fwrite(output_info_2.YVirAddr, 1, output_info_2.width*output_info_2.height, fp_2);
				fwrite(output_info_2.CVirAddr, 1, output_info_2.width*output_info_2.height>>1, fp_2);
	#endif
				display_num_2++;
			}
		}
		//printf("1. %d frame parsed, %d frame displayed\n\n", frame_num_1, display_num_1);
		//printf("2. %d frame parsed, %d frame displayed\n\n", frame_num_2, display_num_2);
	}while((status_1 != MFC_GETOUTBUF_DISPLAY_END) || (status_2 != MFC_GETOUTBUF_DISPLAY_END));
	
	printf("Decoding Finished!\n");
	printf("1. %d frame parsed, %d frame displayed\n\n", frame_num_1, display_num_1);
	printf("2. %d frame parsed, %d frame displayed\n\n", frame_num_2, display_num_2);

	SsbSipParserDeInit(hParser_1);
	SsbSipParserDeInit(hParser_2);


	SsbSipDisplayDeInit(DEC_DEC_DISPLAY_1);
	SsbSipDisplayDeInit(DEC_DEC_DISPLAY_2);


	SsbSipMfcDecClose(hOpen_1);
	SsbSipMfcDecClose(hOpen_2);
#ifdef FILE_DUMP
	fclose(fp_1);
	fclose(fp_2);
#endif
	fclose(fp_cfg);

	printf("---------------------------------------------------------\n");
	return MFC_RET_OK;
}

int SsbSipMfcDecEncTest(MFCExeMode exeMode, int *ForceExit)
{

	void *hOpen_1, *hParser;
	void *virInBuf_1, *phyInBuf_1;
	int nFrameLeng;
	int isFirstFrame;
	unsigned int frame_num = 0;
	unsigned int display_num = 0;
	int isLastFrame;

	SSBSIP_MFC_DEC_OUTBUF_STATUS status = MFC_GETOUTBUF_STATUS_NULL;
	SSBSIP_MFC_CODEC_TYPE codec_type_1;
	SSBSIP_MFC_DEC_OUTPUT_INFO output_info_1;
	SSBSIP_MFC_ERROR_CODE	ret_1;

	FILE	*fp_cfg;
	char	InputPath_1[512];
	char	OutputPath_1[512];
	char	ext[8];
	char	*divider;
	int		set_conf_val;

	void *hOpen_2;
	void *phyInbuf_2, *virInbuf_2;
	void *phyOutbuf, *virtOutbuf;
	void *param;
	int width_2, height_2;
	int readSize, frame;
	char InputPath_2[512];
	char OutputPath_2[512];
	char RefPath_2[512];
	int NumOfFrames;

	SSBSIP_MFC_CODEC_TYPE codec_type_2;
	SSBSIP_MFC_ENC_INPUT_INFO input_info_2;
	SSBSIP_MFC_ENC_OUTPUT_INFO output_info_2;
	SSBSIP_MFC_ERROR_CODE	ret_2;
	HANDLE	hCfgFile = NULL;
	FILE			   *fp_yuv, *fp_strm;
	int r;
	
		
	printf("SsbSipMfcDecEncTest\n");
	if(*ForceExit)
		return MFC_RET_OK;

	if( (fp_cfg = fopen(DECODER_CONFIG_FILE, "rt"))==NULL )
	{
		printf("Cfg open error\n");
		return MFC_RET_FAIL;
	}

	memset(InputPath_1, 0x00, sizeof(InputPath_1));
	memset(OutputPath_1, 0x00, sizeof(OutputPath_1));
	fgets(InputPath_1, sizeof(InputPath_1)-1, fp_cfg);
	memcpy(OutputPath_1, InputPath_1, strlen(InputPath_1));
	divider = strchr(OutputPath_1, '.');
	strncpy(ext, divider, 4);
	*divider = '\0';
	strcat(OutputPath_1, ".nv12");
	divider = strchr(InputPath_1, '.');
	divider += 4;
	*divider = '\0';

	codec_type_1 = GetCodecType(ext);

	printf("---------------------------------------------------------\n");
	printf("Start Decoding..................................\n");
	printf("- exeMode : %d CodecType : %d\n- inFile : %s\n- outFile : %s\n\n", exeMode, codec_type_1, InputPath_1, OutputPath_1);

	if((hParser = SsbSipParserInit(codec_type_1,InputPath_1 ,MAX_DECODER_INPUT_BUFFER_SIZE)) == NULL)
	{
		printf("SsbSipParserInit Failed\n");
		return MFC_RET_FAIL;
	}

	if(!SsbSipDisplayInit(exeMode))
	{
		printf("SsbSipDisplayInit Failed\n");
		return MFC_RET_FAIL;
	}


	hOpen_1 = SsbSipMfcDecOpen();
	if(hOpen_1 == NULL)
	{
		printf("SsbSipMfcDecOpen Failed\n");
		return MFC_RET_FAIL;
	}

	virInBuf_1 = SsbSipMfcDecGetInBuf(hOpen_1, &phyInBuf_1, MAX_DECODER_INPUT_BUFFER_SIZE);
	if(virInBuf_1 == NULL)
	{
		printf("SsbSipMfcDecGetInBuf Failed\n");
		return MFC_RET_FAIL;
	}

	set_conf_val = 3;
	SsbSipMfcDecSetConfig(hOpen_1, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &set_conf_val);

	if(codec_type_1 == H264_DEC){
		set_conf_val = 16;
		SsbSipMfcDecSetConfig(hOpen_1, MFC_DEC_SETCONF_DISPLAY_DELAY, &set_conf_val);
	}

#ifdef FILE_DUMP	
	fp = fopen(OutputPath, "wb");
	if(fp == NULL){
		printf("file open error : %s\n", OutputPath);
		return -1;
	}
#endif

	param = malloc(sizeof(SSBSIP_MFC_ENC_H264_PARAM));
	memset(param, 0 , sizeof(SSBSIP_MFC_ENC_H264_PARAM));
	r = MFCParseEncoderCFG(&hCfgFile, param, &NumOfFrames, InputPath_2, OutputPath_2, RefPath_2,
		&codec_type_2, &width_2, &height_2);
	if(r==0)
		return MFC_RET_FAIL;

	printf("\n--------------------------------------------------------\n");
	printf("Start Encoding.........(%d)\n", codec_type_2);
	printf("- inFile : %s\n", InputPath_2);
	printf("- outFile : %s\n", OutputPath_2);

	fp_yuv = fopen(InputPath_2, "rb");
	if (fp_yuv == NULL) {
		printf("Cannot open input YUV file.(%s)\n", InputPath_2);
		return MFC_RET_FAIL;
	}
	fp_strm = fopen(OutputPath_2, "wb");
	if (fp_strm == NULL) {
		printf("Cannot open output stream file.\n");
		return MFC_RET_FAIL;
	}

	hOpen_2 = SsbSipMfcEncOpen();
	if(hOpen_2 == NULL)
	{
		printf("SsbSipMfcEncOpen Failed\n");
		return MFC_RET_FAIL;
	}


	if(SsbSipMfcEncInit(hOpen_2, param) != MFC_RET_OK)
	{
		printf("SsbSipMfcEncInit Failed\n");
		return MFC_RET_FAIL;
	}

	if(codec_type_2 != H263_ENC)  // no header for H.263
	{
		SsbSipMfcEncGetOutBuf(hOpen_2, &output_info_2);
		if(output_info_2.headerSize <= 0)
		{
			printf("Header Encoding Failed\n");
			return MFC_RET_FAIL;
		}
		fwrite(output_info_2.StrmVirAddr, 1, output_info_2.headerSize, fp_strm);
	}

	if(SsbSipMfcEncGetInBuf(hOpen_2, &input_info_2) != MFC_RET_OK)
	{
		printf("SsbSipMfcEncGetInBuf Failed\n");
		return MFC_RET_FAIL;
	}

	if((input_info_2.YVirAddr == NULL) || (input_info_2.CVirAddr == NULL))
	{
		printf("Buffer is null after SsbSipMfcEncGetInBuf\n");
		printf("SsbSipMfcEncGetInBuf() have to be called after SsbSipMfcEncInit() \n");
		return MFC_RET_FAIL;
	}

	isFirstFrame = 1;
	isLastFrame = 0;
	frame_num = 0;
	display_num = 0;
	frame = 0;
	do
	{

		if(*ForceExit){
			printf("\nSsbSipMfcDecoderTest Exit by User\n");
			break;
		}
		///////////////////////////////////////////
		//  DEC                                  //
		///////////////////////////////////////////
		if(status != MFC_GETOUTBUF_DISPLAY_END)
		{
			if((!isLastFrame) && (status != MFC_GETOUTBUF_DISPLAY_ONLY)){
				nFrameLeng = SsbSipParserFrameGet(hParser, frame_num, virInBuf_1, &isLastFrame);
				if(nFrameLeng != 0)
					frame_num++;
			}

			if(isFirstFrame)
			{
				isFirstFrame = 0;

				if(SsbSipMfcDecInit(hOpen_1, codec_type_1, nFrameLeng) != MFC_RET_OK){
					printf("SsbSipMfcDecInit Failed\n");
					break;
				}

				if(codec_type_1 != H263_DEC)
					continue;
			}

			if(isLastFrame){
				set_conf_val = 1;
				SsbSipMfcDecSetConfig(hOpen_1, MFC_DEC_SETCONF_IS_LAST_FRAME, &set_conf_val);
				isLastFrame = 0;
			}

			ret_1 = SsbSipMfcDecExe(hOpen_1, nFrameLeng);
			if(ret_1 != MFC_RET_OK){
				printf("SsbSipMfcDecExe Failed(frame_num : %d ret : %d)\n", frame_num, ret_1);
				break;
			}

			status = SsbSipMfcDecGetOutBuf(hOpen_1, &output_info_1);

			if((status == MFC_GETOUTBUF_DISPLAY_DECODING) || (status == MFC_GETOUTBUF_DISPLAY_ONLY))
			{
				//display
				SsbSipDisplayStart(exeMode, (int)output_info_1.YPhyAddr, (int)output_info_1.CPhyAddr, output_info_1.buf_width, output_info_1.buf_height);
	#ifdef FILE_DUMP
				fwrite(output_info_1.YVirAddr, 1, output_info_1.width*output_info.height, fp);
				fwrite(output_info_1.CVirAddr, 1, output_info_1.width*output_info.height>>1, fp);
	#endif
				display_num++;
			}
			Sleep(10);
		}

		///////////////////////////////////////////
		//  ENC                                  //
		///////////////////////////////////////////
		if(frame < NumOfFrames)
		{
			readSize = fread(input_info_2.YVirAddr, 1, width_2 * height_2, fp_yuv);
			if(readSize == 0){
				printf("Y readSize == 0\n");
				break;
			}

			readSize = fread(input_info_2.CVirAddr, 1, (width_2 * height_2)>>1, fp_yuv);
			if(readSize == 0){
				printf("CbCr readSize == 0\n");
				break;
			}

			ret_2 = SsbSipMfcEncSetInBuf(hOpen_2, &input_info_2);
			if(ret_2 != MFC_RET_OK){
				printf("SsbSipMfcEncSetInBuf Failed(frame_num : %d ret : %d)\n", frame, ret_2);
				break;
			} 

			ret_2 = SsbSipMfcEncExe(hOpen_2);
			if(ret_2 != MFC_RET_OK){
				printf("Encoding Failed(frame_num : %d ret : %d)\n", frame, ret_2);
				break;
			} 

			SsbSipMfcEncGetOutBuf(hOpen_2, &output_info_2);
			if(output_info_2.StrmVirAddr == NULL)
			{
				printf("SsbSipMfcEncGetOutBuf Failed\n");
				return MFC_RET_FAIL;
			}

			fwrite(output_info_2.StrmVirAddr, 1, output_info_2.dataSize, fp_strm);

			frame++;
			printf("%d encoded\n", frame);
		}
	}while((status != MFC_GETOUTBUF_DISPLAY_END) || (frame < NumOfFrames));
	
	printf("Decoding Finished!\n");
	printf("%d frame parsed, %d frame displayed\n\n", frame_num, display_num);

	SsbSipParserDeInit(hParser);
	SsbSipDisplayDeInit(exeMode);
	SsbSipMfcDecClose(hOpen_1);
#ifdef FILE_DUMP
	fclose(fp);
#endif
	SsbSipMfcEncClose(hOpen_2);
	fclose(fp_yuv);
	fclose(fp_strm);
	fclose(fp_cfg);
	free(param);

	printf("---------------------------------------------------------\n");
	return MFC_RET_OK;
}


int SsbSipMfcEncEncTest(MFCExeMode exeMode, int *ForceExit)
{

	void *hOpen_1;
	void *phyInbuf_1, *virInbuf_1;
	void *phyOutbuf_1, *virtOutbuf_1;
	void *param_1;
	int width_1, height_1;
	int readSize_1, frame_1;
	char InputPath_1[512];
	char OutputPath_1[512];
	char RefPath_1[512];
	int NumOfFrames_1;

	SSBSIP_MFC_CODEC_TYPE codec_type_1;
	SSBSIP_MFC_ENC_INPUT_INFO input_info_1;
	SSBSIP_MFC_ENC_OUTPUT_INFO output_info_1;
	SSBSIP_MFC_ERROR_CODE	ret_1;
	HANDLE	hCfgFile = NULL;
	FILE	*fp_yuv_1, *fp_strm_1;
	int r;

	void *hOpen_2;
	void *phyInbuf_2, *virInbuf_2;
	void *phyOutbuf_2, *virtOutbuf_2;
	void *param_2;
	int width_2, height_2;
	int readSize_2, frame_2;
	char InputPath_2[512];
	char OutputPath_2[512];
	char RefPath_2[512];
	int NumOfFrames_2;

	SSBSIP_MFC_CODEC_TYPE codec_type_2;
	SSBSIP_MFC_ENC_INPUT_INFO input_info_2;
	SSBSIP_MFC_ENC_OUTPUT_INFO output_info_2;
	SSBSIP_MFC_ERROR_CODE	ret_2;
	FILE	*fp_yuv_2, *fp_strm_2;


	if(*ForceExit)
		return MFC_RET_FAIL;

	param_1 = malloc(sizeof(SSBSIP_MFC_ENC_H264_PARAM));
	param_2 = malloc(sizeof(SSBSIP_MFC_ENC_H264_PARAM));

	memset(param_1, 0 , sizeof(SSBSIP_MFC_ENC_H264_PARAM));
	memset(param_2, 0 , sizeof(SSBSIP_MFC_ENC_H264_PARAM));

	r = MFCParseEncoderCFG(&hCfgFile, param_1, &NumOfFrames_1, InputPath_1, OutputPath_1, RefPath_1,
		&codec_type_1, &width_1, &height_1);
	if(r==0)
		return MFC_RET_FAIL;

	r = MFCParseEncoderCFG(&hCfgFile, param_2, &NumOfFrames_2, InputPath_2, OutputPath_2, RefPath_2,
		&codec_type_2, &width_2, &height_2);
	if(r==0)
		return MFC_RET_FAIL;

	printf("\n--------------------------------------------------------\n");
	printf("1. Start Encoding.........(%d)\n", codec_type_1);
	printf("- inFile : %s\n", InputPath_1);
	printf("- outFile : %s\n\n", OutputPath_1);
	printf("2. Start Encoding.........(%d)\n", codec_type_2);
	printf("- inFile : %s\n", InputPath_2);
	printf("- outFile : %s\n", OutputPath_2);

	///////////////////////////////////////////
	//  1. ENC-Init                          //
	///////////////////////////////////////////
	fp_yuv_1 = fopen(InputPath_1, "rb");
	if (fp_yuv_1 == NULL) {
		printf("Cannot open input YUV file.(%s)\n", InputPath_1);
		return MFC_RET_FAIL;
	}
	fp_strm_1 = fopen(OutputPath_1, "wb");
	if (fp_strm_1 == NULL) {
		printf("Cannot open output stream file.\n");
		return MFC_RET_FAIL;
	}

	hOpen_1 = SsbSipMfcEncOpen();
	if(hOpen_1 == NULL)
	{
		printf("SsbSipMfcEncOpen Failed\n");
		return MFC_RET_FAIL;
	}

	if(SsbSipMfcEncInit(hOpen_1, param_1) != MFC_RET_OK)
	{
		printf("SsbSipMfcEncInit Failed\n");
		return MFC_RET_FAIL;
	}

	if(codec_type_1 != H263_ENC)  // no header for H.263
	{
		SsbSipMfcEncGetOutBuf(hOpen_1, &output_info_1);
		if(output_info_1.headerSize <= 0)
		{
			printf("Header Encoding Failed\n");
			return MFC_RET_FAIL;
		}
		fwrite(output_info_1.StrmVirAddr, 1, output_info_1.headerSize, fp_strm_1);
	}

	if(SsbSipMfcEncGetInBuf(hOpen_1, &input_info_1) != MFC_RET_OK)
	{
		printf("SsbSipMfcEncGetInBuf Failed\n");
		return MFC_RET_FAIL;
	}

	if((input_info_1.YVirAddr == NULL) || (input_info_1.CVirAddr == NULL))
	{
		printf("Buffer is null after SsbSipMfcEncGetInBuf\n");
		printf("SsbSipMfcEncGetInBuf() have to be called after SsbSipMfcEncInit() \n");
		return MFC_RET_FAIL;
	}

	///////////////////////////////////////////
	//  2. ENC-Init                          //
	///////////////////////////////////////////
	fp_yuv_2 = fopen(InputPath_2, "rb");
	if (fp_yuv_2 == NULL) {
		printf("Cannot open input YUV file.(%s)\n", InputPath_2);
		return MFC_RET_FAIL;
	}
	fp_strm_2 = fopen(OutputPath_2, "wb");
	if (fp_strm_2 == NULL) {
		printf("Cannot open output stream file.\n");
		return MFC_RET_FAIL;
	}

	hOpen_2 = SsbSipMfcEncOpen();
	if(hOpen_2 == NULL)
	{
		printf("SsbSipMfcEncOpen Failed\n");
		return MFC_RET_FAIL;
	}
	if(SsbSipMfcEncInit(hOpen_2, param_2) != MFC_RET_OK)
	{
		printf("SsbSipMfcEncInit Failed\n");
		return MFC_RET_FAIL;
	}

	if(codec_type_2 != H263_ENC)  // no header for H.263
	{
		SsbSipMfcEncGetOutBuf(hOpen_2, &output_info_2);
		if(output_info_2.headerSize <= 0)
		{
			printf("Header Encoding Failed\n");
			return MFC_RET_FAIL;
		}
		fwrite(output_info_2.StrmVirAddr, 1, output_info_2.headerSize, fp_strm_2);
	}

	if(SsbSipMfcEncGetInBuf(hOpen_2, &input_info_2) != MFC_RET_OK)
	{
		printf("SsbSipMfcEncGetInBuf Failed\n");
		return MFC_RET_FAIL;
	}

	if((input_info_2.YVirAddr == NULL) || (input_info_2.CVirAddr == NULL))
	{
		printf("Buffer is null after SsbSipMfcEncGetInBuf\n");
		printf("SsbSipMfcEncGetInBuf() have to be called after SsbSipMfcEncInit() \n");
		return MFC_RET_FAIL;
	}


	frame_1 = 0;
	frame_2 = 0;
	do
	{
		if(*ForceExit){
			printf("\nSsbSipMfcEncoderTest Exit by User\n");
			break;
		}
		///////////////////////////////////////////
		//  1. ENC                               //
		///////////////////////////////////////////
		if(frame_1 < NumOfFrames_1)
		{
			readSize_1 = fread(input_info_1.YVirAddr, 1, width_1 * height_1, fp_yuv_1);
			if(readSize_1 == 0){
				printf("Y readSize == 0\n");
				break;	
			}

			readSize_1 = fread(input_info_1.CVirAddr, 1, (width_1 * height_1) >> 1, fp_yuv_1);
			if(readSize_1 == 0){
				printf("CbCr readSize == 0\n");
				break;	
			}

			ret_1 = SsbSipMfcEncSetInBuf(hOpen_1, &input_info_1);
			if(ret_1 != MFC_RET_OK){
				printf("SsbSipMfcEncSetInBuf Failed(frame_num : %d ret : %d)\n", frame_1, ret_1);
				break;
			} 

			ret_1 = SsbSipMfcEncExe(hOpen_1);
			if(ret_1 != MFC_RET_OK){
				printf("Encoding Failed(frame_num : %d ret : %d)\n", frame_1, ret_1);
				break;
			} 

			SsbSipMfcEncGetOutBuf(hOpen_1, &output_info_1);
			if(output_info_1.StrmVirAddr == NULL)
			{
				printf("SsbSipMfcEncGetOutBuf Failed\n");
				break;
			}
			fwrite(output_info_1.StrmVirAddr, 1, output_info_1.dataSize, fp_strm_1);
			frame_1++;

			Sleep(20);
		}

		///////////////////////////////////////////
		//  2. ENC                               //
		///////////////////////////////////////////

		if(frame_2 < NumOfFrames_2)
		{
			readSize_2 = fread(input_info_2.YVirAddr, 1, width_2 * height_2, fp_yuv_2);
			if(readSize_1 == 0){
				printf("Y readSize == 0\n");
				break;	
			}

			readSize_2 = fread(input_info_2.CVirAddr, 1, (width_2 * height_2) >> 1, fp_yuv_2);
			if(readSize_2 == 0){
				printf("CbCr readSize == 0\n");
				break;	
			}

			ret_2 = SsbSipMfcEncSetInBuf(hOpen_2, &input_info_2);
			if(ret_2 != MFC_RET_OK){
				printf("SsbSipMfcEncSetInBuf Failed(frame_num : %d ret : %d)\n", frame_2, ret_2);
				break;
			} 

			ret_2 = SsbSipMfcEncExe(hOpen_2);
			if(ret_2 != MFC_RET_OK){
				printf("Encoding Failed(frame_num : %d ret : %d)\n", frame_2, ret_2);
				break;
			} 

			SsbSipMfcEncGetOutBuf(hOpen_2, &output_info_2);
			if(output_info_2.StrmVirAddr == NULL)
			{
				printf("SsbSipMfcEncGetOutBuf Failed\n");
				break;
			}
			fwrite(output_info_2.StrmVirAddr, 1, output_info_2.dataSize, fp_strm_2);
			frame_2++;

			Sleep(20);
		}

		//printf("ENC1 : %d frame encoded\n", frame_1);
		//printf("ENC2 : %d frame encoded\n", frame_2);

	}while((frame_1 < NumOfFrames_1) || (frame_2 < NumOfFrames_2)) ;
	
	SsbSipMfcEncClose(hOpen_1);
	fclose(fp_yuv_1);
	fclose(fp_strm_1);


	SsbSipMfcEncClose(hOpen_2);
	fclose(fp_yuv_2);
	fclose(fp_strm_2);

	printf("ENC1 : %d frame encoded\n", frame_1);
	printf("ENC2 : %d frame encoded\n", frame_2);
	printf("--------------------------------------------------------\n");


	free(param_1);
	free(param_2);

	return MFC_RET_OK;
}
