//
// Copyright  2009 Samsung Electronics Co; Ltd. All Rights Reserved.
//
//
//
/*++

Module Name:    video_processor.c

Abstract:       Implementation of video processor Library
                This module implements Low Level HW control

Functions:


Notes:


--*/

#include <windows.h>
#include <bsp_cfg.h>    // for reference HCLK, ECLK
#include <register_map.h>
#include "vp_reg.h"
#include "tvout_message.h"
#include "video_processor.h"
#include "video_processor_internal.h"


// initialization
//  - iniization functions are only called under stopping video processor
VPROC_ERROR
VProc_initialize_register_address
(void *pVPReg)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_register_address(0x%08x)\n\r"), pVPReg));

	if (pVPReg == NULL)
	{
		DBGMSG(TV_USR1,(_T("[VP:ERR] VProc_initialize_register_address() : NULL pointer parameter\n\r")));
		return VPROC_ERROR_INVALID_PARAM;
	}
	else
	{
		g_pVPConfig = (PVP_REG)pVPReg;
		DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_register_address(0x%08x)\n\r"), g_pVPConfig));
	}

	return VPROC_NO_ERROR;
}

void
VProc_initialize_field_id
(VPROC_FIELD_ID mode)
{
	VProc_set_field_id(mode);
}

void
VProc_initialize_op_mode
(BOOL bLineSkip,
BOOL b2D_IPC,
VPROC_MEM_MODE memMode,
VPROC_CHROMA_EXPANSION chromaExp,
VPROC_FILED_ID_TOGGLE toggleID)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_op_mode(%d,%d, %d, %d,%d)\n\r"),bLineSkip,b2D_IPC,memMode,chromaExp,toggleID));

	g_pVPConfig->VP_MODE = (bLineSkip)? VP_LINE_SKIP_ON : VP_LINE_SKIP_OFF;
	g_pVPConfig->VP_MODE |= (b2D_IPC)? VP_2D_IPC_ON : VP_2D_IPC_OFF;
	g_pVPConfig->VP_MODE |= (memMode == VPROC_2D_TILE_MODE)?
									VP_MEM_2D_MODE : VP_MEM_LINEAR_MODE;
	g_pVPConfig->VP_MODE |= (chromaExp == VPROC_USING_C_TOP_BOTTOM)?
									VP_CHROMA_USE_TOP_BOTTOM : VP_CHROMA_USE_TOP;
	g_pVPConfig->VP_MODE |= (toggleID == VPROC_FILED_ID_TOGGLE_VSYNC)?
									VP_FIELD_ID_TOGGLE_VSYNC : VP_FIELD_ID_TOGGLE_USER;



	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_op_mode(0x%08x)\n\r"), g_pVPConfig->VP_MODE));
}

VPROC_ERROR
VProc_initialize_layer
(unsigned int uiTopYAddress,
unsigned int uiTopCAddress,
unsigned int uiBottomYAddress,
unsigned int uiBottomCAddress,
TVOUT_ENDIAN_FORMAT_TYPE srcImgEndian,
unsigned int uiImgWidth,
unsigned int uiImgHeight,
unsigned int uiSrcOffsetX,
unsigned int uiSrcXFractStep,
unsigned int uiSrcOffsetY,
unsigned int uiSrcWidth,
unsigned int uiSrcHeight,
unsigned int uiDestOffsetX,
unsigned int uiDestOffsetY,
unsigned int uiDestWidth,
unsigned int uiDestHeight,
BOOL b2dIpc)
{
	VPROC_ERROR error = VPROC_NO_ERROR;

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_layer(%d)\n\r"), srcImgEndian));

	//CommentTemp
	g_pVPConfig->VP_ENDIAN_MODE = (srcImgEndian == TVOUT_BIG_ENDIAN_MODE)?
		VP_BIG_ENDIAN_MODE : VP_LITTLE_ENDIAN_MODE;
	error = VProc_set_top_field_address(uiTopYAddress,uiTopCAddress);
	if(error != VPROC_NO_ERROR)
		return error;
	error = VProc_set_bottom_field_address(uiBottomYAddress,uiBottomCAddress);
	if(error != VPROC_NO_ERROR)
		return error;
	error = VProc_set_img_size(uiImgWidth,uiImgHeight);
	if(error != VPROC_NO_ERROR)
		return error;
	VProc_set_src_position(uiSrcOffsetX,uiSrcXFractStep,uiSrcOffsetY);
	VProc_set_dest_position(uiDestOffsetX,uiDestOffsetY);
	VProc_set_src_dest_size(uiSrcWidth,uiSrcHeight,uiDestWidth,uiDestHeight,b2dIpc);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_layer(0x%08x)\n\r"), g_pVPConfig->VP_ENDIAN_MODE));

	return error;

}

VPROC_ERROR
VProc_initialize_layer_with_default_poly_filter_coef
(unsigned int uiTopYAddress,
unsigned int uiTopCAddress,
unsigned int uiBottomYAddress,
unsigned int uiBottomCAddress,
TVOUT_ENDIAN_FORMAT_TYPE srcImgEndian,
unsigned int uiImgWidth,
unsigned int uiImgHeight,
unsigned int uiSrcOffsetX,
unsigned int uiSrcXFractStep,
unsigned int uiSrcOffsetY,
unsigned int uiSrcWidth,
unsigned int uiSrcHeight,
unsigned int uiDestOffsetX,
unsigned int uiDestOffsetY,
unsigned int uiDestWidth,
unsigned int uiDestHeight,
BOOL b2dIpc)
{
	VPROC_ERROR error = VPROC_NO_ERROR;

	unsigned int uiHRatio = (uiSrcWidth<<16)/uiDestWidth;
	unsigned int uiVRatio = (b2dIpc)? ((uiSrcHeight<<17)/uiDestHeight) :
	((uiSrcHeight<<16)/uiDestHeight);

	VProc_set_poly_filter_coef_default(uiHRatio,uiVRatio);
	error = VProc_initialize_layer(uiTopYAddress,uiTopCAddress,
							uiBottomYAddress,uiBottomCAddress,
							srcImgEndian,
							uiImgWidth,uiImgHeight,
							uiSrcOffsetX,uiSrcXFractStep,uiSrcOffsetY,
							uiSrcWidth,uiSrcHeight,
							uiDestOffsetX,uiDestOffsetY,
							uiDestWidth,uiDestHeight,
							b2dIpc);
	return error;
}

VPROC_ERROR
VProc_initialize_poly_filter_coef
(VPROC_POLY_COEFFICIENT polyCoeff,
signed char ch0,
signed char ch1,
signed char ch2,
signed char ch3)
{
	return VProc_set_poly_filter_coef(polyCoeff,ch0,ch1,ch2,ch3);
}

void
VProc_initialize_bypass_post_process
(BOOL bByPass)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_bypass_post_process(%d)\n\r"), bByPass));

	g_pVPConfig->PP_BYPASS = (bByPass)? VP_BY_PASS_ENABLE : VP_BY_PASS_DISABLE;

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_bypass_post_process(0x%08x)\n\r"), g_pVPConfig->PP_BYPASS));
}

VPROC_ERROR
VProc_initialize_csc_coef
(VPROC_CSC_COEFFICIENT cscCoeff,
unsigned int uiCoeff)
{
	unsigned int* uiTemp = (unsigned int*)&(g_pVPConfig->PP_CSC_Y2Y_COEF);

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_csc_coef(%d,%d)\n\r"),cscCoeff,uiCoeff));

	if(cscCoeff>VPROC_CSC_CR2CR_COEF || cscCoeff<VPROC_CSC_Y2Y_COEF)
	{
		DBGMSG(TV_USR1,(_T("[VP:ERR] VProc_initialize_csc_coef() : invaild cscCoeff parameter \n\r")));
		return VPROC_ERROR_INVALID_PARAM;
	}

	uiTemp += (unsigned int)cscCoeff;
	*uiTemp = VP_CSC_COEF(uiCoeff);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_csc_coef(0x%08x)\n\r"), *uiTemp));

	return VPROC_NO_ERROR;
}

void
VProc_initialize_saturation
(unsigned int uiSat)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_saturation(%d)\n\r"), uiSat));

	g_pVPConfig->PP_SATURATION = VP_SATURATION(uiSat);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_saturation(0x%08x)\n\r"), g_pVPConfig->PP_SATURATION));
}

void
VProc_initialize_sharpness
(unsigned int uiThHNoise,
VPROC_SHARPNESS_CONTROL sharpness)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_sharpness(%d,%d)\n\r"),uiThHNoise,sharpness));

	g_pVPConfig->PP_SHARPNESS = VP_TH_HNOISE(uiThHNoise) | VP_SHARPNESS(sharpness);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_sharpness(0x%08x)\n\r"), g_pVPConfig->PP_SHARPNESS));
}

VPROC_ERROR
VProc_initialize_brightness_contrast_control
(VPROC_LINE_EQ_NUM eqNum,
unsigned int uiIntc,
unsigned int uiSlope)
{
	return VProc_set_brightness_contrast_control(eqNum, uiIntc, uiSlope);
}

void
VProc_initialize_brightness_offset
(unsigned int uiOffset)
{
	VProc_set_brightness_offset(uiOffset);	
}

void
VProc_initialize_csc_control
(BOOL bSubYOffsetEn,
BOOL bCscEn)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_brightness_offset(%d,%d)\n\r"),bSubYOffsetEn,bCscEn));

	g_pVPConfig->PP_CSC_EN = (bSubYOffsetEn)? VP_SUB_Y_OFFSET_ENABLE :
										VP_SUB_Y_OFFSET_DISABLE;
	g_pVPConfig->PP_CSC_EN |= (bCscEn)? VP_CSC_ENABLE : VP_CSC_DISABLE;

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_brightness_offset(0x%08x)\n\r"), g_pVPConfig->PP_CSC_EN));
}

VPROC_ERROR
VProc_initialize_csc_coef_default
(VPROC_CSC_TYPE cscType)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_csc_coef_default(%d)\n\r"),cscType));
	switch(cscType)
	{
		case VPROC_CSC_SD_HD:
			g_pVPConfig->PP_CSC_Y2Y_COEF = Y2Y_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_CB2Y_COEF = CB2Y_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_CR2Y_COEF = CR2Y_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_Y2CB_COEF = Y2CB_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_CB2CB_COEF = CB2CB_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_CR2CB_COEF = CR2CB_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_Y2CR_COEF = Y2CR_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_CB2CR_COEF = CB2CR_COEF_601_TO_709;
			g_pVPConfig->PP_CSC_CR2CR_COEF = CR2CR_COEF_601_TO_709;
			break;
		case VPROC_CSC_HD_SD:
			g_pVPConfig->PP_CSC_Y2Y_COEF = Y2Y_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_CB2Y_COEF = CB2Y_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_CR2Y_COEF = CR2Y_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_Y2CB_COEF = Y2CB_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_CB2CB_COEF = CB2CB_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_CR2CB_COEF = CR2CB_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_Y2CR_COEF = Y2CR_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_CB2CR_COEF = CB2CR_COEF_709_TO_601;
			g_pVPConfig->PP_CSC_CR2CR_COEF = CR2CR_COEF_709_TO_601;
			break;
		default:
			DBGMSG(TV_USR1,(_T("[VP:ERR] VProc_initialize_csc_coef_default() : invalid cscType parameter = %d\n\r"),cscType));
			return VPROC_ERROR_INVALID_PARAM;
			break;
	}

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_csc_coef_default(0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x)\n\r"),
									g_pVPConfig->PP_CSC_Y2Y_COEF,g_pVPConfig->PP_CSC_CB2Y_COEF,g_pVPConfig->PP_CSC_CR2Y_COEF,
									g_pVPConfig->PP_CSC_Y2CB_COEF,g_pVPConfig->PP_CSC_CB2CB_COEF,g_pVPConfig->PP_CSC_CR2CB_COEF,
									g_pVPConfig->PP_CSC_Y2CR_COEF,g_pVPConfig->PP_CSC_CB2CR_COEF,g_pVPConfig->PP_CSC_CR2CR_COEF));

	return VPROC_NO_ERROR;
}


// set
//  - set functions are only called under running video processor
//  - after running set functions, it is need to run VProc_update() function for update shadow registers
void
VProc_set_field_id
(VPROC_FIELD_ID mode)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_set_field_id(%d)\n\r"), mode));

	g_pVPConfig->VP_FIELD_ID = (mode == VPROC_TOP_FIELD)? VP_FIELD_ID_TOP : VP_FIELD_ID_BOTTOM;

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_set_field_id(0x%08x)\n\r"), g_pVPConfig->VP_FIELD_ID));
}

VPROC_ERROR
VProc_set_top_field_address
(unsigned int uiTopYAddress,
unsigned int uiTopCAddress)
{
	RETAILMSG(TV_PLAY,(_T("[VP]++VProc_set_top_field_address(0x%x,0x%x)\n\r"),uiTopYAddress,uiTopCAddress));

	if(VP_PTR_ILLEGAL(uiTopYAddress) || VP_PTR_ILLEGAL(uiTopCAddress))
	{
		RETAILMSG(TV_PLAY,(_T("[VP:ERR] VProc_set_top_field_address() : address is not double word align = 0x%x,0x%x\n\r"),uiTopYAddress,uiTopCAddress));
		return VPROC_ERROR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
	}

	g_pVPConfig->VP_TOP_Y_PTR = uiTopYAddress;
	g_pVPConfig->VP_TOP_C_PTR = uiTopCAddress;

	RETAILMSG(TV_PLAY,(_T("[VP]--VProc_set_top_field_address(0x%x,0x%x)\n\r"),g_pVPConfig->VP_TOP_Y_PTR,g_pVPConfig->VP_TOP_C_PTR));

	return VPROC_NO_ERROR;
}

VPROC_ERROR
VProc_set_bottom_field_address
(unsigned int uiBottomYAddress,
unsigned int uiBottomCAddress)
{
	RETAILMSG(TV_PLAY,(_T("[VP]++VProc_set_bottom_field_address(0x%x,0x%x)\n\r"),uiBottomYAddress,uiBottomCAddress));

	if(VP_PTR_ILLEGAL(uiBottomYAddress)) // || VP_PTR_ILLEGAL(uiBottomCAddress))
	{
		RETAILMSG(TV_PLAY,(_T("[VP:ERR] VProc_set_bottom_field_address() : address is not double word align = 0x%x,0x%x\n\r"),uiBottomYAddress,uiBottomCAddress));
		return VPROC_ERROR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
	}

	g_pVPConfig->VP_BOT_Y_PTR = uiBottomYAddress;
	g_pVPConfig->VP_BOT_C_PTR = uiBottomCAddress;

	RETAILMSG(TV_PLAY,(_T("[VP]--VProc_set_bottom_field_address(0x%x,0x%x)\n\r"),g_pVPConfig->VP_BOT_Y_PTR,g_pVPConfig->VP_BOT_C_PTR));

	return VPROC_NO_ERROR;
}

VPROC_ERROR
VProc_set_img_size
(unsigned int uiImgWidth,
unsigned int uiImgHeight)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_set_img_size(%d,%d)\n\r"),uiImgWidth,uiImgHeight));

	if(VP_IMG_SIZE_ILLEGAL(uiImgWidth))
	{
		DBGMSG(TV_USR1,(_T("[VP:ERR] VProc_set_img_size() : image full size is not double word align = %d,%d\n\r"),uiImgWidth,uiImgHeight));
		return VPROC_ERROR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
	}

	g_pVPConfig->VP_IMG_SIZE_Y = VP_IMG_HSIZE(uiImgWidth) | VP_IMG_VSIZE(uiImgHeight);
	g_pVPConfig->VP_IMG_SIZE_C = VP_IMG_HSIZE(uiImgWidth) | VP_IMG_VSIZE(uiImgHeight/2);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_set_img_size(0x%x,0x%x)\n\r"),g_pVPConfig->VP_IMG_SIZE_Y,g_pVPConfig->VP_IMG_SIZE_C));

	return VPROC_NO_ERROR;
}

void
VProc_set_src_position
(unsigned int uiSrcOffsetX,
unsigned int uiSrcXFractStep,
unsigned int uiSrcOffsetY)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_set_src_position(%d,%d,%d)\n\r"),uiSrcOffsetX,uiSrcXFractStep,uiSrcOffsetY));

	g_pVPConfig->VP_SRC_H_POSITION = VP_SRC_H_POSITION(uiSrcOffsetX) | VP_SRC_X_FRACT_STEP(uiSrcXFractStep);
	g_pVPConfig->VP_SRC_V_POSITION = VP_SRC_V_POSITION(uiSrcOffsetY);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_set_src_position(0x%x,0x%x)\n\r"),g_pVPConfig->VP_SRC_H_POSITION,g_pVPConfig->VP_SRC_V_POSITION));
}

void
VProc_set_dest_position
(unsigned int uiDestOffsetX,
unsigned int uiDestOffsetY)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_set_dest_position(%d,%d)\n\r"),uiDestOffsetX,uiDestOffsetY));

	g_pVPConfig->VP_DST_H_POSITION = VP_DST_H_POSITION(uiDestOffsetX);
	g_pVPConfig->VP_DST_V_POSITION = VP_DST_V_POSITION(uiDestOffsetY);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_set_dest_position(0x%x,0x%x)\n\r"),g_pVPConfig->VP_DST_H_POSITION,g_pVPConfig->VP_DST_V_POSITION));
}

void
VProc_set_src_dest_size
(unsigned int uiSrcWidth,
unsigned int uiSrcHeight,
unsigned int uiDestWidth,
unsigned int uiDestHeight,
BOOL b2dIpc)
{
	unsigned int uiHRatio = (uiSrcWidth<<16)/uiDestWidth;
	unsigned int uiVRatio = (b2dIpc)? ((uiSrcHeight<<17)/uiDestHeight) :
								((uiSrcHeight<<16)/uiDestHeight);

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_set_src_dest_size(%d,%d,%d,%d)\n\r"),uiSrcWidth,uiSrcHeight,uiDestWidth,uiDestHeight));

	g_pVPConfig->VP_SRC_WIDTH = VP_SRC_WIDTH(uiSrcWidth);
	g_pVPConfig->VP_SRC_HEIGHT = VP_SRC_HEIGHT(uiSrcHeight);
	g_pVPConfig->VP_DST_WIDTH = VP_DST_WIDTH(uiDestWidth);
	g_pVPConfig->VP_DST_HEIGHT = VP_DST_HEIGHT(uiDestHeight);
	g_pVPConfig->VP_H_RATIO = VP_H_RATIO(uiHRatio);
	g_pVPConfig->VP_V_RATIO = VP_V_RATIO(uiVRatio);

	g_pVPConfig->VP_MODE = (b2dIpc)? (g_pVPConfig->VP_MODE | VP_2D_IPC_ON) :
								(g_pVPConfig->VP_MODE & ~VP_2D_IPC_ON);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_set_src_dest_size(%d,%d,%d,%d,0x%x,0x%x)\n\r"),
							g_pVPConfig->VP_SRC_WIDTH,g_pVPConfig->VP_SRC_HEIGHT,g_pVPConfig->VP_DST_WIDTH,g_pVPConfig->VP_DST_HEIGHT,g_pVPConfig->VP_H_RATIO,g_pVPConfig->VP_V_RATIO));
}

VPROC_ERROR
VProc_set_poly_filter_coef
(VPROC_POLY_COEFFICIENT polyCoeff,
signed char ch0,
signed char ch1,
signed char ch2,
signed char ch3)
{
	unsigned int* uiTemp = (unsigned int*)&(g_pVPConfig->VP_POLY8_Y0_LL);

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_poly_filter_coef(%d,%d,%d,%d,%d)\n\r"),polyCoeff,ch0,ch1,ch2,ch3));

	if(polyCoeff>VPROC_POLY4_C1_HH || polyCoeff<VPROC_POLY8_Y0_LL ||
			(polyCoeff>VPROC_POLY8_Y3_HH && polyCoeff<VPROC_POLY4_Y0_LL))
	{
		DBGMSG(TV_USR1,(_T("[VP:ERR] VProc_initialize_poly_filter_coef() : invaild polyCoeff parameter \n\r")));
		return VPROC_ERROR_INVALID_PARAM;
	}

	uiTemp += (unsigned int)polyCoeff;
	*uiTemp = ((0xff&ch0)<<24) | ((0xff&ch1)<<16) | ((0xff&ch2)<<8) | (0xff&ch3);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_poly_filter_coef(0x%08x, 0x%08x)\n\r"),uiTemp, *uiTemp));

	return VPROC_NO_ERROR;
}

void
VProc_set_poly_filter_coef_default
(unsigned int uiHRatio,
unsigned int uiVRatio)
{
	VPROC_FILTER_H_PP eHFilter;
	VPROC_FILTER_V_PP eVFilter;
	unsigned char* ucpPolyFilterCoeff;
	int i,j;

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_initialize_poly_filter_coef_default(%d,%d)\n\r"),uiHRatio,uiVRatio));

	/* For the real interlace mode, the vertical ratio should be used after divided by 2.
	Because in the interlace mode, all the VP output is used for SDOUT display
	and it should be the same as one field of the progressive mode.
	Therefore the same filter coefficients should be used for the same the final output video.
	When half of the interlace V_RATIO is same as the progressive V_RATIO,
	the final output video scale is same. (20051104,ishan) */
#if 0
	/*Horizontal Y 8tap */
	/*Horizontal C 4tap */
	if (uiHRatio <= 0x200)           /* 720->720 or zoom in */
		eHFilter = VPROC_PP_H_NORMAL;
	else if (uiHRatio <= 0x240)      /* 720->640 */ // ??
		eHFilter = VPROC_PP_H_8_9 ;
	else if(uiHRatio <= 0x400)       /* 2->1 */ // 2
		eHFilter = VPROC_PP_H_1_2;
	else if (uiHRatio <= 0x600)      /* 3->1 */ // 3
		eHFilter = VPROC_PP_H_1_3;
	else // 0x800                       /* 4->1 */ //4
		eHFilter = VPROC_PP_H_1_4;

	/* Vertical Y 4tap */
	if (uiVRatio <=  0x100)          /* 720->720 or zoom in*/
		eVFilter = VPROC_PP_V_NORMAL;
	else if (uiVRatio <= 0x133)      /*6->5*/
		eVFilter = VPROC_PP_V_5_6;
	else if(uiVRatio <= 0x155)       /* 4->3*/
		eVFilter = VPROC_PP_V_3_4;
	else if (uiVRatio <= 0x200)      /* 2->1*/
		eVFilter = VPROC_PP_V_1_2;
	else if (uiVRatio <= 0x300)      /* 3->1*/
		eVFilter = VPROC_PP_V_1_3;
	else // 0x400                       /* 4->1*/
		eVFilter = VPROC_PP_V_1_4;
	
#else
	/*Horizontal Y 8tap */
	/*Horizontal C 4tap */
	//    if (uiHRatio <= 0x200)            /* 720->720 or zoom in */
	if (uiHRatio <= (0x1<<16))            /* 720->720 or zoom in */
	{
		eHFilter = VPROC_PP_H_NORMAL;
	}
	//    else if (uiHRatio <= 0x240)        /* 720->640 */ // ??
	else if (uiHRatio <= (0x9<<13))        /* 720->640 */ // ??

		eHFilter = VPROC_PP_H_8_9 ;
	//    else if(uiHRatio <= 0x400)        /* 2->1 */ // 2
	else if(uiHRatio <= (0x1<<17))        /* 2->1 */ // 2
		eHFilter = VPROC_PP_H_1_2;
	//    else if (uiHRatio <= 0x600)        /* 3->1 */ // 3
	else if(uiHRatio <= (0x3<<16))        /* 2->1 */ // 2
		eHFilter = VPROC_PP_H_1_3;
	else // 0x800                        /* 4->1 */ //4
		eHFilter = VPROC_PP_H_1_4;

	/* Vertical Y 4tap */
	//    if (uiVRatio <=  0x100)            /* 720->720 or zoom in*/
	if (uiVRatio <= (0x1<<16))            /* 720->720 or zoom in*/
	{
		eVFilter = VPROC_PP_V_NORMAL;
	}
	else if(uiVRatio <= (0x5<<14))        /* 4->3*/
	//else if(uiVRatio <= (0x7<<14))        /* 4->3*/
		eVFilter = VPROC_PP_V_3_4;
	else if (uiVRatio <= (0x3<<15))        /*6->5*/
		eVFilter = VPROC_PP_V_5_6;
	else if (uiVRatio <= (0x1<<17))        /* 2->1*/
		eVFilter = VPROC_PP_V_1_2;
	else if (uiVRatio <= (0x3<<16))        /* 3->1*/
		eVFilter = VPROC_PP_V_1_3;
	else // 0x400                        /* 4->1*/
		eVFilter = VPROC_PP_V_1_4;
#endif
	ucpPolyFilterCoeff = (unsigned char*)(g_sVp8tapCoef_Y_H+eHFilter*16*8);
	for (i=0; i<4; i++)
	{
		for (j=0; j<4; j++)
		{
			VProc_set_poly_filter_coef(VPROC_POLY8_Y0_LL+(i*4)+j,
								*(ucpPolyFilterCoeff+4*j*8 + (7-i)),
								*(ucpPolyFilterCoeff+(4*j+1)*8 + (7-i)),
								*(ucpPolyFilterCoeff+(4*j+2)*8 + (7-i)),
								*(ucpPolyFilterCoeff+(4*j+3)*8 + (7-i)));
		}
	}

	ucpPolyFilterCoeff = (unsigned char*)(g_sVp4tapCoef_C_H+eHFilter*16*4);
	for (i=0; i<2; i++)
	{
		for (j=0; j<4; j++)
		{
			VProc_set_poly_filter_coef(VPROC_POLY4_C0_LL+(i*4)+j,
								*(ucpPolyFilterCoeff+4*j*4 + (3-i)),
								*(ucpPolyFilterCoeff+(4*j+1)*4 + (3-i)),
								*(ucpPolyFilterCoeff+(4*j+2)*4 + (3-i)),
								*(ucpPolyFilterCoeff+(4*j+3)*4 + (3-i)));
		}
	}

	ucpPolyFilterCoeff = (unsigned char*)(g_sVp4tapCoef_Y_V+eVFilter*16*4);
	for (i=0; i<4; i++)
	{
		for (j=0; j<4; j++)
		{
			VProc_set_poly_filter_coef(VPROC_POLY4_Y0_LL+(i*4)+j,
								*(ucpPolyFilterCoeff+4*j*4 + (3-i)),
								*(ucpPolyFilterCoeff+(4*j+1)*4 + (3-i)),
								*(ucpPolyFilterCoeff+(4*j+2)*4 + (3-i)),
								*(ucpPolyFilterCoeff+(4*j+3)*4 + (3-i)));
		}
	}

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_initialize_poly_filter_coef_default(%d,%d)\n\r"),eHFilter,eVFilter));
}

void
VProc_set_src_dest_size_with_default_poly_filter_coef
(unsigned int uiSrcWidth,
unsigned int uiSrcHeight,
unsigned int uiDestWidth,
unsigned int uiDestHeight,
BOOL b2dIpc)
{
	unsigned int uiHRatio = (uiSrcWidth<<16)/uiDestWidth;
	unsigned int uiVRatio = (b2dIpc)? ((uiSrcHeight<<17)/uiDestHeight) :
							((uiSrcHeight<<16)/uiDestHeight);

	VProc_set_src_dest_size(uiSrcWidth,uiSrcHeight,uiDestWidth,uiDestHeight, b2dIpc);
	VProc_set_poly_filter_coef_default(uiHRatio,uiVRatio);
}

VPROC_ERROR
VProc_set_brightness_contrast_control
(VPROC_LINE_EQ_NUM eqNum,
unsigned int uiIntc,
unsigned int uiSlope)
{
	unsigned int* uiTemp = (unsigned int*)&(g_pVPConfig->PP_LINE_EQ0);

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_set_brightness_contrast_control(%d,%d,%d)\n\r"),eqNum,uiIntc,uiSlope));

	if(eqNum>VProc_LINE_EQ_7 || eqNum<VProc_LINE_EQ_0)
	{
		DBGMSG(TV_USR1,(_T("[VP:ERR] VProc_set_brightness_contrast_control() : invaild eqNum parameter \n\r")));
		return VPROC_ERROR_INVALID_PARAM;
	}

	uiTemp += (unsigned int)eqNum;
	*uiTemp = VP_LINE_INTC(uiIntc) | VP_LINE_SLOPE(uiSlope);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_set_brightness_contrast_control(0x%08x)\n\r"), *uiTemp));

	return VPROC_NO_ERROR;
}

void
VProc_set_brightness_offset
(unsigned int uiOffset)
	{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_set_brightness_offset(%d)\n\r"),uiOffset));

	g_pVPConfig->PP_BRIGHT_OFFSET = VP_BRIGHT_OFFSET(uiOffset);

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_set_brightness_offset(0x%08x)\n\r"), g_pVPConfig->PP_BRIGHT_OFFSET));
}

VPROC_ERROR
VProc_update
(void)
{
	RETAILMSG(TV_PLAY,(_T("[VP]++VProc_update()\n\r")));

	g_pVPConfig->VP_SHADOW_UPDATE |= VP_SHADOW_UPDATE_ENABLE;

	RETAILMSG(TV_PLAY,(_T("[VP]--VProc_update()\n\r")));

	return VPROC_NO_ERROR;
}


// get
//  - get info
VPROC_FIELD_ID
VProc_get_field_id
(void)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_get_field_id()\n\r")));

	return (g_pVPConfig->VP_FIELD_ID == VP_FIELD_ID_BOTTOM)? VPROC_BOTTOM_FIELD :
													VPROC_TOP_FIELD;

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_get_field_id()\n\r")));
}
/*
unsigned int
VProc_get_version_info
(void)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_get_version_info()\n\r")));

	return (unsigned int)g_pVPConfig->PP_VERSION_INFO;

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_get_version_info()\n\r")));
}
*/

// etc
//  -
BOOL
VProc_get_update_status
(void)
{
	int i=0;

	RETAILMSG(TV_PLAY,(_T("[VP]++VProc_wait_update()\n\r")));
	RETAILMSG(TV_PLAY,(_T("[VP]--VProc_wait_update()\n\r")));

	return (g_pVPConfig->VP_SHADOW_UPDATE & VP_SHADOW_UPDATE_ENABLE);
}


// start
//  - start functions are only called under stopping video processor
VPROC_ERROR
VProc_start
(void)
{
	VPROC_ERROR error = VPROC_NO_ERROR;
	//int i;
	//unsigned int *puiTemp = (unsigned int*)g_pVPConfig;

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_start()\n\r")));

	//if(error == VPROC_NO_ERROR)
	{
		g_pVPConfig->VP_ENABLE |= VP_ON_ENABLE;
		DBGMSG(TV_FUNC,(_T("[VP]--VProc_start()\n\r")));
	}
	error = VProc_update();
	//for(i=0;i<(0x240/4);i++)
	//{
	//    DBGMSG(TV_USR1,(_T("[VP] 0x%x = 0x%x\n\r"),puiTemp+i,*(puiTemp+i)));
	//}

	return error;
}


// stop
//  - stop functions are only called under running video processor
VPROC_ERROR
VProc_stop
(void)
{
	VPROC_ERROR error = VPROC_NO_ERROR;

	DBGMSG(TV_FUNC,(_T("[VP]++VProc_stop()\n\r")));

	//error = VProc_update();
	//if(error == VPROC_NO_ERROR)
	{
		g_pVPConfig->VP_ENABLE &= ~VP_ON_ENABLE;
		DBGMSG(TV_FUNC,(_T("[VP]--VProc_stop()\n\r")));
	}
	error = VProc_update();

	while(!(g_pVPConfig->VP_ENABLE & VP_POWER_DOWN_RDY))
	{
		Sleep(1);
	}

	return error;
}


// reset
//  - reset function
void
VProc_sw_reset
(void)
{
	DBGMSG(TV_FUNC,(_T("[VP]++VProc_sw_reset()\n\r")));

	g_pVPConfig->VP_SRESET |= VP_SOFT_RESET;

	while(g_pVPConfig->VP_SRESET & VP_SOFT_RESET)
	{
		Sleep(10);
	}

	DBGMSG(TV_FUNC,(_T("[VP]--VProc_sw_reset()\n\r")));
}

