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

📄 halvpe.cpp

📁 SM501基于ARMV4/ARMV4I平台
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, HREF_PHASE, ACTIVE_LOW);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, VSYNC_PHASE, ACTIVE_HIGH);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, FIELD_DETECT, FALLING);
			break;
		case VPE_PHILIPS_SAA7118_8:
			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - VPE_PHILIPS_SAA7118_8\r\n")));
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, HREF_PHASE, ACTIVE_LOW);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, VSYNC_PHASE, ACTIVE_LOW);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, FIELD_DETECT, FALLING);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, CAPTURE_SIZE, 8);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, CLOCK_POLARITY, ACTIVE_LOW);
 			break;
		case VPE_PHILIPS_SAA7118_16:
			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - VPE_PHILIPS_SAA7118_16\r\n")));
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, HREF_PHASE, ACTIVE_LOW);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, VSYNC_PHASE, ACTIVE_LOW);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, FIELD_DETECT, FALLING);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, CLOCK_POLARITY, ACTIVE_LOW);
			break;
		default:
			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - Bad GUID\r\n")));
			break;
	}


    DDPIXELFORMAT *lppfInputFormat = pd->lpVideoInfo->lpddpfInputFormat;
    if (lppfInputFormat->dwFlags == DDPF_RGB) 
    {
		// for RGB, need to find 5-6-5 or 5-5-5
        if (lppfInputFormat->dwRBitMask==(DWORD)0xF800 && 
            lppfInputFormat->dwGBitMask==(DWORD)0x07E0 &&
            lppfInputFormat->dwBBitMask==(DWORD)0x001F )
        {
			// 5-6-5 RGB format
			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - 565 format\r\n")));
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, CAPTURE_FORMAT, RGB);
        }
    }
    else if (lppfInputFormat->dwFlags == DDPF_FOURCC) 
	{
		// for FourCC, need to find YUY2 OR UYVY.
        if (lppfInputFormat->dwFourCC == mmioFOURCC('Y','U','Y','V'))
        {
			// YUV
			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - YUY2 format\r\n")));
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, CAPTURE_FORMAT, YUV);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, UV_SWAP, DISABLE);
        }
        else
        {
            // UYVY
   			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - YUY2 format\r\n")));
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, CAPTURE_FORMAT, YUV);
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, UV_SWAP, ENABLE);
		}
	}
	else 
	{
		DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - Bad pixel format\r\n")));
	}

	DWORD DstOfs = pDstSurfGbl->fpVidMem - (DWORD)g_pVideoMemory;
	// adjust src ptr
    DstOfs += pd->lpVideoInfo->dwOriginX * wDstBytePP;
	DstOfs += pd->lpVideoInfo->dwOriginY * wDstPitch;

	// The purpose of the following code is to clear VPE surface
	// when VPE is updated first time
	if (bVPEFirstTime)
	{
		// Maybe we should account for dest surface rectangles
		int nSize = (pDstSurfGbl->wHeight * wDstPitch) >> 2;	// DWORD size
		DWORD *lpAddr = (LPDWORD) pDstSurfGbl->fpVidMem; 
        while (nSize--)
			*lpAddr++ = 0x80108010; // this is the YUYV value equivalent to BLACK RGB=0.

		if (!bDoubleBuffer)
			bVPEFirstTime = FALSE;
	}

	// Buffer 1 source address
	DWORD lastDstOfs = DstOfs;
	((SMI *)g_pGPE)->VPE_SetDst(DstOfs);
	
	if (bDoubleBuffer)
	{
	    /*
	    ** If hardware double buffering, set base address
	    ** for second buffer
	    */
		DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - Hardware Double Buffer\r\n")));

		DWORD DstOfs2;
	    DstOfs2 = pd->lplpDDSurface[1]->lpLcl->lpGbl->fpVidMem - (DWORD)g_pVideoMemory;
	    DstOfs2 += pd->lpVideoInfo->dwOriginX * wDstBytePP;
		DstOfs2 += pd->lpVideoInfo->dwOriginY * wDstPitch;

		// Again clean the VPE second buffer for the first time
		if (bVPEFirstTime)
		{
			// Maybe we should account for dest surface rectangles
			int nSize = (pd->lplpDDSurface[1]->lpLcl->lpGbl->wHeight * 
						 pd->lplpDDSurface[1]->lpLcl->lpGbl->lPitch) >> 2;	// DWORD size
			DWORD *lpAddr = (LPDWORD) pd->lplpDDSurface[1]->lpLcl->lpGbl->fpVidMem; 
	        while (nSize--)
				*lpAddr++ = 0x80108010; // this is the YUYV value equivalent to BLACK RGB=0.

			bVPEFirstTime = FALSE;
		}

		lastDstOfs = DstOfs2;
		((SMI *)g_pGPE)->VPE_SetDst2(DstOfs2);
		dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, DOUBLE_BUFFERING, ENABLE);

		//Enable Capture Video as the Overlay Video window
		((SMI *)g_pGPE)->VPE_EnableOverlayWindow(DstOfs2);

		// For SMI 710, 712, 720, 820
		// Interlace double buffer can turn on bob mode
        if (pd->lpVideoPort->ddvpDesc.VideoPortType.dwFlags & DDVPCONNECT_INTERLACED) 
        {
   			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - BOB mode set\r\n")));
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, INTERLACE_BOB, ENABLE);			
			((SMI *)g_pGPE)->VPE_EnableBOB();
        }
	}

    DWORD dwSrcPixelWidth, dwDstPixelWidth;
    DWORD dwSrcHeight, dwDstHeight;

	dwSrcPixelWidth = (pd->lpVideoInfo->dwVPFlags & DDVP_CROP) ?
						(pd->lpVideoInfo->rCrop.right - pd->lpVideoInfo->rCrop.left) : 
						pd->lpVideoPort->ddvpDesc.dwFieldWidth; 
	dwSrcHeight = (pd->lpVideoInfo->dwVPFlags & DDVP_CROP) ?
					(pd->lpVideoInfo->rCrop.bottom - pd->lpVideoInfo->rCrop.top) :
					pd->lpVideoPort->ddvpDesc.dwFieldHeight;

	DEBUGMSG(GPE_ZONE_VPE,(TEXT("Source Width = %ld\r\n"),dwSrcPixelWidth));
	DEBUGMSG(GPE_ZONE_VPE,(TEXT("Source Height = %ld\r\n"),dwSrcHeight));

	// capture size
	((SMI *)g_pGPE)->VPE_SetCaptureSize(dwSrcPixelWidth,dwSrcHeight);

	if (bVPEWeave) 
	{
		DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - Weave mode set\r\n")));

		((SMI *)g_pGPE)->VPE_SetDst2(lastDstOfs);

		dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, DOUBLE_BUFFERING, ENABLE);           
		dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, INTERLACE_WEAVE, ENABLE);
            
	}

	// source offset in 64 bit boundary
	((SMI *)g_pGPE)->VPE_SetStride((DWORD)wDstPitch);

    if (pd->lpVideoInfo->dwVPFlags & DDVP_PRESCALE)
	{
		DWORD dwXScale, dwYScale;
            
        dwDstPixelWidth = pd->lpVideoInfo->dwPrescaleWidth;
        dwDstHeight= pd->lpVideoInfo->dwPrescaleHeight;

		DEBUGMSG(GPE_ZONE_VPE,(TEXT("dwPrescaleWidth = %ld\r\n"),dwDstPixelWidth));
		DEBUGMSG(GPE_ZONE_VPE,(TEXT("dwPrescaleHeight = %ld\r\n"),dwDstHeight));

        dwXScale = 0;
        dwYScale = 0;
        while (dwSrcPixelWidth > dwDstPixelWidth) {
            dwSrcPixelWidth >>= 1;
            dwXScale ++;
        }
        while (dwSrcHeight > dwDstHeight) {
            dwSrcHeight >>= 1;
            dwYScale ++;
        }
        
		// This is used to limit the XScale & YScale to 2 or less
        if (dwXScale > 1)
		{
			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - DDVP_PRESCALE Set, dwPrescaleWidth too SMALL!\r\n")));
			pd->ddRVal = DDERR_UNSUPPORTED;
			return DDHAL_DRIVER_HANDLED;
		}
        if (dwYScale > 1)
		{
			DEBUGMSG(GPE_ZONE_VPE,(TEXT("SMI::HalUpdateVideoPort - DDVP_PRESCALE Set, dwPrescaleHeight too SMALL!\r\n")));
			pd->ddRVal = DDERR_UNSUPPORTED;
			return DDHAL_DRIVER_HANDLED;
		}

		if (dwXScale > 0)
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, 2TO1_HORIZONTAL_SHRINK, ENABLE);
		if (dwYScale > 0)
			dwMode = FIELD_SET(dwMode, CAPTURE_CONTROL, 2TO1_VERTICAL_SHRINK, ENABLE);
		
	}

	if (pd->lpVideoInfo->dwVPFlags & DDVP_CROP)
	{
		DEBUGMSG(GPE_ZONE_VPE,(TEXT("Crop.left = %ld\r\n"),pd->lpVideoInfo->rCrop.left));
		DEBUGMSG(GPE_ZONE_VPE,(TEXT("Crop.Top = %ld\r\n"),pd->lpVideoInfo->rCrop.top));

        // capture cropping
		((SMI *)g_pGPE)->VPE_SetCropSize((DWORD)pd->lpVideoInfo->rCrop.left,
										(DWORD)pd->lpVideoInfo->rCrop.top);

    }

	// Need to Swap Video 0 and 1 Address
	//

	// Set CPR00 all bits except bit 0
	((SMI *)g_pGPE)->VPE_SetVPEMode(dwMode);
        
    // do a dummy read for CPR00
	((SMI *)g_pGPE)->VPE_GetVPEMode();
        
    // Finally, turn on zv port.
	((SMI *)g_pGPE)->VPE_Enable();
        
	pd->ddRVal = DD_OK;
	return DDHAL_DRIVER_HANDLED;
};

// Hardware functions

// Disable VPE
void SMI::VPE_Disable(void)
{
	DWORD gate = FIELD_SET(0, CURRENT_POWER_GATE, ZVPORT, ENABLE);

	POKE_32(CAPTURE_CONTROL,FIELD_SET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, CAPTURE, DISABLE));

	VPE_DisableInterrupt();
	// Disable gate
	setGate(gate, 0);
}

// Enable VPE
void SMI::VPE_Enable(void)
{
	//DWORD gate = FIELD_SET(0, CURRENT_POWER_GATE, ZVPORT, ENABLE);

	// Enable gate
	//setGate(gate, gate);

	POKE_32(CAPTURE_CONTROL,FIELD_SET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, CAPTURE, ENABLE));

	WaitForVBlank();
	WaitForVBlank();
	WaitForVBlank();
	WaitForVBlank();
	WaitForVBlank();

	VPE_InitInterrupt();
}

// Get VPE hardware status
DWORD SMI::VPE_GetVPEMode(void)
{
	DWORD dwMode = PEEK_32(CAPTURE_CONTROL);
	return dwMode;
}

// Set VPE hardware status
void SMI::VPE_SetVPEMode(DWORD dwMode)
{
	POKE_32(CAPTURE_CONTROL,dwMode);
}

// Check Vsync status
BOOL SMI::VPE_IsVsync(void)
{
	BOOL bVsync = (FIELD_GET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, VSYNC) == CAPTURE_CONTROL_VSYNC_ACTIVE);
	return bVsync;
}

// Check VPE enable status
BOOL SMI::VPE_IsEnable(void)
{
	BOOL bEnable = (FIELD_GET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, CAPTURE) == CAPTURE_CONTROL_CAPTURE_ENABLE);
	return bEnable;
}

// Check Even Field status
BOOL SMI::VPE_IsEvenField(void)
{
	BOOL bEven = (FIELD_GET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, FIELD) == CAPTURE_CONTROL_FIELD_EVEN);
	return bEven;
}

// Set Buffer I address
void SMI::VPE_SetDst(DWORD dwBase)
{
	POKE_32(CAPTURE_BUFFER_0_ADDRESS,
		FIELD_SET(0, CAPTURE_BUFFER_0_ADDRESS, STATUS, CURRENT) |
		FIELD_VALUE(0, CAPTURE_BUFFER_0_ADDRESS, EXT, m_SMISettings.m_bUMA) |
		FIELD_VALUE(0, CAPTURE_BUFFER_0_ADDRESS, ADDRESS, VgxSurfAddr(dwBase)) |
		0);
}

// Set Buffer II address
void SMI::VPE_SetDst2(DWORD dwBase)
{
	POKE_32(CAPTURE_BUFFER_1_ADDRESS,
		FIELD_SET(0, CAPTURE_BUFFER_1_ADDRESS, STATUS, CURRENT) |
		FIELD_VALUE(0, CAPTURE_BUFFER_1_ADDRESS, EXT, m_SMISettings.m_bUMA) |
		FIELD_VALUE(0, CAPTURE_BUFFER_1_ADDRESS, ADDRESS, VgxSurfAddr(dwBase)) |
		0);
}

// Get Buffer I address
DWORD SMI::VPE_GetDst(void)
{
	DWORD dwBase = FIELD_GET(PEEK_32(CAPTURE_BUFFER_0_ADDRESS), CAPTURE_BUFFER_0_ADDRESS, ADDRESS);
	return dwBase;
}

// Set Capture Size
void SMI::VPE_SetCaptureSize(DWORD dwWidth, DWORD dwHeight)
{
	POKE_32(CAPTURE_SIZE,
		FIELD_VALUE(0, CAPTURE_SIZE, HEIGHT, dwHeight) |
		FIELD_VALUE(0, CAPTURE_SIZE, WIDTH, dwWidth) |
		0);
}

// Set Capture stride
void SMI::VPE_SetStride(DWORD dwStride)
{
	POKE_32(CAPTURE_BUFFER_OFFSET,
		FIELD_VALUE(0, CAPTURE_BUFFER_OFFSET, OFFSET, dwStride) |
		0);
}

// Set Crop size
void SMI::VPE_SetCropSize(DWORD dwLeft, DWORD dwTop)
{
	POKE_32(CAPTURE_CLIPPING,
		FIELD_VALUE(0, CAPTURE_CLIPPING, YCLIP, dwTop) |
		FIELD_VALUE(0, CAPTURE_CLIPPING, XCLIP, dwLeft) |
		0);
}

// Set Overlay Video I address to Capture Video Buffer I address
void SMI::VPE_EnableOverlayWindow(DWORD dwDstOfs2)
{

	POKE_32(VIDEO_FB_1_ADDRESS, 
		FIELD_SET(0, VIDEO_FB_1_ADDRESS, STATUS, PENDING) |
		FIELD_VALUE(0, VIDEO_FB_1_ADDRESS, EXT, m_SMISettings.m_bUMA) |
		FIELD_VALUE(0, VIDEO_FB_1_ADDRESS, ADDRESS, VgxSurfAddr(dwDstOfs2)) |
		0);

	POKE_32(VIDEO_FB_1_LAST_ADDRESS, 
		FIELD_VALUE(0, VIDEO_FB_1_LAST_ADDRESS, EXT, m_SMISettings.m_bUMA) |
		FIELD_VALUE(0, VIDEO_FB_1_LAST_ADDRESS, ADDRESS, 0x03FFFFFF) |
		0);

	POKE_32(VIDEO_DISPLAY_CTRL,	FIELD_SET(PEEK_32(VIDEO_DISPLAY_CTRL), VIDEO_DISPLAY_CTRL, CAPTURE, ENABLE));
}

// Set Overlay Video I address to standard address
void SMI::VPE_DisableOverlayWindow(void)
{

	POKE_32(VIDEO_DISPLAY_CTRL,	
		FIELD_SET(PEEK_32(VIDEO_DISPLAY_CTRL), VIDEO_DISPLAY_CTRL, CAPTURE, DISABLE));
}

// Enable BOB
void SMI::VPE_EnableBOB(void)
{
	POKE_32(VIDEO_INITIAL_SCALE, 
		FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_1, 0x800) |
		FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_0, 0x0) |
		0);
}

// Disable BOB
void SMI::VPE_DisableBOB(void)
{
	POKE_32(VIDEO_INITIAL_SCALE, 
		FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_1, 0) |
		FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_0, 0) |
		0);
}

// Enable byte swapping for YUV data
void SMI::VPE_EnableByteSwap(void)
{
    POKE_32(CAPTURE_CONTROL,
        FIELD_SET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, BYTE_SWAP, ENABLE));
}

// Disable byte swapping for YUV data
void SMI::VPE_DisableByteSwap(void)
{
    POKE_32(CAPTURE_CONTROL,
        FIELD_SET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, BYTE_SWAP, DISABLE));
}

// Enable Field Swap
void SMI::VPE_EnableFieldSwap(void)
{
    POKE_32(CAPTURE_CONTROL,
        FIELD_SET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, FIELD_SWAP, ENABLE));
}

// Disable Field Swap
void SMI::VPE_DisableFieldSwap(void)
{
    POKE_32(CAPTURE_CONTROL,
        FIELD_SET(PEEK_32(CAPTURE_CONTROL), CAPTURE_CONTROL, FIELD_SWAP, DISABLE));
}

// Enable/Disable cap

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -