📄 cnova.c
字号:
}/****f* HwLib/IAnalogOverlay_ClearPulse * USAGE * void IAnalogOverlay_ClearPulse(IAnalogOverlay* pIAnalogOverlay, IN BYTE bPulse) * void CNova__ClearPulse(IAnalogOverlay* pIAnalogOverlay, IN BYTE bPulse) * DESCRIPTION * IAnalogOverlay_ClearPulse is implemented only for Nova(EM9010). * The autodetection is based on pulse detect comparator, that sets bits 2,1,0 of register 0 * when R,G,B analog voltage level of VGA reaches 0.3V. * IAnalogOverlay_ClearPulse clears these three bits. * IAnalogOverlay_ClearPulse is called by CNova__Upper, IDecoderBoard_AdjTopBorder, * IDecoderBoard_AdjLeftBorder, IDecoderBoard_AdjCorrection. * PARAMETERS * IN IAnalogOverlay* pIAnalogOverlay - pointer to the overlay object * IN BYTE bPulse - not used * SEE ALSO * IAnalogOverlay_DetectPulse/******************************************************************************/void CNova__ClearPulse(IAnalogOverlay* pIAnalogOverlay, IN BYTE bPulse){ CNovaBase__Write(pIAnalogOverlay, 0, 0x17 ); // clear Pulse CNovaBase__Write(pIAnalogOverlay, 0, 0x10 ); // prepare Pulse for detection}/****f* HwLib/IAnalogOverlay_DetectPulse * USAGE * void IAnalogOverlay_DetectPulse(IAnalogOverlay* pIAnalogOverlay, IN BYTE bPulse) * void CNova__DetectPulse(IAnalogOverlay* pIAnalogOverlay, IN BYTE bPulse) * DESCRIPTION * IAnalogOverlay_DetectPulse is implemented only for Nova(EM9010). * The autodetection is based on pulse detect comparator, that sets bits 2,1,0 of register 0 * when R,G,B analog voltage level of VGA reaches 0.3V. * IAnalogOverlay_DetectPulse clears these three bits. * IAnalogOverlay_DetectPulse is called by CNova__Upper, IDecoderBoard_AdjTopBorder, * IDecoderBoard_AdjLeftBorder, IDecoderBoard_AdjCorrection. * PARAMETERS * IN IAnalogOverlay* pIAnalogOverlay - pointer to the overlay object * IN BYTE bPulse - 1 for Red, 2 for Green, 4 for Blue * SEE ALSO * IAnalogOverlay_ClearPulse/******************************************************************************/BOOL CNova__DetectPulse(IAnalogOverlay* pIAnalogOverlay, IN BYTE bPulse){ return CNovaBase__Read(pIAnalogOverlay, 0) & bPulse;}/****f* HwLib/CNova__Upper * USAGE * NOT PRESENT in IAnalogOverlay interface * void CNova__Upper(IAnalogOverlay* pIAnalogOverlay, WORD Color, BYTE MaxValue, WORD* pUpperLimit) * DESCRIPTION * CNova__Upper is implemented only for Nova(EM9010). * It detects the upper limit of the chroma key for the "Color" specified and the color * intensity specified by MaxValue. It assumes that the VGA is painted with "Color"in the * the Mpeg window area and Mpeg itself is black. It assumes also that the mask is set to * the required "Color". * 1. The current implementation returns a default value (BlackLevelUpper) for 0% color * intensity(MaxValue<0x20) because of hardware limitation. * For MaxValue > 0x20 the function starts setting the chroma key registers to "MaxValue". * The VGA "color" is visible on the VGA screen at this time and pulse detect should set * the corresponding bit in register 0 (pulse detect comparator has a similar function like * the human eye; it sets the register 0 when the human eye see the color on the screen). * Then the chroma key upper limit is decreased until the VGA color is completly covered * by the black Mpeg and the pulse cannot be detected. This value is returned in pUpperLimit. * In case the value is too small (detection error) a default value is returned. * CNova__Upper is called by IAnalogOverlay_UpperLower. * PARAMETERS * IN IAnalogOverlay* pIAnalogOverlay - pointer to the overlay object * IN WORD Color - one of RLIMIT, GLIMIT, BLIMIT * IN BYTE MaxValue - indicates the color intensity (recommended values 0xFF for 100% color, * 0x80 for 50% color, 0x20 for 0% color). * IN WORD* pUpperLimit - receives the upper limit of chroma key for the specified Color * SEE ALSO * CNova__Lower, IAnalogOverlay_UpperLower/******************************************************************************/void CNova__Upper(IAnalogOverlay* pIAnalogOverlay, WORD Color, BYTE MaxValue, WORD* pUpperLimit){ CNova *this = (CNova*) pIAnalogOverlay; BYTE i; if(MaxValue <= 0x20) { // the detection for black is not working - take some defaults *pUpperLimit = this->BlackLevelUpper; return; } if( !CNova__WaitVSync(pIAnalogOverlay) ) return; CNova__WriteREG12(pIAnalogOverlay, Color, MaxValue, 0x00 ); CNova__ClearPulse(pIAnalogOverlay, 1); for(i = MaxValue;i>0;i--) { QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("KeyUpper=%x"), i)); CNova__WriteREG12(pIAnalogOverlay, Color, i, 0x00 ); if( CNovaBase__Read(pIAnalogOverlay, 0) & (Color>>3) ) break; } // Nova 9828 ( manufacturing date ) doesn't detect the grey color with S3 Trio VGA board -> // check if Nova doesn't work and take some defaults that are OK with S3 Trio 3D if( i < 0x20 ) { QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("S3 + bad Nova Problem"), i)); i = MaxValue - 0x20; this->BlackLevelUpper = 0x10 - this->DeltaUpperLevel; } *pUpperLimit = i;}/****f* HwLib/CNova__Lower * USAGE * NOT PRESENT in IAnalogOverlay interface * void CNova__Upper(IAnalogOverlay* pIAnalogOverlay, WORD Color, WORD* pLowerLimit) * DESCRIPTION * CNova__Upper is implemented only for Nova(EM9010). * It should detect the lower limit of the chroma key for the "Color" specified, but * it returns 0 in pLowerLimit, without detecting anything(hardware limitation). * CNova__Lower is called by IAnalogOverlay_UpperLower./******************************************************************************/void CNova__Lower(IAnalogOverlay* pIAnalogOverlay, WORD Color, WORD* pLowerLimit){ *pLowerLimit = 0; return;/* //remove next code because the current NOVA cannot detect the lower limit BYTE i; for(i=0;i<0xff;i++) { CNovaBase__WriteREG12(pIAnalogOverlay, Color, 0xff, i ); if( CNovaBase__Read(pIAnalogOverlay, 0) & 0x01 ) break; QDbgLog((QLOG_TRACE, QDebugLevelWarning, TEXT("KeyLower=%x"), i)); } *pLowerLimit = i;*/}/****f* HwLib/IAnalogOverlay_UpperLower * USAGE * void IAnalogOverlay_UpperLower(IAnalogOverlay* pIAnalogOverlay, * BYTE MaxValue, OVERLAY_COLOUR_REGISTERS* pRegs) * void CNova__UpperLower(IAnalogOverlay* pIAnalogOverlay, * BYTE MaxValue, OVERLAY_COLOUR_REGISTERS* pRegs) * DESCRIPTION * IAnalogOverlay_UpperLower is implemented only for Nova(EM9010). * It detects the upper and lower limit of the chroma key for Red, Green and Blue at color * intensity specified by MaxValue. It assumes that the VGA is painted with grey shades in * the Mpeg window area and Mpeg itself is black. * It calls CNova__Upper three times for Red, Green and Blue to find the upper limits of * chroma key, increase them by DeltaUpperLevel=0x14 (value initialized in IAnalogOverlay_Init) * and save them in OVERLAY_COLOUR_REGISTERS structure. DeltaUpperLevel is added to avoid * any transparence of the Mpeg (hardware, issue). * It calls CNova__Lower three times for Red, Green and Blue to find the lower limits of * chroma key, decrease them by DeltaLevel=0x28 (value initialized in IAnalogOverlay_Init) * and save them in OVERLAY_COLOUR_REGISTERS structure. DeltaLevel is added to avoid * any transparence of the Mpeg (hardware, issue). * The ideal hardware should have DeltaUpperLevel and DeltaLevel very small, case when only * one specific VGA color will be replaced by Mpeg. Increasing DeltaLevel different shades of * the same VGA color will become transparent to Mpeg. * * IAnalogOverlay_UpperLower is called by IDecoderBoard_OverlayColorCalibrate. * PARAMETERS * IN IAnalogOverlay* pIAnalogOverlay - pointer to the overlay object * IN BYTE MaxValue - indicates the color intensity (recommended values 0xFF for 100% color, * 0x80 for 50% color, 0x20 for 0% color). * IN OVERLAY_COLOUR_REGISTERS* pRegs - receives the upper and lower limits for RGB/******************************************************************************/BOOL CNova__UpperLower(IAnalogOverlay* pIAnalogOverlay, BYTE MaxValue, OVERLAY_COLOUR_REGISTERS* pRegs){ // For MAX - Unmask Max for the color to calibrate, all other masked, set Max to 0xff. // The VGA is covered by black MPEG => the pulse is OFF. Decrease Max from 0xff // to 0x00 until the pulse is ON (we begin to see the white VGA through black MPEG). CNova *this = (CNova*) pIAnalogOverlay; CNovaBase__Write(pIAnalogOverlay, 0xa, 0x37 );// unmask upper RED CNova__Upper(pIAnalogOverlay, RLIMIT, MaxValue, &pRegs->RedUpper); CNovaBase__Write(pIAnalogOverlay, 0xa, 0x57 );// unmask upper GREEN CNova__Upper(pIAnalogOverlay, GLIMIT, MaxValue, &pRegs->GreenUpper); CNovaBase__Write(pIAnalogOverlay, 0xa, 0x67 );// unmask upper BLUE CNova__Upper(pIAnalogOverlay, BLIMIT, MaxValue, &pRegs->BlueUpper); // For MIN - Unmask Min for the color to calibrate, all other masked, set Min to 0x00. // The VGA is covered by black MPEG => the pulse is OFF. Increase Min from 0x00 // to 0xFF until the pulse is ON (we begin to see the white VGA through black MPEG). CNovaBase__Write(pIAnalogOverlay, 0xA, 0x73 );// unmask lower RED CNova__Lower(pIAnalogOverlay, RLIMIT, &pRegs->RedLower); CNovaBase__Write(pIAnalogOverlay, 0xA, 0x75 );// unmask lower GREEN CNova__Lower(pIAnalogOverlay, GLIMIT, &pRegs->GreenLower); CNovaBase__Write(pIAnalogOverlay, 0xA, 0x76 );// unmask lower BLUE CNova__Lower(pIAnalogOverlay, BLIMIT, &pRegs->BlueLower); pRegs->RedUpper = (BYTE) min( 0xff, (SHORT)(pRegs->RedUpper + this->DeltaUpperLevel) ); pRegs->GreenUpper = (BYTE) min( 0xff, (SHORT)(pRegs->GreenUpper + this->DeltaUpperLevel) ); pRegs->BlueUpper = (BYTE) min( 0xff, (SHORT)(pRegs->BlueUpper + this->DeltaUpperLevel) ); pRegs->RedLower = (BYTE) max( 0x00, (SHORT)(pRegs->RedUpper - this->DeltaLevel) ); pRegs->GreenLower = (BYTE) max( 0x00, (SHORT)(pRegs->GreenUpper - this->DeltaLevel) ); pRegs->BlueLower = (BYTE) max( 0x00, (SHORT)(pRegs->BlueUpper - this->DeltaLevel) ); return TRUE;}DWORD GetInterpolatedValue( IN DWORD valFF,IN DWORD val80,IN DWORD val00,IN DWORD val ){ DWORD retval; DWORD x1, y1, x2, y2; if (val < 0x80) { x1 = 0; y1 = val00; x2 = 0x80; y2 = val80; } else { x1 = 0x80; y1 = val80; x2 = 0xFF; y2 = valFF; } retval = ((y2-y1)*(val-x1)/(x2-x1)) + y1; QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("0x%lx (0x%lx, 0x%lx, 0x%lx) -> 0x%lx"), val, val00, val80, valFF, retval)); return retval;}/****f* HwLib/IAnalogOverlay_UpdateColorKey * USAGE * BOOL IAnalogOverlay_UpdateColorKey(IAnalogOverlay* pIAnalogOverlay) * BOOL CNova__UpdateColorKey(IAnalogOverlay* pIAnalogOverlay) * DESCRIPTION * IAnalogOverlay_UpdateColorKey is implemented only for Nova(EM9010). * IAnalogOverlay_UpdateColorKey sets the Nova overlay registers according to the VGAKeyReq * (previously set by IAnalogOverlay_SetVgaKey). * The VGAKeyReq can be: * - index in a pallete if color depth is 4 or 8 bits * - true color if color depth is 16, 24, 32bits. * If VGAKeyReq is an index it will be transformed into true color using a standard palette. * The next step is to find the chroma key limits (VGAKeyUpper, VGAKeyLower) of the Nova chip, * corresponding to VGAKeyReq, knowing the chroma key limits for black, grey and white. * There are two possibilities, selectable by user: * 1. Chroma key limits for black, grey and white are preset by user (manual calibration or * specific values) through IAnalogOverlay_SetVgaKey2 in OVERLAY_COLOUR_REGISTERS structure * or through IAnalogOverlay_SetOverrideRedUpper, IAnalogOverlay_SetOverrideRedLower etc. * 2. A previous autocalibration sets the chroma key limits for black, grey and white, see * IDecoderBoard_OverlayColorCalibrate. * * The digital value of Red, Green or Blue is mapped to the appropiate value of Nova registers * using linear interpolation: * * chroma key limit * | * white + .* * VGAKeyUpper Y<---------------o/ * | ../ | * | ./ | * grey + .* | * | ./ | * | ./ | * | ./ | * |./ | * black* | * +---------+------X--+---> digital value for color(R, G or B) * 0 0x80 0xFF * black grey white * 0% 50% 100% * * After VGAKeyUpper and VGAKeyLower are found IAnalogOverlay__MakeMask is called to make * the chroma key mask, then depending of the mode required ModeReq (previously set by * IAnalogOverlay_SetMode) one of the functons is called: * - IAnalogOverlay_Hide for MpegModeNone * - IAnalogOverlay_SetChromaKey for MpegModeOverlay * - IAnalogOverlay_ShowAll for MpegModeRectangle. * IAnalogOverlay_UpdateColorKey is called by IAnalogOverlay_SetMode, IAnalogOverlay_SetVgaKey, * IAnalogOverlay_SetVgaKey2. * PARAMETERS * IN IAnalogOverlay* pIAnalogOverlay - pointer to the overlay object * SEE ALSO * IAnalogOverlay_SetColorCalibration/******************************************************************************/BOOL CNova__UpdateColorKey(IAnalogOverlay* pIAnalogOverlay){ CNova *this = (CNova*) pIAnalogOverlay; BOOL IsIndex = FALSE; // TRUE if we are palette based display DWORD VGAKeyReq = this->VGAKeyReq & 0x00FFFFFF; DWORD VGAKeyMask, VGAKeyUpper, VGAKeyLower; DWORD Red, Green, Blue; // (this->VGAKeyReq & 0xFF000000) indicates t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -