⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tccvrend.cpp

📁 自己在wince的环境下做的一移动数字电视驱动
💻 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 + -