//
// Copyright  2009 Samsung Electronics Co; Ltd. All Rights Reserved.
//
//
//
//
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:    stda_video_layer.c

Abstract:       Implementation of tvout driver DLL
                This module implements Middle Level Video Processor Layer HW control

Functions:


Notes:


--*/

#include <windows.h>
#include <bsp_cfg.h>    // for reference HCLK, ECLK
#include <register_map.h>
#include "tvout_global.h"
#include "stda_common.h"
#include "stda_context.h"
#include "stda_resource.h"
#include "stda_interrupt.h"
#include "stda_video_layer.h"

#define VP_UPDATE_RETRY_MAXIMUM 30
#define VP_WAIT_UPDATE_SLEEP 3

/*  VP Brightness Contrast Reaseved Param */
const signed int g_sVp_brightness_contrast[] =
{
	0x00005E,	0xFEEC6C,	0xF51494,	0xF0A0A0,	0xF0A0A0,	0xF81494,	0x156C6C,	0x1FE060,
	0x00004A,	0xFD6464,	0xEF9C9C,	0xE6B4B4,	0xE6B4B4,	0xF59C9C,	0x1EE464,	0x33CC4C,
	0x000039,	0xFC5C5C,	0xEAA4A4,	0xDEC4C4,	0xDEC4C4,	0xF2A4A4,	0x27DC5C,	0x43BC3C,
	0x000029,	0xFB5454,	0xE5ACAC,	0xD6D4D4,	0xD6D4D4,	0xEFACAC,	0x33D050,	0x4FB030,
	0x000025,	0xFBCC4C,	0xE330B0,	0xD2DCDC,	0xD2DCDC,	0xEE30B0,	0x384C4C,	0x57A828,
	0x000021,	0xFBC848,	0xE230B0,	0xCEE4E4,	0xCEE4E4,	0xEF30B0,	0x3C4848,	0x5BA424,
	0x000021,	0xFCC040,	0xE130B0,	0xCAECEC,	0xCAECEC,	0xF030B0,	0x434040,	0x5BA424,
	0x00001C,	0xFCBC3C,	0xE030B0,	0xC6F4F4,	0xC6F4F4,	0xF130B0,	0x473C3C,	0x5FA020
};



/*============================================================================*/
// Pre-defined functions
/*============================================================================*/

static BOOL STDA_VideoLayer_init_param(PBYTE pBufIn);
static void STDA_VideoLayer_calc_inner_values(void);
static BOOL STDA_VideoLayer_init_vl_reg(void);

static void STDA_VideoLayer_init_op_mode(PBYTE pBufIn);
static void STDA_VideoLayer_init_bypass_post(PBYTE pBufIn);
static void STDA_VideoLayer_init_sarpness(PBYTE pBufIn);
static void STDA_VideoLayer_init_saturation(PBYTE pBufIn);
static void STDA_VideoLayer_init_brightness_offset(PBYTE pBufIn);
static void STDA_VideoLayer_init_csc_control(PBYTE pBufIn);
static BOOL STDA_VideoLayer_init_brightness_contrast_control(PBYTE pBufIn);
static BOOL STDA_VideoLayer_init_poly_filter_coef(PBYTE pBufIn);
static BOOL STDA_VideoLayer_init_csc_coef(PBYTE pBufIn);

static BOOL STDA_VideoLayer_set_priority(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_field_id(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_top_address(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_bottom_address(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_img_size(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_src_position(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_dest_position(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_src_size(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_dest_size(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_brightness_offset(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_contrast(PBYTE pBufIn);
static void STDA_VideoLayer_get_priority(PBYTE pBufOut);
static BOOL STDA_VideoLayer_set_brightness_contrast_control(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_poly_filter_coef(PBYTE pBufIn);
static BOOL STDA_VideoLayer_set_csc_coef(PBYTE pBufIn);
static BOOL STDA_VideoLayer_wait_previous_update(BOOL bFrameWait);

static BOOL STDA_HDMI_wait_hpdVP_status_change(PBYTE pBufIn, PBYTE pBufOut);

void STDA_VideoLayer_CalcImageSize(STDA_ARG_VIDEO_BASIC_PARAM *pVideoParam, UINT32 *dwYsize, UINT32 *dwCsize);

/*============================================================================*/


BOOL
STDA_VideoLayer_API_Proc
(DWORD hOpenContext,
 DWORD dwCode,
 PBYTE pBufIn,
 DWORD dwLenIn,
 PBYTE pBufOut,
 DWORD dwLenOut,
 PDWORD pdwActualOut)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	RETAILMSG(TV_PLAY,(_T("[TVVLA] ++STDA_Video_Layer_API_Proc(%d)\n\r"),dwCode));

	if(!STDA_resource_compare_VP(hOpenContext))
	{
		return FALSE;
	}

	if(dwCode>STDA_VL_FUNCTION_API_BASE && dwCode<=STDA_VL_START && pPMCtxt->bVPLayerEnable)
	{
		RETAILMSG(TV_PLAY,(_T("[TVVLA:ERR] STDA_Video_Layer_API_Proc() : Video Layer is already running status\n\r")));
		return FALSE;
	}

	if(dwCode>STDA_VL_INIT_PROCESSING_PARAM && dwCode<=STDA_VL_START && !(pPMCtxt->bVLMode))
	{
		RETAILMSG(TV_PLAY,(_T("[TVVLA:ERR] STDA_Video_Layer_API_Proc() : Video Layer is not initialized with basic default value\n\r")));
		return FALSE;
	}

	if(dwCode>=STDA_VL_STOP && dwCode<STDA_VL_FUNCTION_API_END && !(pPMCtxt->bVPLayerEnable))
	{
		RETAILMSG(TV_PLAY,(_T("[TVVLA:ERR] STDA_Video_Layer_API_Proc() : Video Layer is not running\n\r")));
		return FALSE;
	}

	switch(dwCode)
	{
		case STDA_VL_INIT_PROCESSING_PARAM:
			return STDA_VideoLayer_init_param(pBufIn);
			break;
		case STDA_VL_INIT_BRIGHTNESS_OFFSET:
			STDA_VideoLayer_init_brightness_offset(pBufIn);
			break;
		case STDA_VL_INIT_CONTRAST_BRIGHTNESS:
			STDA_VideoLayer_init_brightness_contrast_control(pBufIn);
			break;
		case STDA_VL_START:
			return STDA_VideoLayer_start();
			break;
		case STDA_VL_STOP:
			return STDA_VideoLayer_stop();
			break;
		case STDA_VL_SET_PRIORITY:
			return STDA_VideoLayer_set_priority(pBufIn);
			break;
		case STDA_VL_SET_TOP_ADDRESS:
			return STDA_VideoLayer_set_top_address(pBufIn);
			break;
		case STDA_VL_SET_BOTTOM_ADDRESS:
			return STDA_VideoLayer_set_bottom_address(pBufIn);
			break;
		case STDA_VL_SET_FIELD_ID:
			return STDA_VideoLayer_set_field_id(pBufIn);
			break;
		case STDA_VL_SET_IMG_SIZE:
			return STDA_VideoLayer_set_img_size(pBufIn);
			break;
		case STDA_VL_SET_SRC_POSITION:
			return STDA_VideoLayer_set_src_position(pBufIn);
			break;
		case STDA_VL_SET_DEST_POSITION:
			return STDA_VideoLayer_set_dest_position(pBufIn);
			break;
		case STDA_VL_SET_SRC_SIZE:
			return STDA_VideoLayer_set_src_size(pBufIn);
			break;
		case STDA_VL_SET_DEST_SIZE:
			return STDA_VideoLayer_set_dest_size(pBufIn);
			break;
		case STDA_VL_SET_BRIGHTNESS_OFFSET:
			return STDA_VideoLayer_set_brightness_offset(pBufIn);
			break;
		case STDA_VL_SET_CONTRAST_BRIGHTNESS:
			return STDA_VideoLayer_set_brightness_contrast_control(pBufIn);
			break;
		case STDA_VL_GET_PRIORITY:
			STDA_VideoLayer_get_priority(pBufOut);
			break;
		case STDA_HDMI_WAIT_HPD_STATUS_CHANGE:
			return STDA_HDMI_wait_hpdVP_status_change(pBufIn, pBufOut);
			break;
		default:
			RETAILMSG(TV_PLAY,(_T("[TVVLA:ERR] STDA_Video_Layer_API_Proc() : invalid dwCode parameter(%d)\n\r"),dwCode));
			return FALSE;
			break;
	}

	RETAILMSG(TV_PLAY,(_T("[TVVLA] --STDA_Video_Layer_API_Proc()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_init_param
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_BASIC_PARAM *pVideoParam = (STDA_ARG_VIDEO_BASIC_PARAM*)pBufIn;

	BOOL bTVScanProgressive = TRUE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_param()\n\r")));

	memcpy((void *)&(pPMCtxt->tVLBasicParam), (const void *)pVideoParam,
		sizeof(STDA_ARG_VIDEO_BASIC_PARAM));

	pPMCtxt->srcColor = pVideoParam->srcColor;
	pPMCtxt->srcCodec = pVideoParam->srcCodec;

	DBGMSG(TV_INFO,(_T("pVideoParam->bWinBlending[%d] \n\r"),pVideoParam->bWinBlending));
	DBGMSG(TV_INFO,(_T("pVideoParam->srcColor[%d] \n\r"),pVideoParam->srcColor));
	DBGMSG(TV_INFO,(_T("pVideoParam->srcCodec[%d] \n\r"),pVideoParam->srcCodec));
	DBGMSG(TV_INFO,(_T("pVideoParam->uiAlpha[%d] \n\r"),pVideoParam->uiAlpha));
	DBGMSG(TV_INFO,(_T("pVideoParam->uiPriority[%d] \n\r"),pVideoParam->uiPriority));
	
	DBGMSG(TV_INFO,(_T("pVideoParam->uiTopYAddress[0x%x] \n\r"),pVideoParam->uiTopYAddress));
	DBGMSG(TV_INFO,(_T("pVideoParam->uiTopCAddress[0x%x] \n\r"),pVideoParam->uiTopCAddress));

	DBGMSG(TV_INFO,(_T("pVideoParam->srcImgEndian[%d] \n\r"),pVideoParam->srcImgEndian));
	DBGMSG(TV_INFO,(_T("pVideoParam->uiImgWidth[%d] \n\r"),pVideoParam->uiImgWidth));	
	DBGMSG(TV_INFO,(_T("pVideoParam->uiImgHeight[%d] \n\r"),pVideoParam->uiImgHeight));	
	DBGMSG(TV_INFO,(_T("pVideoParam->uiSrcOffsetX[%d] \n\r"),pVideoParam->uiSrcOffsetX));	
	DBGMSG(TV_INFO,(_T("pVideoParam->uiSrcOffsetY[%d] \n\r"),pVideoParam->uiSrcOffsetY));	
	DBGMSG(TV_INFO,(_T("pVideoParam->uiSrcWidth[%d] \n\r"),pVideoParam->uiSrcWidth));		

	DBGMSG(TV_INFO,(_T("pVideoParam->uiSrcHeight[%d] \n\r"),pVideoParam->uiSrcHeight));		
	DBGMSG(TV_INFO,(_T("pVideoParam->uiDestOffsetX[%d] \n\r"),pVideoParam->uiDestOffsetX));		
	DBGMSG(TV_INFO,(_T("pVideoParam->uiDestOffsetY[%d] \n\r"),pVideoParam->uiDestOffsetY));		
	DBGMSG(TV_INFO,(_T("pVideoParam->uiDestWidth[%d] \n\r"),pVideoParam->uiDestWidth));			
	DBGMSG(TV_INFO,(_T("pVideoParam->uiDestHeight[%d] \n\r"),pVideoParam->uiDestHeight));			
	
	if(pVideoParam->uiImgWidth <= 720 && pPMCtxt->tTvOutputParam.dispMode > TVOUT_576P_50_4_3)
	{
		pPMCtxt->vlCscType = VPROC_CSC_SD_HD;
	}
	else if(pVideoParam->uiImgWidth > 720 && pPMCtxt->tTvOutputParam.dispMode < TVOUT_1080P_60)
	{
		pPMCtxt->vlCscType = VPROC_CSC_HD_SD;
	}
	pPMCtxt->tVLCscControl.bCscEn = FALSE;

//we can define vp mode if we know codec output format, and tv scan mode
//interlace -> interlace
//interlace -> progressive
//progressive -> interlace
//progressive -> progressive

	bTVScanProgressive =
		((pPMCtxt->tTvOutputParam.outMode == TVOUT_OUTPUT_COMPOSITE)||
			(pPMCtxt->tTvOutputParam.dispMode == TVOUT_1080I_60))?	FALSE : TRUE;

	pPMCtxt->tVlOpMode.chromaExp = (bTVScanProgressive)?
					VPROC_USING_C_TOP : VPROC_USING_C_TOP_BOTTOM;
					pPMCtxt->tVlOpMode.toggleID = (bTVScanProgressive)? VPROC_FILED_ID_TOGGLE_USER :
					VPROC_FILED_ID_TOGGLE_VSYNC;


	if((pPMCtxt->srcCodec == VPROC_SRC_CODEC_PROGRESSIVE)&&(bTVScanProgressive == TRUE))
	{
		//p->p
		pPMCtxt->tVlOpMode.bLineSkip = FALSE;
		pPMCtxt->tVlOpMode.b2D_IPC = FALSE;
		pPMCtxt->tVlOpMode.toggleID = VPROC_FILED_ID_TOGGLE_USER;

		DBGMSG(TV_INFO,(_T("[TVVLA]   STDA_VideoLayer_init_param()[VP_MODE=PP]\n\r")));		
	}
	else if((pPMCtxt->srcCodec == VPROC_SRC_CODEC_PROGRESSIVE)&&(bTVScanProgressive == FALSE))
	{
		//p->i
		pPMCtxt->tVlOpMode.bLineSkip = TRUE;
		pPMCtxt->tVlOpMode.b2D_IPC = FALSE;
		pPMCtxt->tVlOpMode.toggleID = VPROC_FILED_ID_TOGGLE_VSYNC;
		
		DBGMSG(TV_INFO,(_T("[TVVLA]   STDA_VideoLayer_init_param()[VP_MODE=PI]\n\r")));
		
	}
	else if((pPMCtxt->srcCodec == VPROC_SRC_CODEC_INTERLACE)&&(bTVScanProgressive == TRUE))
	{
		//i->p
		pPMCtxt->tVlOpMode.bLineSkip = TRUE;
		pPMCtxt->tVlOpMode.b2D_IPC = TRUE;
		pPMCtxt->tVlOpMode.toggleID = VPROC_FILED_ID_TOGGLE_USER;

		DBGMSG(TV_INFO,(_T("[TVVLA]   STDA_VideoLayer_init_param()[VP_MODE=IP]\n\r")));
	}
	else if((pPMCtxt->srcCodec == VPROC_SRC_CODEC_INTERLACE)&&(bTVScanProgressive == FALSE))
	{
		//i->i
		pPMCtxt->tVlOpMode.bLineSkip = TRUE;
		pPMCtxt->tVlOpMode.b2D_IPC = FALSE;
		pPMCtxt->tVlOpMode.toggleID = VPROC_FILED_ID_TOGGLE_VSYNC;

		DBGMSG(TV_INFO,(_T("[TVVLA]   STDA_VideoLayer_init_param()[VP_MODE=II]\n\r")));
	}
	else if((pPMCtxt->srcCodec == VPROC_SRC_CODEC_INTERLACE_2PLANE)&&(bTVScanProgressive == TRUE))
	{
		//i_2 -> p
		pPMCtxt->tVlOpMode.bLineSkip = FALSE;
		pPMCtxt->tVlOpMode.b2D_IPC = TRUE;
		pPMCtxt->tVlOpMode.toggleID = VPROC_FILED_ID_TOGGLE_USER;
		
		DBGMSG(TV_INFO,(_T("[TVVLA]   STDA_VideoLayer_init_param()[VP_MODE=I2P]\n\r")));		
	}
	else //((pPMCtxt->srcCodec == VPROC_SRC_CODEC_INTERLACE_2PLANE)&&(bTVScanProgressive == FALSE))
	{
		//i_2 -> i
		pPMCtxt->tVlOpMode.bLineSkip = FALSE;
		pPMCtxt->tVlOpMode.b2D_IPC = FALSE;
		pPMCtxt->tVlOpMode.toggleID = VPROC_FILED_ID_TOGGLE_VSYNC;

		DBGMSG(TV_INFO,(_T("[TVVLA]   STDA_VideoLayer_init_param()[VP_MODE=I2I]\n\r")));		
	}

	if(pPMCtxt->srcColor >= VPROC_SRC_COLOR_TILE_NV12)
	{
		pPMCtxt->tVlOpMode.memMode = VPROC_2D_TILE_MODE;
	}
	else
	{
		pPMCtxt->tVlOpMode.memMode = VPROC_LINEAR_MODE;
	}

	STDA_VideoLayer_calc_inner_values();

	if(pPMCtxt->bVLMode)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA]   STDA_VideoLayer_init_param() : Default values are already updated\n\r")));
		return TRUE;
	}

	// Initialize Video Layer Parameters to Default Values
	pPMCtxt->uiVLSrcXFractStep = 0;
	pPMCtxt->vlFiledId = VPROC_TOP_FIELD;

	pPMCtxt->bVLPolyFilterDefault = TRUE;
	pPMCtxt->bVLByPassPostProcess = FALSE;
	pPMCtxt->uiVLSaturation = 0x80;
	pPMCtxt->tVLSharpness.uiThHNoise = 0;
	pPMCtxt->tVLSharpness.sharpness = VPROC_SHARPNESS_NO;
	pPMCtxt->uiVLBrightOffset = 0x00;
	pPMCtxt->tVLCscControl.bSubYOffsetEn = FALSE;
	pPMCtxt->bVLCscCoefDefault = TRUE;
	pPMCtxt->tVLBCControl[0].eqNum = VProc_LINE_EQ_7+1;
	pPMCtxt->tVLBCControl[1].eqNum = VProc_LINE_EQ_7+1;
	pPMCtxt->tVLBCControl[2].eqNum = VProc_LINE_EQ_7+1;
	pPMCtxt->tVLBCControl[3].eqNum = VProc_LINE_EQ_7+1;
	pPMCtxt->tVLBCControl[4].eqNum = VProc_LINE_EQ_7+1;
	pPMCtxt->tVLBCControl[5].eqNum = VProc_LINE_EQ_7+1;
	pPMCtxt->tVLBCControl[6].eqNum = VProc_LINE_EQ_7+1;
	pPMCtxt->tVLBCControl[7].eqNum = VProc_LINE_EQ_7+1;

	pPMCtxt->bVLByPassPostProcess = TRUE;
	pPMCtxt->uiVLSaturation = 0x90;
	pPMCtxt->tVLSharpness.uiThHNoise = 0x5;
	pPMCtxt->tVLSharpness.sharpness = VPROC_SHARPNESS_NO;

	pPMCtxt->uiVLBCControl = 1;

	if(pPMCtxt->uiVLBCControl <= VProc_LINE_EQ_7)
	{
		int loopCount;

		pPMCtxt->tVLBCControl[0].eqNum = VProc_LINE_EQ_0;
		pPMCtxt->tVLBCControl[1].eqNum = VProc_LINE_EQ_1;
		pPMCtxt->tVLBCControl[2].eqNum = VProc_LINE_EQ_2;
		pPMCtxt->tVLBCControl[3].eqNum = VProc_LINE_EQ_3;
		pPMCtxt->tVLBCControl[4].eqNum = VProc_LINE_EQ_4;
		pPMCtxt->tVLBCControl[5].eqNum = VProc_LINE_EQ_5;
		pPMCtxt->tVLBCControl[6].eqNum = VProc_LINE_EQ_6;
		pPMCtxt->tVLBCControl[7].eqNum = VProc_LINE_EQ_7;

		for(loopCount = 0; loopCount < VProc_LINE_EQ_7+1; loopCount++)
		{
                     //                                                                                                               pPMCtxt->uiVLBCControl * Line_EQ_Register_Num
			pPMCtxt->tVLBCControl[loopCount].uiIntc = ((g_sVp_brightness_contrast[(pPMCtxt->uiVLBCControl * 8) + loopCount])>>8);
			pPMCtxt->tVLBCControl[loopCount].uiSlope = g_sVp_brightness_contrast[(pPMCtxt->uiVLBCControl * 8) + loopCount];

		}

	}

	pPMCtxt->bVLMode = TRUE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_param()\n\r")));

	return TRUE;
}

static void
STDA_VideoLayer_calc_inner_values
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_BASIC_PARAM *pVideo = &(pPMCtxt->tVLBasicParam);
	BOOL bProgressive =
		((pPMCtxt->tTvOutputParam.outMode == TVOUT_OUTPUT_COMPOSITE)||
			(pPMCtxt->tTvOutputParam.dispMode == TVOUT_1080I_60))?	FALSE : TRUE;

	RETAILMSG(TV_PLAY,(_T("[TVVLA] ++STDA_VideoLayer_calc_inner_values()\n\r")));

	pPMCtxt->uiVLTopYAddress      = pVideo->uiTopYAddress;
	pPMCtxt->uiVLTopCAddress      = pVideo->uiTopCAddress;

	if(pPMCtxt->srcColor == VPROC_SRC_COLOR_NV12IW)
	{
		pPMCtxt->uiVLBottomYAddress   = pVideo->uiTopYAddress + pVideo->uiImgWidth;
		pPMCtxt->uiVLBottomCAddress   = pVideo->uiTopCAddress + pVideo->uiImgWidth;
	}

	pPMCtxt->uiVLSrcOffsetX       = pVideo->uiSrcOffsetX;
	pPMCtxt->uiVLSrcOffsetY       = pVideo->uiSrcOffsetY;
	pPMCtxt->uiVLSrcWidth         = pVideo->uiSrcWidth;
	pPMCtxt->uiVLSrcHeight        = pVideo->uiSrcHeight;
	pPMCtxt->uiVLDestOffsetX      = pVideo->uiDestOffsetX;
	pPMCtxt->uiVLDestOffsetY      = pVideo->uiDestOffsetY;
	pPMCtxt->uiVLDestWidth        = pVideo->uiDestWidth;
	pPMCtxt->uiVLDestHeight       = pVideo->uiDestHeight;

	switch(pPMCtxt->srcColor)
	{
		case VPROC_SRC_COLOR_NV12:
		case VPROC_SRC_COLOR_TILE_NV12:

			if (bProgressive)
			{
			}
			else // eScanMode == INTERLACE
			{
				pPMCtxt->uiVLSrcHeight = pVideo->uiSrcHeight/2;
				pPMCtxt->uiVLSrcOffsetY = pVideo->uiSrcOffsetY/2;

				pPMCtxt->uiVLDestHeight = pVideo->uiDestHeight/2;
				pPMCtxt->uiVLDestOffsetY = pVideo->uiDestOffsetY/2;
			}
			break;
		case VPROC_SRC_COLOR_NV12IW:
		case VPROC_SRC_COLOR_TILE_NV12IW: // Interlace weave
			if (bProgressive)
			{
				pPMCtxt->uiVLSrcHeight = pVideo->uiSrcHeight/2;
				pPMCtxt->uiVLSrcOffsetY = pVideo->uiSrcOffsetY/2;
			}
			else // eScanMode == INTERLACE
			{
				// Top field. In fact, in this mode this value is don't care because FILED_ID_AUTO_TOGGLLING bit will be enabled

				pPMCtxt->uiVLSrcHeight = pVideo->uiSrcHeight/2;
				pPMCtxt->uiVLSrcOffsetY = pVideo->uiSrcOffsetY/2;

				pPMCtxt->uiVLDestHeight = pVideo->uiDestHeight/2;
				pPMCtxt->uiVLDestOffsetY = pVideo->uiDestOffsetY/2;
			}
			break;
	default:
		RETAILMSG(TV_PLAY,(_T("[TVVLA:ERR] STDA_VideoLayer_calc_inner_values() : invalid pPMCtxt->srcColor parameter(%d)\n\r"),pPMCtxt->srcColor));
		break;
	}

	RETAILMSG(TV_PLAY,(_T("[TVVLA] --STDA_VideoLayer_calc_inner_values()\n\r")));
}

static void
STDA_VideoLayer_init_op_mode
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_OP_MODE *pOpMode = (STDA_ARG_VIDEO_OP_MODE*)pBufIn;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_op_mode()\n\r")));

	memcpy((void *)&(pPMCtxt->tVlOpMode), (const void *)pOpMode,
		sizeof(STDA_ARG_VIDEO_OP_MODE));

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_op_mode()\n\r")));
}

static void
STDA_VideoLayer_init_bypass_post
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_bypass_post()\n\r")));

	pPMCtxt->bVLByPassPostProcess = (BOOL)(*pBufIn);

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_bypass_post()\n\r")));
}

static void
STDA_VideoLayer_init_sarpness
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_SHARPNESS *ptSharpnesse = (STDA_ARG_VIDEO_SHARPNESS*)pBufIn;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_sarpness()\n\r")));

	memcpy((void *)&(pPMCtxt->tVLSharpness), (const void *)ptSharpnesse,
		sizeof(STDA_ARG_VIDEO_SHARPNESS));

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_sarpness()\n\r")));
}

static void
STDA_VideoLayer_init_saturation
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_saturation()\n\r")));

	pPMCtxt->uiVLSaturation = (unsigned int)(*pBufIn);

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_saturation()\n\r")));
}

static void
STDA_VideoLayer_init_brightness_offset
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_brightness_offset()\n\r")));

	pPMCtxt->uiVLBrightOffset = (unsigned int)(*pBufIn);

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_brightness_offset()\n\r")));
}

static void
STDA_VideoLayer_init_csc_control
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_CSC_CONTROL *ptCscControl = (STDA_ARG_VIDEO_CSC_CONTROL*)pBufIn;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_csc_control()\n\r")));

	memcpy((void *)&(pPMCtxt->tVLCscControl), (const void *)ptCscControl,
		sizeof(STDA_ARG_VIDEO_CSC_CONTROL));

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_csc_control()\n\r")));
}

static BOOL
STDA_VideoLayer_init_brightness_contrast_control
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_BRIGHTNESS_CONTRAST_CONTROL *ptBCControl = (STDA_ARG_VIDEO_BRIGHTNESS_CONTRAST_CONTROL*)pBufIn;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_brightness_contrast_control()\n\r")));

	if(ptBCControl->eqNum > VProc_LINE_EQ_7 || ptBCControl->eqNum < VProc_LINE_EQ_0)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA:ERR] STDA_VideoLayer_init_brightness_contrast_control() : invalid eqNum(%d)\n\r"),ptBCControl->eqNum));
		return FALSE;
	}

	pPMCtxt->tVLBCControl[ptBCControl->eqNum].eqNum = ptBCControl->eqNum;
	pPMCtxt->tVLBCControl[ptBCControl->eqNum].uiIntc= ptBCControl->uiIntc;
	pPMCtxt->tVLBCControl[ptBCControl->eqNum].uiSlope= ptBCControl->uiSlope;	

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_brightness_contrast_control()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_init_poly_filter_coef
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_POLY_FILTER_COEF *ptPolyCoef = (STDA_ARG_VIDEO_POLY_FILTER_COEF*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_poly_filter_coef()\n\r")));

	if(ptPolyCoef->polyCoeff < VPROC_POLY8_Y0_LL ||
		(ptPolyCoef->polyCoeff > VPROC_POLY8_Y3_HH && ptPolyCoef->polyCoeff < VPROC_POLY4_Y0_LL) ||
		ptPolyCoef->polyCoeff > VPROC_POLY4_C1_HH)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA:ERR] STDA_VideoLayer_init_poly_filter_coef() : invalid polyCoeff(%d)\n\r"),ptPolyCoef->polyCoeff));
		return FALSE;
	}

	if(pPMCtxt->powerState == D0)
	{
		error = VProc_initialize_poly_filter_coef(ptPolyCoef->polyCoeff,
		ptPolyCoef->ch0, ptPolyCoef->ch1,
		ptPolyCoef->ch2, ptPolyCoef->ch3);

		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	pPMCtxt->bVLPolyFilterDefault = FALSE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_poly_filter_coef()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_init_csc_coef
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_CSC_COEF *ptCscCoef = (STDA_ARG_VIDEO_CSC_COEF*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_init_csc_coef()\n\r")));

	if(ptCscCoef->cscCoeff < VPROC_CSC_Y2Y_COEF || ptCscCoef->cscCoeff > VPROC_CSC_CR2CR_COEF)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA:ERR] STDA_VideoLayer_init_csc_coef() : invalid cscCoeff(%d)\n\r"),ptCscCoef->cscCoeff));
		return FALSE;
	}

	if(pPMCtxt->powerState == D0)
	{
		error = VProc_initialize_csc_coef(ptCscCoef->cscCoeff, ptCscCoef->uiCoeff);

		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	pPMCtxt->bVLCscCoefDefault = FALSE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_init_csc_coef()\n\r")));

	return TRUE;
}


BOOL
STDA_VideoLayer_start
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	VPROC_ERROR error;
	VMIXER_ERROR error1;
	int i;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_start()\n\r")));

	if(pPMCtxt->powerState == D0)
	{
		Tvout_clk_set_vp_clk_onoff(TRUE);
		VProc_sw_reset();
		VProc_initialize_field_id(pPMCtxt->vlFiledId);

		VProc_initialize_op_mode(pPMCtxt->tVlOpMode.bLineSkip,
							pPMCtxt->tVlOpMode.b2D_IPC,
							pPMCtxt->tVlOpMode.memMode,
							pPMCtxt->tVlOpMode.chromaExp,
							pPMCtxt->tVlOpMode.toggleID);


		if(pPMCtxt->bVLPolyFilterDefault)
		{
			error = VProc_initialize_layer_with_default_poly_filter_coef
							(pPMCtxt->uiVLTopYAddress,
							pPMCtxt->uiVLTopCAddress,
							pPMCtxt->uiVLBottomYAddress,
							pPMCtxt->uiVLBottomCAddress,
							pPMCtxt->tVLBasicParam.srcImgEndian,
							pPMCtxt->tVLBasicParam.uiImgWidth,
							pPMCtxt->tVLBasicParam.uiImgHeight,
							pPMCtxt->uiVLSrcOffsetX,
							pPMCtxt->uiVLSrcXFractStep,
							pPMCtxt->uiVLSrcOffsetY,
							pPMCtxt->uiVLSrcWidth,
							pPMCtxt->uiVLSrcHeight,
							pPMCtxt->uiVLDestOffsetX,
							pPMCtxt->uiVLDestOffsetY,
							pPMCtxt->uiVLDestWidth,
							pPMCtxt->uiVLDestHeight,
							pPMCtxt->bVL2dIpc);
		}
		else
		{
			error = VProc_initialize_layer(pPMCtxt->uiVLTopYAddress,
							pPMCtxt->uiVLTopCAddress,
							pPMCtxt->uiVLBottomYAddress,
							pPMCtxt->uiVLBottomCAddress,
							pPMCtxt->tVLBasicParam.srcImgEndian,
							pPMCtxt->tVLBasicParam.uiImgWidth,
							pPMCtxt->tVLBasicParam.uiImgHeight,
							pPMCtxt->uiVLSrcOffsetX,
							pPMCtxt->uiVLSrcXFractStep,
							pPMCtxt->uiVLSrcOffsetY,
							pPMCtxt->uiVLSrcWidth,
							pPMCtxt->uiVLSrcHeight,
							pPMCtxt->uiVLDestOffsetX,
							pPMCtxt->uiVLDestOffsetY,
							pPMCtxt->uiVLDestWidth,
							pPMCtxt->uiVLDestHeight,
							pPMCtxt->bVL2dIpc);
		}
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		VProc_initialize_bypass_post_process(pPMCtxt->bVLByPassPostProcess);

		VProc_initialize_sharpness(pPMCtxt->tVLSharpness.uiThHNoise,
								pPMCtxt->tVLSharpness.sharpness);

		VProc_initialize_saturation(pPMCtxt->uiVLSaturation);

		for(i=VProc_LINE_EQ_0;i<=VProc_LINE_EQ_7;i++)
		{
			if(pPMCtxt->tVLBCControl[i].eqNum == i)
			{
				error = VProc_initialize_brightness_contrast_control
							(pPMCtxt->tVLBCControl[i].eqNum,
							pPMCtxt->tVLBCControl[i].uiIntc,
							pPMCtxt->tVLBCControl[i].uiSlope);
			}
			if(error != VPROC_NO_ERROR)
			{
				return FALSE;
			}
		}

		VProc_initialize_brightness_offset(pPMCtxt->uiVLBrightOffset);

		VProc_initialize_csc_control(pPMCtxt->tVLCscControl.bSubYOffsetEn,
							pPMCtxt->tVLCscControl.bCscEn);

		if(pPMCtxt->tVLCscControl.bCscEn && pPMCtxt->bVLCscCoefDefault)
		{
			error = VProc_initialize_csc_coef_default(pPMCtxt->vlCscType);

			if(error != VPROC_NO_ERROR)
			{
				return FALSE;
			}
		}

		error = VProc_start();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		error1 = VMixer_initialize_layer(VM_VIDEO_LAYER,
							TRUE,
							pPMCtxt->tVLBasicParam.bWinBlending,
							pPMCtxt->tVLBasicParam.uiAlpha,
							pPMCtxt->tVLBasicParam.uiPriority,
							VM_DIRECT_RGB565,FALSE,FALSE,FALSE,
							0,0,0,0,0,0,0,0,0,0,0);
		if(error1 != VMIXER_NO_ERROR)
		{
			return FALSE;
		}

		VMixer_start();
	}

	pPMCtxt->bVPLayerEnable = TRUE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_start()\n\r")));

	return TRUE;
}

BOOL
STDA_VideoLayer_stop
(void)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	VPROC_ERROR error;
	VMIXER_ERROR error1;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_stop()\n\r")));

	if(pPMCtxt->powerState == D0)
	{
		error1 = VMixer_set_layer_show(VM_VIDEO_LAYER, FALSE);
		if(error1 != VMIXER_NO_ERROR)
		{
			return FALSE;
		}

		VMixer_start();

		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		error = VProc_stop();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		Tvout_clk_set_vp_clk_onoff(FALSE);
	}

	pPMCtxt->bVPLayerEnable = FALSE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_stop()\n\r")));

	return TRUE;
}


static BOOL
STDA_VideoLayer_set_priority
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	VMIXER_ERROR error1;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_priority()\n\r")));

	pPMCtxt->tVLBasicParam.uiPriority = (unsigned int)*(pBufIn);

	if(pPMCtxt->powerState == D0)
	{
		error1 = VMixer_set_layer_priority(VM_VIDEO_LAYER, pPMCtxt->tVLBasicParam.uiPriority);
		if(error1 != VMIXER_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_priority()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_field_id
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_field_id()\n\r")));

	pPMCtxt->vlFiledId = (VPROC_FIELD_ID)*(pBufIn);

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		VProc_set_field_id(pPMCtxt->vlFiledId);

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_field_id()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_top_address
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_IMG_ADDRESS *pAddress = (STDA_ARG_VIDEO_IMG_ADDRESS*)pBufIn;
	VPROC_ERROR error;

	RETAILMSG(TV_PLAY,(_T("[TVVLA] ++STDA_VideoLayer_set_top_address()\n\r")));

	pPMCtxt->tVLBasicParam.uiTopYAddress= pAddress->uiYAddress;
	pPMCtxt->tVLBasicParam.uiTopCAddress = pAddress->uiCAddress;

	STDA_VideoLayer_calc_inner_values();

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		error = VProc_set_top_field_address(pPMCtxt->uiVLTopYAddress,
		pPMCtxt->uiVLTopCAddress);
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		if(pPMCtxt->srcColor == VPROC_SRC_COLOR_NV12IW)
		{
			error = VProc_set_bottom_field_address(pPMCtxt->uiVLBottomYAddress,
			pPMCtxt->uiVLBottomCAddress);
			if(error != VPROC_NO_ERROR)
			{
				return FALSE;
			}
		}
		if((pPMCtxt->tTvOutputParam.outMode == TVOUT_OUTPUT_COMPOSITE)
			||(pPMCtxt->tTvOutputParam.dispMode == TVOUT_1080I_60))
		{

			if(pPMCtxt->tVLBasicParam.srcColor >= VPROC_SRC_COLOR_TILE_NV12)
			{
				error = VProc_set_bottom_field_address(pPMCtxt->tVLBasicParam.uiTopYAddress + TILE_WIDTH,
												pPMCtxt->tVLBasicParam.uiTopCAddress + TILE_WIDTH);
				
			}
			else
			{
				error = VProc_set_bottom_field_address(pPMCtxt->tVLBasicParam.uiTopYAddress + pPMCtxt->tVLBasicParam.uiSrcWidth,
												pPMCtxt->tVLBasicParam.uiTopCAddress + pPMCtxt->tVLBasicParam.uiSrcWidth);
			}


			if(error != VPROC_NO_ERROR)
			{
				return FALSE;
			}

		}

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	RETAILMSG(TV_PLAY,(_T("[TVVLA] --STDA_VideoLayer_set_top_address()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_bottom_address
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_IMG_ADDRESS *pAddress = (STDA_ARG_VIDEO_IMG_ADDRESS*)pBufIn;
	VPROC_ERROR error;

	RETAILMSG(TV_PLAY,(_T("[TVVLA] ++STDA_VideoLayer_set_bottom_address()\n\r")));

	if(pPMCtxt->srcColor == VPROC_SRC_COLOR_NV12IW)
	{
		pPMCtxt->tVLBasicParam.uiTopYAddress =
			pAddress->uiYAddress - pPMCtxt->tVLBasicParam.uiImgWidth;
		pPMCtxt->tVLBasicParam.uiTopCAddress =
			pAddress->uiCAddress - pPMCtxt->tVLBasicParam.uiImgWidth;
	}
	STDA_VideoLayer_calc_inner_values();

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		error = VProc_set_bottom_field_address(pPMCtxt->uiVLBottomYAddress,
		pPMCtxt->uiVLBottomCAddress);
		if(error != VPROC_NO_ERROR)
		{
		return FALSE;
		}

		if(pPMCtxt->srcColor == VPROC_SRC_COLOR_NV12IW)
		{
			error = VProc_set_top_field_address(pPMCtxt->uiVLTopYAddress,
			pPMCtxt->uiVLTopCAddress);
			if(error != VPROC_NO_ERROR)
			{
				return FALSE;
			}
		}
		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	RETAILMSG(TV_PLAY,(_T("[TVVLA] --STDA_VideoLayer_set_bottom_address()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_img_size
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_IMG_SIZE *pSize = (STDA_ARG_IMG_SIZE*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_bottom_address()\n\r")));

	pPMCtxt->tVLBasicParam.uiImgWidth = pSize->uiImgWidth;
	pPMCtxt->tVLBasicParam.uiImgHeight = pSize->uiImgHeight;

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		error = VProc_set_img_size(pSize->uiImgWidth, pSize->uiImgHeight);
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_bottom_address()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_src_position
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_IMG_OFFSET *pOffset = (STDA_ARG_IMG_OFFSET*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_src_position()\n\r")));

	pPMCtxt->tVLBasicParam.uiSrcOffsetX = pOffset->uiOffsetX;
	pPMCtxt->tVLBasicParam.uiSrcOffsetY = pOffset->uiOffsetY;
	STDA_VideoLayer_calc_inner_values();

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		VProc_set_src_position(pPMCtxt->uiVLSrcOffsetX,
							pPMCtxt->uiVLSrcXFractStep,
							pPMCtxt->uiVLSrcOffsetY);

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_src_position()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_dest_position
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_IMG_OFFSET *pOffset = (STDA_ARG_IMG_OFFSET*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_src_position()\n\r")));

	pPMCtxt->tVLBasicParam.uiDestOffsetX = pOffset->uiOffsetX;
	pPMCtxt->tVLBasicParam.uiDestOffsetY = pOffset->uiOffsetY;
	STDA_VideoLayer_calc_inner_values();

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		VProc_set_dest_position(pPMCtxt->uiVLDestOffsetX, pPMCtxt->uiVLDestOffsetY);

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_src_position()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_src_size
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_IMG_SIZE *pSize = (STDA_ARG_IMG_SIZE*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_src_size()\n\r")));

	pPMCtxt->tVLBasicParam.uiSrcWidth = pSize->uiImgWidth;
	pPMCtxt->tVLBasicParam.uiSrcHeight = pSize->uiImgHeight;
	STDA_VideoLayer_calc_inner_values();

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		VProc_set_src_dest_size(pPMCtxt->uiVLSrcWidth, pPMCtxt->uiVLSrcHeight,
		pPMCtxt->uiVLDestWidth, pPMCtxt->uiVLDestHeight,
		pPMCtxt->bVL2dIpc);

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_src_size()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_dest_size
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_IMG_SIZE *pSize = (STDA_ARG_IMG_SIZE*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_dest_size()\n\r")));

	pPMCtxt->tVLBasicParam.uiDestWidth = pSize->uiImgWidth;
	pPMCtxt->tVLBasicParam.uiDestHeight = pSize->uiImgHeight;
	STDA_VideoLayer_calc_inner_values();

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		VProc_set_src_dest_size(pPMCtxt->uiVLSrcWidth, pPMCtxt->uiVLSrcHeight,
							pPMCtxt->uiVLDestWidth, pPMCtxt->uiVLDestHeight,
							pPMCtxt->bVL2dIpc);

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_dest_size()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_brightness_offset
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_brightness()\n\r")));

	pPMCtxt->uiVLBrightOffset = (unsigned int)*pBufIn;

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		VProc_set_brightness_offset(pPMCtxt->uiVLBrightOffset);

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_brightness()\n\r")));

	return TRUE;
}

static void
STDA_VideoLayer_get_priority
(PBYTE pBufOut)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	unsigned int *pId = (unsigned int*)pBufOut;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_get_priority()\n\r")));

	*pId = pPMCtxt->tVLBasicParam.uiPriority;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_get_priority()\n\r")));
}

static BOOL
STDA_VideoLayer_set_brightness_contrast_control
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	VPROC_ERROR error;
	STDA_ARG_VIDEO_BRIGHTNESS_CONTRAST_CONTROL *ptBCControl = (STDA_ARG_VIDEO_BRIGHTNESS_CONTRAST_CONTROL*)pBufIn;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_brightness_contrast_control()\n\r")));
	DBGMSG(TV_FUNC,(_T(" ptBCControl(%d,%d,%d)\n\r"),ptBCControl->eqNum,ptBCControl->uiIntc,ptBCControl->uiSlope));

	if(ptBCControl->eqNum > VProc_LINE_EQ_7 || ptBCControl->eqNum < VProc_LINE_EQ_0)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA:ERR] STDA_VideoLayer_set_brightness_contrast_control() : invalid eqNum(%d)\n\r"),ptBCControl->eqNum));
		return FALSE;
	}

	pPMCtxt->tVLBCControl[ptBCControl->eqNum].eqNum = ptBCControl->eqNum;
	pPMCtxt->tVLBCControl[ptBCControl->eqNum].uiIntc= ptBCControl->uiIntc;
	pPMCtxt->tVLBCControl[ptBCControl->eqNum].uiSlope= ptBCControl->uiSlope;

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		error = VProc_set_brightness_contrast_control(pPMCtxt->tVLBCControl[ptBCControl->eqNum].eqNum,
												pPMCtxt->tVLBCControl[ptBCControl->eqNum].uiIntc,
												pPMCtxt->tVLBCControl[ptBCControl->eqNum].uiSlope);
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_brightness_contrast_control()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_poly_filter_coef
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_POLY_FILTER_COEF *ptPolyCoef = (STDA_ARG_VIDEO_POLY_FILTER_COEF*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_poly_filter_coef()\n\r")));

	if(ptPolyCoef->polyCoeff < VPROC_POLY8_Y0_LL ||
		(ptPolyCoef->polyCoeff > VPROC_POLY8_Y3_HH && ptPolyCoef->polyCoeff < VPROC_POLY4_Y0_LL) ||
		ptPolyCoef->polyCoeff > VPROC_POLY4_C1_HH)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA:ERR] STDA_VideoLayer_set_poly_filter_coef() : invalid polyCoeff(%d)\n\r"),ptPolyCoef->polyCoeff));
		return FALSE;
	}

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		error = VProc_initialize_poly_filter_coef(ptPolyCoef->polyCoeff,
		ptPolyCoef->ch0, ptPolyCoef->ch1,
		ptPolyCoef->ch2, ptPolyCoef->ch3);

		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	pPMCtxt->bVLPolyFilterDefault = FALSE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_poly_filter_coef()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_set_csc_coef
(PBYTE pBufIn)
{
	STDAPowerContext *pPMCtxt = STDA_get_power_context();
	STDA_ARG_VIDEO_CSC_COEF *ptCscCoef = (STDA_ARG_VIDEO_CSC_COEF*)pBufIn;
	VPROC_ERROR error;

	DBGMSG(TV_FUNC,(_T("[TVVLA] ++STDA_VideoLayer_set_csc_coef()\n\r")));

	if(ptCscCoef->cscCoeff < VPROC_CSC_Y2Y_COEF || ptCscCoef->cscCoeff > VPROC_CSC_CR2CR_COEF)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA:ERR] STDA_VideoLayer_set_csc_coef() : invalid cscCoeff(%d)\n\r"),ptCscCoef->cscCoeff));
		return FALSE;
	}

	if(pPMCtxt->powerState == D0)
	{
		if(STDA_VideoLayer_wait_previous_update(TRUE))
		{
			return FALSE;
		}

		error = VProc_initialize_csc_coef(ptCscCoef->cscCoeff, ptCscCoef->uiCoeff);

		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}

		error = VProc_update();
		if(error != VPROC_NO_ERROR)
		{
			return FALSE;
		}
	}

	pPMCtxt->bVLCscCoefDefault = FALSE;

	DBGMSG(TV_FUNC,(_T("[TVVLA] --STDA_VideoLayer_set_csc_coef()\n\r")));

	return TRUE;
}

static BOOL
STDA_VideoLayer_wait_previous_update
(BOOL bFrameWait)
{

	int iCount=0;

	RETAILMSG(TV_PLAY,(_T("[TVVLA] ++STDA_VideoLayer_wait_previous_update(%d)\n\r"),bFrameWait));

	if(bFrameWait)
	{
	while(VProc_get_update_status() && iCount<VP_UPDATE_RETRY_MAXIMUM)
	{
		iCount++;
		Sleep(VP_WAIT_UPDATE_SLEEP);
	}

	if(iCount == VP_UPDATE_RETRY_MAXIMUM)
	{
		DBGMSG(TV_USR1,(_T("[TVVLA:ERR] STDA_VideoLayer_wait_previous_update() : timeout\n\r")));
		return TRUE;
	}

	RETAILMSG(TV_PLAY,(_T("[TVVLA] --STDA_VideoLayer_wait_previous_update()\n\r")));

	return FALSE;
}
	else
	{
		RETAILMSG(TV_PLAY,(_T("[TVVLA] --STDA_VideoLayer_wait_previous_update()\n\r")));

		return TRUE;
	}

}

static BOOL
STDA_HDMI_wait_hpdVP_status_change
(PBYTE pBufIn,
 PBYTE pBufOut)
{
	PDWORD pOut = (PDWORD)pBufOut;
	PDWORD pdwWaitTime = (PDWORD)pBufIn;

	DBGMSG(TV_USR4,(_T("[TVOUT] ++STDA_HDMI_wait_hpdVP_status_change(%d)\n\r"),*pdwWaitTime));

	if(!pBufOut)
	{
		DBGMSG(TV_USR1,(_T("[TVOUT] ++STDA_HDMI_wait_hpdVP_status_change() pBufOut is NULL\n\r")));
		return FALSE;
	}

	*pOut = STDA_interrupt_wait_hpdVP_cmd_done(*pdwWaitTime);

	if(*pOut == WAIT_TIMEOUT)
	{
		DBGMSG(TV_USR4,(_T("[TVOUT] ++STDA_HDMI_wait_hpdVP_status_change() TIMEOUT~\n\r")));
	}
	else if(*pOut == WAIT_FAILED)
	{
		DBGMSG(TV_USR1,(_T("[TVOUT] ++STDA_HDMI_wait_hpdVP_status_change() WAIT_FAILED\n\r")));
	}

	DBGMSG(TV_USR4,(_T("[TVOUT] --STDA_HDMI_wait_hpdVP_status_change() change hpd status\n\r")));

	return TRUE;
}


