📄 auto.c
字号:
usHStartPos = (DWORD)(usHEndPos - stModeInfo.IHWidth) * (stModeUserData.Clock)
/ (DWORD)stModeInfo.IHWidth;
if(usHStartPos <= 2) break;
usHStartPos = (usHStartPos + 2) & 0xfffc;
//if((stModeInfo.IHTotal - (stModeUserData.Clock - usHStartPos)) > usDelta)
if((usHStartPos + stModeInfo.IHTotal) > (delta + stModeUserData.Clock))
{
stop = 1;
}
else
{
stModeUserData.Clock -= usHStartPos;
}
}
}
if(stop) break;
CAdjustAdcClock(stModeUserData.Clock);
}
while(--count);
if((count == 0) || (stop == 1))
return _ERROR_ABORT;
// Prevent from 1/2-line moire and smear effect.
if((usHEndPos >= stModeInfo.IHWidth && (stModeUserData.Clock - stModeInfo.IHTotal) == 4)
|| (usHEndPos < stModeInfo.IHWidth && (stModeInfo.IHTotal - stModeUserData.Clock) == 4))
{
stModeUserData.Clock = stModeInfo.IHTotal;
CAdjustAdcClock(stModeUserData.Clock);
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);
if(result != _ERROR_SUCCESS)
return result;
usHEndPos = usHEndPos + 1 - usHStartPos;
}
#if(_AUTO_CLOCK_PRECISION < 4)
// Save 4N clock
stop = stModeUserData.Clock;
stModeUserData.Clock += (stModeInfo.IHWidth >= usHEndPos) ? 4 : 2;
CAdjustAdcClock(stModeUserData.Clock);
// Set threshold for Clock Search
CScalerSetByte(_DIFF_THRESHOLD_79, 0x18);
count = stop;
maxval = 0;
delta = 6; // Initial value must be (N * AUTO_CLOCK_STEP)
do
{
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN + 0x10);
if(result != _ERROR_SUCCESS)
return result;
usHEndPos = usHEndPos + 1 - usHStartPos;
if(usHEndPos > (stModeInfo.IHWidth + 2))
{
((DWORD *)pData)[0] = 0;
}
else
{
((DWORD *)pData)[0] = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &phase);
if (0xffffffffL == ((DWORD *)pData)[0]) return _ERROR_INPUT;
}
if(maxval < ((DWORD *)pData)[0])
{
maxval = ((DWORD *)pData)[0];
count = stModeUserData.Clock;
}
if(delta == 0x00)
{
// Check if default clock is the best when clock searching range is larger than default.
if(stModeUserData.Clock > stModeInfo.IHTotal)
{
stModeUserData.Clock = stModeInfo.IHTotal;
CAdjustAdcClock(stModeUserData.Clock);
continue;
}
break;
}
delta -= _AUTO_CLOCK_PRECISION;
stModeUserData.Clock -= _AUTO_CLOCK_PRECISION;
CAdjustAdcClock(stModeUserData.Clock);
}
while(_TRUE);
maxval = maxval / 3;
stModeUserData.Clock = (maxval > ((DWORD)stModeInfo.IHWidth << 10)) ? count : stop;
// if (stModeUserData.Clock > 100)
// stModeUserData.Clock = 100; // within range
CAdjustAdcClock(stModeUserData.Clock);
#endif
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Auto phase process
// Input Value : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoDoAutoPhase(void)
{
BYTE result, phase, best;
DWORD maxsum, temp0, temp1, temp2;
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
if(_ERROR_SUCCESS != result)
return result;
// Set threshold 0x80 for Phase Search
CScalerSetByte(_DIFF_THRESHOLD_79, 0x80);
maxsum = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &result);
if(maxsum == 0xffffffffL)
return _ERROR_INPUT;
if(maxsum == 0)
return _ERROR_ABORT;
if(maxsum < ((DWORD)stModeInfo.IVHeight * 1024 * 3 / 2))
{
// Decrease threshold to 0x40 for Phase Search
CScalerSetByte(_DIFF_THRESHOLD_79, 0x40);
maxsum = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_8, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART(0), &result);
if(maxsum == 0xffffffffL)
return _ERROR_INPUT;
if(maxsum == 0)
return _ERROR_ABORT;
if(maxsum < ((DWORD)stModeInfo.IVHeight * 1024 * 3 / 2))
return _ERROR_PHASE;
}
// Issac:
// Please do not delete these backup code below.
/*if(((DWORD)stModeInfo.IHFreq * stModeInfo.IHTotal / 1000) < 530)
{
BYTE count, ucSelStep, ucSelColor;
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
ucSelStep = (0x01 << _HWAUTO_STEP_2);
count = ((result - 8) & 0x3f);
ucSelColor = count + (8 * ucSelStep);
maxsum = 0;
best = 0;
do
{
CAdjustPhase(count);
if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT)) return _ERROR_INPUT;
if(((DWORD *)pData)[0] > maxsum)
{
maxsum = ((DWORD *)pData)[0];
best = count;
}
count += ucSelStep;
}
while(count < ucSelColor);
CScalerSetByte(_AUTO_ADJ_CTRL1_7D, 0x00);
result = best & 0x3f;
}
else
*/
{
maxsum = CAutoPhaseSearch(_COLOR_SELECT, _HWAUTO_STEP_2, HWAUTOSTEPNUM(8), HWAUTOSTEPSTART((result - 8) & 0x3f), &result);
if(maxsum == 0xffffffffL)
return _ERROR_INPUT;
if(maxsum == 0)
return _ERROR_ABORT;
}
// Search phase by weighting SOD
phase = (result - 3) & 0x3f;
CAdjustPhase(phase);
if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))
return _ERROR_INPUT;
temp0 = ((DWORD *)pData)[0];
phase = (phase + 1) & 0x3f;
CAdjustPhase(phase);
if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))
return _ERROR_INPUT;
temp1 = ((DWORD *)pData)[0];
result = (result + 3) & 0x3f;
maxsum = 0;
do
{
phase = (phase + 1) & 0x3f;
CAdjustPhase(phase);
if(_ERROR_SUCCESS != CAutoReadPhaseInfo(_COLOR_SELECT))
return _ERROR_INPUT;
temp2 = ((DWORD *)pData)[0];
((DWORD *)pData)[0] = temp2 + temp1 + temp0
- ((temp1 > temp0 ? temp1 - temp0 : temp0 - temp1) / 2)
- ((temp1 > temp2 ? temp1 - temp2 : temp2 - temp1) / 2);
if(((DWORD *)pData)[0] > maxsum)
{
maxsum = ((DWORD *)pData)[0];
best = (phase - 1) & 0x3f;
}
temp0 = temp1;
temp1 = temp2;
}
while(phase != result);
stModeUserData.Phase = best;
CAdjustPhase(stModeUserData.Phase);
CScalerSetByte(_DIFF_THRESHOLD_79, 0x40);
return _ERROR_SUCCESS;
}
//--------------------------------------------------
// Description : Auto position process
// Input Value : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoDoAutoPosition(void)
{
BYTE result;
SWORD dtemp, ctemp, atemp;
result = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
if(_ERROR_SUCCESS != result)
return result;
result = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
if(_ERROR_SUCCESS != result)
return result;
/////////////////////////////////
// Calculate Vertical Position //
/////////////////////////////////
CScalerRead(_IPV_ACT_STA_H_18, 2, pData, _AUTOINC);
ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];
CScalerRead(_IVS_DELAY_1C, 1, pData, _AUTOINC);
CScalerRead(_VGIP_HV_DELAY_1E, 1, &pData[1], _AUTOINC);
dtemp = (((WORD)(pData[1] & _BIT1)) << 8) | pData[0];
dtemp = usVStartPos - dtemp;
atemp = (stModeInfo.IVHeight - (usVEndPos - usVStartPos + 1));
if(atemp > 3)
atemp = abs(usVEndPos - usVStartPos + 1 - stModeInfo.IVHeight) / 2;
else
atemp = 0;
while(_TRUE)
{
if(abs(stModeUserData.VPosition + (ctemp - dtemp) - stModeInfo.IVStartPos + atemp) <= ucVStartBias)
{
#if(_V_POSITION_DIRECTION == _V_POSITION_METHOD_0)
stModeUserData.VPosition += ctemp - dtemp + atemp;
#endif
#if(_V_POSITION_DIRECTION == _V_POSITION_METHOD_1)
stModeUserData.VPosition -= ctemp - dtemp + atemp;
#endif
break;
}
else
{
stModeUserData.VPosition = stModeInfo.IVStartPos;
break;
}
}
CAdjustVPosition();
///////////////////////////////////
// Calculate Horizontal Position //
///////////////////////////////////
CScalerRead(_IPH_ACT_STA_H_14, 2, pData, _AUTOINC);
ctemp = (((WORD)(pData[0] & 0x07)) << 8) | pData[1];
CScalerRead(_IHS_DELAY_1D, 2, pData, _AUTOINC);
dtemp = (((WORD)(pData[1] & _BIT0)) << 8) | pData[0];
dtemp = usHStartPos - dtemp - 2;
while(_TRUE)
{
if(abs(stModeUserData.HPosition + (ctemp - dtemp) - stModeInfo.IHStartPos) <= ucHStartBias)
{
stModeUserData.HPosition += ctemp - dtemp;
break;
}
else
{
stModeUserData.HPosition = stModeInfo.IHStartPos;
break;
}
}
CAdjustHPosition();
return _ERROR_SUCCESS;
}
#define _AUTO_VGA_MAX_LEVEL 242
#define _AUTO_VGA_MIN_LEVEL 2
#define _AUTO_COMPONENT_Y_MAX_LEVEL 250
#define _AUTO_COMPONENT_Y_MIN_LEVEL 12
#define _AUTO_COMPONENT_PB_MAX_LEVEL 240
#define _AUTO_COMPONENT_PR_MAX_LEVEL 240
#define _AUTO_VIDEO8_Y_MAX_LEVEL 248
#define _AUTO_VIDEO8_Y_MIN_LEVEL 2//12
#define _AUTO_VIDEO8_C_MAX_LEVEL 236 //this value can't over 240
#define _CHROMA_BLACK_LEVEL 0x80
void CGetTargetValue(UINT8* max_value, UINT8* min_value, UINT8 color)
{
switch(_GET_INPUT_SOURCE())
{
case _SOURCE_VGA:
*max_value = _AUTO_VGA_MAX_LEVEL;
*min_value = _AUTO_VGA_MIN_LEVEL;
break;
case _SOURCE_YPBPR:
if(color == _GREEN)
{
*max_value = _AUTO_COMPONENT_Y_MAX_LEVEL;
*min_value = _AUTO_COMPONENT_Y_MIN_LEVEL;
}
else
{
*max_value = (color == _RED) ? _AUTO_COMPONENT_PR_MAX_LEVEL : _AUTO_COMPONENT_PB_MAX_LEVEL;
*min_value = _CHROMA_BLACK_LEVEL;
}
break;
#if(_VIDEO_AUTO_WHITE_BLANCE == _ENABLE)
case _SOURCE_VIDEO_AV: //VIDEO8
case _SOURCE_VIDEO_SV: //VIDEO8
case _SOURCE_VIDEO_TV: //VIDEO8
if(color == _GREEN)
{
*max_value = _AUTO_VIDEO8_Y_MAX_LEVEL;
*min_value = _AUTO_VIDEO8_Y_MIN_LEVEL;
}
else
{
*max_value = _AUTO_VIDEO8_C_MAX_LEVEL;
*min_value = _CHROMA_BLACK_LEVEL;
}
break;
#endif
}
}
/*
#define VIDEO8_Y_MAX_LEVEL 250
#define VIDEO8_Y_MIN_LEVEL 6
#define VIDEO8_C_MAX_LEVEL 240
*/
//--------------------------------------------------
// Description : Tune ADC gain and offset
// Input Value : None
// Output Value : Measure status
//--------------------------------------------------
BYTE CAutoTuneBalance(void)
{
BYTE rev, result0, result1, color, count;
BYTE xdata ucMax_Value, ucMin_Value;
if(_GET_INPUT_SOURCE() == _SOURCE_VGA)// VGA
{
for(count=0;count<3;count++)
{
stAdcData.AdcGain[count] = 0x80;
stAdcData.AdcOffset[count] = 0x80;
}
CAdjustAdcGainOffset();//jerry0921
}
else if(_GET_INPUT_SOURCE() == _SOURCE_YPBPR )// YPBPR
{
for(count=0;count<3;count++)
{
stYPbPrData.YPbPrGain[count] = 0x80;
stYPbPrData.YPbPrOffset[count] = 0x80;
}
CAdjustAdcGainOffset();//jerry0921
}
#if(_VIDEO_AUTO_WHITE_BLANCE == _ENABLE)
else if(bSourceVideo())// AV / SV / TV
{
SET_CONTRAST(50); // set OSD default value to 50
SET_SATURATION(50); // set OSD default value to 50
SET_VDC_GAIN(0x80);
SET_VDC_OFFSET(0x80);
SET_VDC_CHROMA(0x80);
CVideoSetVDCContrast(0x80);
CVideoSetVDCBrightness(0x80);
CVideoSetVDCSaturation(0x80);
#if(sRGB_Color_Enhance == _ENABLE)
CAdjustSaturationHue(50, _TRUE);// set to OSD default value is 50
#endif
}
#endif
rev = CAutoMeasurePositionV(_MIN_NOISE_MARGIN);
if(rev != _ERROR_SUCCESS) return rev;
rev = CAutoMeasurePositionH(_MIN_NOISE_MARGIN);
if(rev != _ERROR_SUCCESS) return rev;
if(CAutoMeasureColor(_BLUE, _MEASURE_COLORS_MAX, &rev) != _ERROR_SUCCESS) return _ERROR_ABORT;
if(rev < 0x60) return _ERROR_ABORT;
if(CAutoMeasureColor(_GREEN, _MEASURE_COLORS_MAX, &rev) != _ERROR_SUCCESS) return _ERROR_ABORT;
if(rev < 0x60) return _ERROR_ABORT;
if(CAutoMeasureColor(_RED, _MEASURE_COLORS_MAX, &rev) != _ERROR_SUCCESS) return _ERROR_ABORT;
if(rev < 0x60) return _ERROR_ABORT;
if(bSourceVideo())
color = _GREEN; //we don't measure the blue color in VIDEO8 auto color
else
color = _BLUE;
while(_TRUE)
{
count = 0x30;
CGetTargetValue(&ucMax_Value, &ucMin_Value, color);
do
{
rev = CAutoTuneDeviceGain(color, &result0, ucMax_Value);
if(rev == _ERROR_ABORT) return rev;
if(rev == _ERROR_FINISH) break;
rev = CAutoTuneDeviceOffset(color, &result1, ucMin_Value);
#if(_VIDEO_AUTO_WHITE_BLANCE == _ENABLE)
if(bSourceVideo())
{
//Chroma doesn't need to adjust the offset
if(color != _GREEN)
result1 = ucMin_Value;
}
#endif
if(rev == _ERROR_ABORT)
return rev;
if((result0 == ucMax_Value) && (result1 == ucMin_Value))
break;
if((count > 8) && (result0 <= (ucMax_Value + 1)) && (result0 >= (ucMax_Value - 1))
&& (result1 <= (ucMin_Value + 1)) && (result1 >= (ucMin_Value - 1)))
{
count = 8;
}
}
while(--count);
if(color == _BLUE) // 2 : Blue or PB
color = _GREEN;
else if(color == _GREEN) // 1: Green or Y
color = _RED;
else // 0: Red or PR
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -