📄 nullpdd.cpp
字号:
PatBlt(hdc, x, y, nBoxWidth, nBoxHeight, BLACKNESS);
// Delete the dc before the bitmap because it's still selected, deleting the dc deselects the bitmap.
if(!DeleteObject(hdc))
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("BufferFill: Failed to delete allocated DC\r\n"))) ;
return -1;
}
}
if(!DeleteObject(hbmp))
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("BufferFill: Failed to delete allocated bitmap\r\n"))) ;
return -1;
}
}
else
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("BufferFill: OOM or unrecognized format\r\n"))) ;
return -1;
}
// return the size of the image filled
return(biSizeImage);
}
DWORD CNullPdd::YUVBufferFill( ULONG ulModeType, PUCHAR pImage )
{
PCS_VIDEOINFOHEADER pCsVideoInfoHdr = &m_pCurrentFormat[ulModeType].VideoInfoHeader;
UINT biWidth = pCsVideoInfoHdr->bmiHeader.biWidth;
UINT biHeight = abs(pCsVideoInfoHdr->bmiHeader.biHeight);
UINT biSizeImage = pCsVideoInfoHdr->bmiHeader.biSizeImage;
DWORD biCompression = pCsVideoInfoHdr->bmiHeader.biCompression;
biCompression &= ~BI_SRCPREROTATE;
if ( ( FOURCC_YUY2 != biCompression ) &&
( FOURCC_YV12 != biCompression ) )
{
return -1;
}
// make the box width/height 1/8th of the screen, so it's visible but doesn't
// overwhelm
UINT uiBoxWidth = biWidth/BOXWIDTHDIVIDER;
UINT uiBoxHeight = biHeight/BOXHEIGHTDIVIDER;
float fWidthStep = (float) (biWidth - uiBoxWidth)/LOCATIONWIDTHMASK;
float fHeightStep = (float) (biHeight - uiBoxHeight)/LOCATIONHEIGHTMASK;
UINT x, y;
UINT uiTickCount;
UINT uiDirection;
UINT uiLocationX, uiLocationY;
uiTickCount = GetTickCount() >> SPEEDSHIFT;
// and the result with 0x3 so the value ranges between 0 and 3 for the direction.
uiDirection = (uiTickCount >> LOCATIONSHIFT) & 0x3;
uiLocationX = static_cast<UINT>(fWidthStep * (uiTickCount & LOCATIONWIDTHMASK));
uiLocationY = static_cast<UINT>(fHeightStep * (uiTickCount & LOCATIONHEIGHTMASK));
switch (uiDirection)
{
case 0:
x = uiLocationX;
y = 0;
break;
case 1:
x = biWidth - uiBoxWidth;
y = uiLocationY;
break;
case 2:
x = (biWidth - uiBoxWidth) - uiLocationX;
y = biHeight - uiBoxHeight;
break;
case 3:
x = 0;
y = (biHeight - uiBoxHeight) - uiLocationY;
break;
}
if (MAKEFOURCC('Y','V','1','2') == biCompression )
{
UINT uiStride = (2 * biSizeImage) / (3 * biHeight);
UINT uiDelta = uiStride-biWidth;
UINT uiSizeYPlane = uiStride * biHeight;
UINT uiHalfStride = uiStride >> 1;
UINT uiHalfWidth = biWidth >> 1;
UINT uiHalfDelta = uiHalfStride - uiHalfWidth;
// 1. Make the entire image white.
// Y plane
for (UINT i = 0; i < uiSizeYPlane; i += uiStride)
{
memset(&pImage[i], Y_WHITE, biWidth);
memset(&pImage[i+biWidth], 0, uiDelta);
}
// V & U planes
for (; i < biSizeImage; i += uiHalfStride)
{
memset(&pImage[i], VU_BOTH, uiHalfWidth);
memset(&pImage[i+uiHalfWidth], 0, uiHalfDelta);
}
// 2. Add the black square. Since the chroma (V & U) values are the same
// for both black and white, we only have to touch the luma (Y) plane.
UINT uiBound = ((y + uiBoxHeight) * uiStride) + (x + uiBoxWidth);
for (i = (y * uiStride) + x; i < uiBound; i += uiStride)
{
memset(&pImage[i], Y_BLACK, uiBoxWidth);
}
}
else if (MAKEFOURCC('Y','U','Y','2') == biCompression )
{
UINT uiStrideDWORD = (biSizeImage / biHeight) / sizeof(DWORD);
UINT uiWidthDWORD = biWidth / 2;
UINT uiDeltaDWORD = uiStrideDWORD - uiWidthDWORD;
// upcast should be safe because images are dword aligned
DWORD* pdwImage = reinterpret_cast<DWORD*>(pImage);
ASSERT(pdwImage);
if (!pdwImage)
{
return 0;
}
// paint the background color first
for (UINT i = 0; i < biHeight; i++)
{
for (UINT j = 0; j < uiWidthDWORD; j++)
#if 0
*pdwImage++ = MACROPIXEL_WHITE;
#else
*pdwImage++ = MACROPIXEL_RED;
#endif
for (j = 0; j < uiDeltaDWORD; j++)
*pdwImage++ = 0;
}
// then add the square
UINT uiBoundDWORD = ((y + uiBoxHeight) * uiStrideDWORD) + ((x + uiBoxWidth) / 2);
UINT uiBoxWidthDWORD = uiBoxWidth / 2;
pdwImage = reinterpret_cast<DWORD*>(pImage);
pdwImage += (y * uiStrideDWORD) + (x / 2);
for (i = 0; i < uiBoxHeight; i++)
{
for (UINT j = 0; j < uiBoxWidthDWORD; j++)
#if 0
*pdwImage++ = MACROPIXEL_BLACK;
#else
*pdwImage++ = MACROPIXEL_GRN;
#endif
pdwImage += (uiStrideDWORD - uiBoxWidthDWORD);
}
}
return(biSizeImage);
}
bool CNullPdd :: CreateTimer( ULONG ulModeType )
{
if ( NULL == m_hTimerDll )
{
m_hTimerDll = LoadLibrary( L"MMTimer.dll" );
m_pfnTimeSetEvent = (FNTIMESETEVENT)GetProcAddress( m_hTimerDll, L"timeSetEvent" );
m_pfnTimeKillEvent = (FNTIMEKILLEVENT)GetProcAddress( m_hTimerDll, L"timeKillEvent" );
if ( NULL == m_pfnTimeSetEvent || NULL == m_pfnTimeKillEvent )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): GetProcAddress Returned Null.\r\n"), this));
return false;
}
}
if ( NULL == m_hTimerDll )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): LoadLibrary failedr.\r\n"), this));
return false;
}
ASSERT( m_pfnTimeSetEvent );
if ( NULL == m_TimerIdentifier[ulModeType] )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): Creating new timer.\r\n"), this));
if( STILL == ulModeType )
{
m_TimerIdentifier[ulModeType] = m_pfnTimeSetEvent( (ULONG)m_pCurrentFormat[ulModeType].VideoInfoHeader.AvgTimePerFrame/10000, 10, CNullPdd::StillTimerCallBack, reinterpret_cast<DWORD>(this), TIME_PERIODIC|TIME_CALLBACK_FUNCTION);
}
else
{
m_TimerIdentifier[ulModeType] = m_pfnTimeSetEvent( (ULONG)m_pCurrentFormat[ulModeType].VideoInfoHeader.AvgTimePerFrame/10000, 10, CNullPdd::CaptureTimerCallBack, reinterpret_cast<DWORD>(this), TIME_PERIODIC|TIME_CALLBACK_FUNCTION);
}
if ( NULL == m_TimerIdentifier[ulModeType] )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): Timer could not be created.\r\n"), this));
return false;
}
}
else
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): Timer already created.\r\n"), this));
}
return true;
}
void CNullPdd :: CaptureTimerCallBack( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 )
{
UNREFERENCED_PARAMETER(uTimerID) ;
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(dw1);
UNREFERENCED_PARAMETER(dw2);
CNullPdd *pNullPdd= reinterpret_cast<CNullPdd *>(dwUser);
if( NULL == pNullPdd )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack pNullPdd is NULL.\r\n"))) ;
}
else
{
__try
{
pNullPdd->HandleCaptureInterrupt( uTimerID );
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack, Access violation.\r\n"))) ;
}
}
}
void CNullPdd :: StillTimerCallBack( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 )
{
UNREFERENCED_PARAMETER(uTimerID) ;
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(dw1);
UNREFERENCED_PARAMETER(dw2);
CNullPdd *pNullPdd= reinterpret_cast<CNullPdd *>(dwUser);
if( NULL == pNullPdd )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack pNullPdd is NULL.\r\n"))) ;
}
else
{
__try
{
pNullPdd->HandleStillInterrupt( uTimerID );
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack, Access violation.\r\n"))) ;
}
}
}
void CNullPdd :: HandleCaptureInterrupt( UINT uTimerID )
{
ULONG ulModeType;
if( m_bStillCapInProgress )
{
return;
}
if( m_TimerIdentifier[CAPTURE] == uTimerID )
{
ulModeType = CAPTURE;
}
else if ( m_ulCTypes == 3 && m_TimerIdentifier[PREVIEW] == uTimerID )
{
ulModeType = PREVIEW;
}
else
{
ASSERT(false);
return;
}
MDD_HandleIO( m_ppModeContext[ulModeType], ulModeType );
}
void CNullPdd :: HandleStillInterrupt( UINT uTimerID )
{
MDD_HandleIO( m_ppModeContext[STILL], STILL );
m_bStillCapInProgress = false;
}
bool CNullPdd::ReadMemoryModelFromRegistry()
{
HKEY hKey = 0;
DWORD dwType = 0;
DWORD dwSize = sizeof ( DWORD );
DWORD dwValue = -1;
if( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"Drivers\\Capture\\SampleCam", 0, 0, &hKey ))
{
false;
}
if( ERROR_SUCCESS == RegQueryValueEx( hKey, L"MemoryModel", 0, &dwType, (BYTE *)&dwValue, &dwSize ) )
{
if( ( REG_DWORD == dwType )
&& ( sizeof( DWORD ) == dwSize )
&& (( dwValue == CSPROPERTY_BUFFER_DRIVER ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_LIMITED ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_UNLIMITED )))
{
for( int i=0; i<MAX_SUPPORTED_PINS ; i++ )
{
m_SensorModeInfo[i].MemoryModel = (CSPROPERTY_BUFFER_MODE) dwValue;
}
}
}
// Find out if we should be using some other number of supported modes. The only
// valid options are 2 or 3. Default to 2.
if ( ERROR_SUCCESS == RegQueryValueEx( hKey, L"PinCount", 0, &dwType, (BYTE *)&dwValue, &dwSize ) )
{
if ( REG_DWORD == dwType
&& sizeof ( DWORD ) == dwSize
&& 3 == dwValue )
{
m_ulCTypes = 3;
}
}
RegCloseKey( hKey );
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -