📄 halvpe.cpp
字号:
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 + -