📄 tccvrend.cpp
字号:
#if defined(__TCC79XX_WINCE__)
#include "../Common/TCC79x_Physical.h"
#include "../Common/Virtual.h"
#include <streams.h>
#include <initguid.h>
#include "TCCVrend.h"
#include "../Common/TCCUtil.h"
#define HwLIOC_IMG210 (Hw14+Hw12)
#define HwLIOC_IMG102 Hw13
#define _STATIC_INTERRUPT_
#else // TCC78x
#include "../Common/TCC78xPhysical.h"
#include "../Common/Virtual.h"
#include <streams.h>
#include <initguid.h>
#include "tccvrend.h"
#include "../Common/DEBUG.H"
#include "../Common/TCCUtil.h"
//#define _STATIC_INTERRUPT_
#endif
#ifdef _STATIC_INTERRUPT_
#define STATIC_INTERRUPT_USED
#define SYSINTR_SCALER_ALARM 42
#endif
//
// Constructor
//
CVideoRenderer::CVideoRenderer() : m_nTop(0),
m_nLeft(0),
m_nDstSizeH(0),
m_nDstSizeV(0)
{
pLcdINF = NULL;
VirtualAlloc_Init();
CInitRegister();
Bak_LI0C = pLcdINF->LI0C;
Bak_LCTRL = pLcdINF->LCTRL;
Bak_LCLKDIV = pLcdINF->LCLKDIV;
m_flag.mode=0;
m_flag.top=0;
m_flag.left=0;
m_flag.width=m_nScreenWidth;
m_flag.height=m_nScreenHeight;
m_bAVSync = TRUE;
} // (Constructor)
//
// Destructor
//
CVideoRenderer::~CVideoRenderer()
{
pLcdINF->LCTRL = Bak_LCTRL;
pLcdINF->LI0C = Bak_LI0C;
pLcdINF->LCLKDIV = Bak_LCLKDIV;
VirtualAlloc_Free();
} // (Destructor)
void CVideoRenderer::EnableLayer0()
{
if(pLcdINF)
pLcdINF->LCTRL |=(HwLCTRL_IEN0_EN);
}
void CVideoRenderer::DisableLayer0()
{
if(pLcdINF)
pLcdINF->LCTRL &=~(HwLCTRL_IEN0_EN);
}
BOOL CVideoRenderer::GetModeFlag(VrenderModeFlag* flag)
{
flag->mode=m_flag.mode;
flag->top=m_flag.top;
flag->left=m_flag.left;
flag->width=m_flag.width;
flag->height=m_flag.height;
return TRUE;
}
BOOL CVideoRenderer::SetModeFlag(VrenderModeFlag flag)
{
m_flag.mode=flag.mode;
m_flag.top=flag.top;
m_flag.left=flag.left;
m_flag.width=flag.width;
m_flag.height=flag.height;
return TRUE;
}
BOOL CVideoRenderer::SetAVSync(BOOL AVSync)
{
m_bAVSync = AVSync;
return TRUE;
}
int CVideoRenderer::CInitRegister(void)
{
HKEY hk=NULL;
DWORD dwStatus;
DWORD dwSize,dwType;
m_nScreenWidth = 480; // Default Screen width is 480 (WQVGA)
m_nScreenHeight = 272; // Default Screen height is 272 (WQVGA)
#if defined(__TCC79XX_WINCE__)
m_pScalerMem1 = SCALER_TCC79X_OUT1; // Default TCC79x Phyiscal Memory Address for SCALER1
m_pScalerMem2 = SCALER_TCC79X_OUT2; // Default TCC79x Phyiscal Memory Address for SCALER2
dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Drivers\\TCC79X\\CONFIG", 0, 0, &hk);
#else // TCC78x
m_pScalerMem1 = SCALER_OUT1; // Default TCC78x Phyiscal Memory Address for SCALER1
m_pScalerMem2 = SCALER_OUT2; // Default TCC78x Phyiscal Memory Address for SCALER2
dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Drivers\\Display\\TCC78X\\CONFIG", 0, 0, &hk);
#endif
dwType = REG_DWORD;
if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD)
{
dwSize = sizeof(DWORD);
dwStatus = RegQueryValueEx(hk, _T("LCD_Width"), NULL, &dwType, (LPBYTE) &m_nScreenWidth, &dwSize);
}
if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD)
{
dwSize = sizeof(DWORD);
dwStatus = RegQueryValueEx(hk, _T("LCD_Height"), NULL, &dwType, (LPBYTE) &m_nScreenHeight, &dwSize);
}
#if defined(__TCC79XX_WINCE__)
DWORD dwStartAddrScaler, dwEndAddrScaler;
if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD)
{
dwSize = sizeof(DWORD);
dwStatus = RegQueryValueEx(hk, _T("VIDEO_MEM_SCALER"), NULL, &dwType, (LPBYTE) &dwStartAddrScaler, &dwSize);
}
if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD)
{
dwSize = sizeof(DWORD);
dwStatus = RegQueryValueEx(hk, _T("VIDEO_MEM_END"), NULL, &dwType, (LPBYTE) &dwEndAddrScaler, &dwSize);
}
m_pScalerMem1 = dwStartAddrScaler;
m_pScalerMem2 = dwStartAddrScaler+((dwEndAddrScaler-dwStartAddrScaler)>>1);
#endif
RETAILMSG(0,(TEXT("[RENDER] Scaler Memory %08X, %08X\n"), m_pScalerMem1, m_pScalerMem2));
if(hk != NULL)
{
RegCloseKey(hk);
}
return TRUE;
}
int CVideoRenderer::VirtualAlloc_Init(void)
{
sMSC = (MSC_REG*)SetVirtual( 0xF0070000, sizeof(MSC_REG));
if( sMSC == NULL ) {
return -1;
}
pLcdINF = (tLcdInterface *)SetVirtual(0xF0000000,sizeof(tLcdInterface));
if( pLcdINF == NULL ) {
return -1;
}
#ifdef M2MSCALER_CLOCKCONTROL
pCKCREG = (TCC78xCKCReg*)SetVirtual( (unsigned int)&HwCLKCTRL, sizeof(TCC78xCKCReg) );
if( pCKCREG == NULL ) {
return -1;
}
BITSET(pCKCREG->BCLKCTR , HwBCLKCTR_M2MS); // M2M Scaler Bus clock enable
#endif
return 1;
}
void CVideoRenderer::VirtualAlloc_Free(void)
{
FreeVirtual((void*)sMSC, sizeof(MSC_REG));
FreeVirtual((void*)pLcdINF, sizeof(tLcdInterface));
#ifdef M2MSCALER_CLOCKCONTROL
if(pCKCREG) {
BITCLR(pCKCREG->BCLKCTR , HwBCLKCTR_M2MS); //M2M Scaler Bus clock Disable
FreeVirtual( (void*)pCKCREG, sizeof(pCKCREG) ); pCKCREG = NULL; }
#endif
}
void CVideoRenderer::TCC_VideoScale (
U8 *pSrcBase, U16 nSrcWidth, U16 nSrcHeight, U8 nSrcType, U32 nSrcOffsetY,
U8 *pDstBase, U16 nDstWidth, U16 nDstHeight, U8 nDstType, U32 nDstOffsetY,volatile MSC_REG *sMSC
,U8 nHeightOffset // garbage lines due to 16bit alignment output
,U8 nWidthOffset // garbage pixels due to 16bit alignment output
)
{
U32 nScaleH, nScaleV;
U32 nSrcImageSize, nDstImageSize;
U32 nSrcOffsetC, nDstOffsetC;
U32 nSrcFrameWidth, nDstFrameWidth;
U32 nSrcWidth2,nSrcHeight2;
while ( (sMSC->MSCSTR & HwMSCSTR_RDY) != HwMSCSTR_RDY )
{
Sleep(0); // do nothing
}
nSrcWidth2 = ((nSrcWidth-nWidthOffset)>>3)<<3; // 8bit align
nSrcHeight2= ((nSrcHeight-nHeightOffset)>>1)<<1; // 2bit align
nScaleH = nSrcWidth * 256 / nDstWidth;
nScaleV = (nSrcHeight-nHeightOffset) * 256 / nDstHeight;
nSrcImageSize = nSrcWidth * nSrcHeight;
nDstImageSize = nDstWidth * nDstHeight;
nSrcOffsetC = nSrcOffsetY / 2;
nDstOffsetC = nDstOffsetY / 2;
nSrcFrameWidth = nSrcOffsetY;
nDstFrameWidth = nDstOffsetY;
//Setting the Source Image Information
sMSC->SRCBASEY = (unsigned int)pSrcBase;
sMSC->SRCBASEU = (unsigned int)(pSrcBase + nSrcFrameWidth * nSrcHeight);
if ( nSrcType == 2 ) // 422 Separate
sMSC->SRCBASEV = sMSC->SRCBASEU + ((nSrcFrameWidth * nSrcHeight)>>1);
else // 420 Separate
sMSC->SRCBASEV = (sMSC->SRCBASEU + ((nSrcFrameWidth * nSrcHeight)>>2) );
sMSC->SRCSIZE = ((nSrcHeight-nHeightOffset)<<16) | (nSrcWidth<<0);
sMSC->SRCOFF = (nSrcOffsetC<<16) | (nSrcOffsetY<<0);
sMSC->SRCCFG = nSrcType;
//Setting the Destination Image Information
sMSC->DSTBASEY = (unsigned int)pDstBase;
sMSC->DSTBASEU = (unsigned int)(pDstBase + nDstFrameWidth * nDstHeight);
if ( nDstType == 2 ) // 422 Separate
sMSC->DSTBASEV = sMSC->DSTBASEU + ((nDstFrameWidth * nDstHeight)>>1);
else // 420 Separate
sMSC->DSTBASEV = sMSC->DSTBASEU + ((nDstFrameWidth * nDstHeight)>>2);
sMSC->DSTSIZE = (nDstHeight<<16) | (nDstWidth<<0);
sMSC->DSTOFF = (nDstOffsetC<<16) | (nDstOffsetY<<0);
sMSC->DSTCFG = nDstType;
//Setting the Scale Factor
sMSC->MSCINF = (nScaleV << 16) | (nScaleH << 0);
//Setting the Control Register
sMSC->MSCSTR |= HwMSCSTR_IRDY;
sMSC->MSCCTR = HwMSCCTR_IEN_RDY | Hw0; // IEN | EN
sMSC->MSCCTR = HwMSCCTR_IEN_RDY; // IEN
}
#define UPSCALING_FIX
void CVideoRenderer::WriteFrame(unsigned char *pFrame ,int nWidth, int nHeight, int nType, int nHeightOffset, int nWidthOffset)
{
U32 nWndSizeH,nWndSizeV;
#ifdef UPSCALING_FIX
U32 nLeftOffset=0;
#endif
if (pLcdINF->LCTRL & Hw7) // TV Mode
{
nWndSizeH = 720;
nWndSizeV = 480;
}
else
{
nWndSizeH = m_flag.width;
nWndSizeV = m_flag.height;
}
#ifdef UPSCALING_FIX
if((unsigned int)nWidth*4<nWndSizeH)
{
nLeftOffset=((nWndSizeH-nWidth*4)>>1);
nWndSizeH=nWidth*4;
}
#endif
m_nDstSizeH = (nWndSizeH>>3)<<3;
m_nDstSizeV = (nWndSizeV>>2)<<2;
if ((pLcdINF->LCTRL & Hw7) == 0) // Not TV Mode
{
if ( m_nDstSizeH > m_nScreenWidth || m_nDstSizeH == 0 )
{
m_nDstSizeH = m_nScreenWidth;
}
if ( m_nDstSizeV > m_nScreenHeight || m_nDstSizeV == 0 )
{
m_nDstSizeV = m_nScreenHeight;
}
}
m_nTop=m_flag.top;
m_nLeft=m_flag.left;
if ((pLcdINF->LCTRL & Hw7) == 0) // Not TV Mode
{
if ( (m_nTop + m_nDstSizeV) > m_nScreenHeight)
{
m_nTop =0;
}
if ( (m_nLeft + m_nDstSizeH) > m_nScreenWidth)
{
m_nLeft =0;
}
}
#ifdef UPSCALING_FIX
m_nLeft+=nLeftOffset;
#endif
if ((pLcdINF->LCTRL & Hw7) == 0) // Not TV Mode
{
if(misEVEN)
{
m_nDstBaseY = m_pScalerMem2;
misEVEN = FALSE;
}
else
{
m_nDstBaseY = m_pScalerMem1;
misEVEN = TRUE;
}
}
else
m_nDstBaseY = m_pScalerMem1; //m_pScalerMem1;
TCC_VideoScale (
(U8 *)pFrame,
nWidth,
nHeight/nType,
3, // 4:2:0 separate mode
nWidth*nType, //type mpeg2 is 2, h264 is 1
(unsigned char*)m_nDstBaseY,
m_nDstSizeH,
m_nDstSizeV,
3, // 4:2:0 separate mode
m_nDstSizeH,
sMSC
,(U8)nHeightOffset // garbage lines due to 16bit alignment output
,(U8)nWidthOffset // garbage pixels due to 16bit alignment output
);
if ((pLcdINF->LCTRL & Hw7) == 0) // Not TV Mode
{
if(m_nScreenWidth > 480) // 800x480 Only
pLcdINF->LCLKDIV = Bak_LCLKDIV + 1; // Half of Window Clock
}
pLcdINF->LI0P = (m_nTop <<16) | (m_nLeft); // position
pLcdINF->LI0S = (m_nDstSizeV<<16) | (m_nDstSizeH); // size
pLcdINF->LI0BA0 = m_nDstBaseY; // base output Y address
pLcdINF->LI0BA1 = pLcdINF->LI0BA0 + (m_nDstSizeV*m_nDstSizeH); // base output U address
pLcdINF->LI0BA2 = pLcdINF->LI0BA1 + ((m_nDstSizeV*m_nDstSizeH)>>2); // base output V address
if(m_flag.mode==2) // alpha blending 25%
{
pLcdINF->LI0C =
HwLIOC_IMG210| //lcayer 2 - 1 - 0
HwLI0C_YUV_420|
HwLI0C_BPP_332; //or YUV
pLcdINF->LK1 = 0x00;
pLcdINF->LK1 |= 1<<24; // alphablend 0(0%),1(25)%,2(50%),3(75%)
m_nRegTemp = pLcdINF->LCTRL & 0x03FFFFF0;
m_nRegTemp |= HwLCTRL_LEN_EN | //[ 0] LCD Controller Enable 0x0A556147 |
// HwLCTRL_Y2R2_EN| //[31] YUV to RGB Channel Converter Enable 2
// HwLCTRL_AEN2_EN| //[30] Alpha Blend Enable 2
// HwLCTRL_CEN2_EN| //[29] Chroma Key Enable 2
// HwLCTRL_Y2R1_EN| //[28] YUV to RGB Channel Converter Enable 1
HwLCTRL_AEN1_EN| //[27] Alpha Blend Enable 1
// HwLCTRL_CEN1_EN| //[26] Chroma Key Enable 1
HwLCTRL_Y2R0_EN| //[25] YUV to RGB Channel Converter Enable 0
// HwLCTRL_IEN2_EN| //[ 3] Fetch Enable 2
HwLCTRL_IEN1_EN| //[ 2] Fetch Enable 1
HwLCTRL_IEN0_EN //[ 1] Fetch Enable 0
;
pLcdINF->LCTRL= m_nRegTemp;
} else if(m_flag.mode==1) // chromakey setting
{
pLcdINF->LI0C =
HwLIOC_IMG210|
HwLI0C_YUV_420|
HwLI0C_BPP_332; //or YUV
pLcdINF->LK1 |= xCHValue;//Chroma key value setting 16,0,16
pLcdINF->LKM1|= 0xFFFFFF;//Chroma key value setting 16,0,16
m_nRegTemp = pLcdINF->LCTRL & 0x03FFFFF0;
m_nRegTemp |= HwLCTRL_LEN_EN | //[ 0] LCD Controller Enable 0x0A556147 |
// HwLCTRL_Y2R2_EN| //[31] YUV to RGB Channel Converter Enable 2
// HwLCTRL_AEN2_EN| //[30] Alpha Blend Enable 2
// HwLCTRL_CEN2_EN| //[29] Chroma Key Enable 2
// HwLCTRL_Y2R1_EN| //[28] YUV to RGB Channel Converter Enable 1
// HwLCTRL_AEN1_EN| //[27] Alpha Blend Enable 1
HwLCTRL_CEN1_EN| //[26] Chroma Key Enable 1
HwLCTRL_Y2R0_EN| //[25] YUV to RGB Channel Converter Enable 0
// HwLCTRL_IEN2_EN| //[ 3] Fetch Enable 2
HwLCTRL_IEN1_EN| //[ 2] Fetch Enable 1
HwLCTRL_IEN0_EN //[ 1] Fetch Enable 0
;
pLcdINF->LCTRL= m_nRegTemp;
}else if(m_flag.mode==3) // chromakey & alpha blending setting
{
pLcdINF->LI0C =
HwLIOC_IMG210|
HwLI0C_YUV_420|
HwLI0C_BPP_332;
pLcdINF->LK1 |= xCHValue;//Chroma key value setting 16,0,16
pLcdINF->LK1 |= 3<<24; // alphablend 0(0%),1(25)%,2(50%),3(75%)
pLcdINF->LKM1 |= 0xFFFFFF;//Chroma key value setting 16,0,16
m_nRegTemp = pLcdINF->LCTRL & 0x03FFFFF0;
m_nRegTemp |= HwLCTRL_LEN_EN | //[ 0] LCD Controller Enable 0x0A556147 |
// HwLCTRL_Y2R2_EN| //[31] YUV to RGB Channel Converter Enable 2
// HwLCTRL_AEN2_EN| //[30] Alpha Blend Enable 2
// HwLCTRL_CEN2_EN| //[29] Chroma Key Enable 2
// HwLCTRL_Y2R1_EN| //[28] YUV to RGB Channel Converter Enable 1
HwLCTRL_AEN1_EN| //[27] Alpha Blend Enable 1
HwLCTRL_CEN1_EN| //[26] Chroma Key Enable 1
HwLCTRL_Y2R0_EN| //[25] YUV to RGB Channel Converter Enable 0
// HwLCTRL_IEN2_EN| //[ 3] Fetch Enable 2
HwLCTRL_IEN1_EN| //[ 2] Fetch Enable 1
HwLCTRL_IEN0_EN //[ 1] Fetch Enable 0
;
pLcdINF->LCTRL= m_nRegTemp;
} else // default (no alpha blending & no chromakey)
{
pLcdINF->LI0C =
HwLI0C_YUV_420|
HwLI0C_BPP_332; //or YUV
m_nRegTemp = pLcdINF->LCTRL & 0x03FFFFF0;
m_nRegTemp |= HwLCTRL_LEN_EN | //[ 0] LCD Controller Enable 0x0A556147 |
// HwLCTRL_Y2R2_EN| //[31] YUV to RGB Channel Converter Enable 2
// HwLCTRL_AEN2_EN| //[30] Alpha Blend Enable 2
// HwLCTRL_CEN2_EN| //[29] Chroma Key Enable 2
// HwLCTRL_Y2R1_EN| //[28] YUV to RGB Channel Converter Enable 1
// HwLCTRL_AEN1_EN| //[27] Alpha Blend Enable 1
// HwLCTRL_CEN1_EN| //[26] Chroma Key Enable 1
HwLCTRL_Y2R0_EN| //[25] YUV to RGB Channel Converter Enable 0
// HwLCTRL_IEN2_EN| //[ 3] Fetch Enable 2
HwLCTRL_IEN1_EN| //[ 2] Fetch Enable 1
HwLCTRL_IEN0_EN //[ 1] Fetch Enable 0
;
pLcdINF->LCTRL= m_nRegTemp;
}
}
//
// DoRenderSample
//
// Have the drawing object render the current image
//
BOOL CVideoRenderer::DoRenderSample(tStRendererType *pRendertp)
{
if( pRendertp->nWidth != 0 && pRendertp->nHeight != 0 )
WriteFrame(pRendertp->pFrame,pRendertp->nWidth, pRendertp->nHeight, pRendertp->nType,pRendertp->nHeightOffset,pRendertp->nWidthOffset);
return TRUE;
} // DoRenderSample
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -