📄 webcam.cpp
字号:
if (pGetFrStruct->dwFlags & GETFRAMEFLAG_PURGEOLDERFRAMES)
dwFrameFlags |= FRAME_PURGEOLD;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception reading GETFRAMESTRUCT structure\r\n")));
return ERROR_INVALID_PARAMETER;
}
// Don't allow another call to GetNextFrame while we're waiting
pDrv->fBusy = TRUE;
// Get the data, first leave the driver CS. since this can block.
LeaveCriticalSection (&pDrv->csDCall);
__try
{
rc = pdd_GetNextVideoFrame (pDrv, ppFrameBuff, &dwFrameBytes,
&dwValidFrames, pFrameRet, dwTimeout, dwFrameFlags);
}
__finally
{
EnterCriticalSection (&pDrv->csDCall);
pDrv->fBusy = FALSE;
}
if (rc == 0)
{
// Write to the output structure
__try
{
pGetFrStructOut->dwMissedFrames = dwValidFrames;
pGetFrStructOut->pFrameData = pFrameBuff;
pGetFrStructOut->dwFrameSize = dwFrameBytes;
*pdwBytesWritten = sizeof (GETFRAMESTRUCTOUT);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing output data.\r\n")));
rc = ERROR_INVALID_PARAMETER;
}
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetNextVideoFrame-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_GetCurrentFormat - Called to process IOCTL_CAMERA_DEVICE_GETCURRENVIDEOFORMAT ioctl
//
int mdd_GetCurrentFormat (PDRVCONTEXT pDrv, PBYTE pOut, DWORD dwOut, PDWORD pdwBytesWritten)
{
int rc;
FORMATPROPS Props;
PFORMATPROPS pPropsOut;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetCurrentFormat++\r\n")));
if (!pOut || (dwOut < sizeof (FORMATPROPS)) || !pdwBytesWritten)
return ERROR_INVALID_PARAMETER;
// Write to the output structure
__try
{
*pdwBytesWritten = 0;
pPropsOut = (PFORMATPROPS)pOut;
if (pPropsOut->cbSize != sizeof (FORMATPROPS))
{
DEBUGMSG (ZONE_ERROR, (TEXT("Bad structure size\r\n")));
rc = ERROR_INVALID_PARAMETER;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing output data.\r\n")));
rc = ERROR_INVALID_PARAMETER;
}
rc = pdd_GetCurrentFormat (pDrv, &Props);
if (rc == 0)
{
// Write to the output structure
__try
{
*pPropsOut = Props;
*pdwBytesWritten = sizeof (FORMATPROPS);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing output data.\r\n")));
rc = ERROR_INVALID_PARAMETER;
}
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetCurrentFormat-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_StopVideoStream - Called to process IOCTL_CAMERA_DEVICE_STOPVIDEOSTREAM ioctl
//
int mdd_StopVideoStream (PDRVCONTEXT pDrv)
{
int rc;
// Stop the stream
rc = pdd_StopVidStream (pDrv);
// If we allocated the frame buffer, free it,
if (pDrv->mmFrameBuff.p)
{
// Free up the current frame buffer
FreeSharedObject (&pDrv->mmFrameBuff);
pDrv->mmFrameBuff.p = 0;
}
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_QueryStillFormats - Returns the supported still image formats
//
int mdd_QueryStillFormats (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut,
PDWORD pdwBytesWritten)
{
int i, rc = 0;
FORMATPROPS Props;
DWORD dwStillFmt, dwBytes = 0;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_QueryStillFormats++\r\n")));
// Check parameters
if (!pIn || (dwIn < sizeof (DWORD)) || !pdwBytesWritten)
ERROR_INVALID_PARAMETER;
// Get the format the app wants
__try {
dwStillFmt = *pIn;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return ERROR_INVALID_PARAMETER;
}
// Format is actually a byte paramter
if (dwStillFmt > 255)
return ERROR_INVALID_PARAMETER;
PFORMATPROPS pOutFmtProps = (PFORMATPROPS)pOut;
// See if we're currently streaming
rc = pdd_GetCurrentFormat (pDrv, &Props);
// Yes, we're streaming, just return the current format
if (rc == 0)
{
// Write it to the app. but only if they provided an output pointer
if (pOutFmtProps)
{
__try
{
pOutFmtProps[0] = Props;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing to output buffer\r\n")));
rc = ERROR_INVALID_PARAMETER;
}
}
dwBytes += sizeof (FORMATPROPS);
}
else
{
// If not streaming, all formats are available
// Get the number of frame sizes for the format
for (i = 0, rc = 0; (i < 255) && (rc == 0); i++)
{
rc = pdd_GetFormatParameters (pDrv, (BYTE)dwStillFmt, (BYTE)i+1, FALSE, &Props);
// if no more frame sizes, break
if (rc)
{
rc = 0;
break;
}
// Write it to the app. but only if they provided an output pointer
if (pOutFmtProps)
{
__try
{
pOutFmtProps[i] = Props;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing to output buffer\r\n")));
rc = ERROR_INVALID_PARAMETER;
break;
}
}
dwBytes += sizeof (FORMATPROPS);
}
}
// Write the number of bytes written
__try
{
*pdwBytesWritten = dwBytes;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing pdwBytesWritten\r\n")));
rc = ERROR_INVALID_PARAMETER;
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_QueryStillFormats-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_GetStillImage
//
int mdd_GetStillImage (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut,
PDWORD pdwBytesWritten)
{
int rc, nFrameIndex, nFormatIndex;
FORMATPROPS Props;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetStillImage++\r\n")));
if (!pIn || !pdwBytesWritten || (dwIn < sizeof(VIDFORMATSTRUCT)))
return ERROR_INVALID_PARAMETER;
PVIDFORMATSTRUCT pVid = (PVIDFORMATSTRUCT)pIn;
__try
{
if (pVid->cbSize != sizeof (VIDFORMATSTRUCT))
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Size field of VIDFORMATSTRUCT not set\r\n")));
return ERROR_INVALID_PARAMETER;
}
nFormatIndex = pVid->wFormatIndex;
nFrameIndex = pVid->wFrameIndex;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception reading VIDFORMATSTRUCT structure\r\n")));
return ERROR_INVALID_PARAMETER;
}
// See if currently streaming. If so, the format and frame must match the
// current stream.
rc = pdd_GetCurrentFormat (pDrv, &Props);
// Yes, we're streaming, just return the current format
if (rc == 0)
{
if ((nFormatIndex != Props.wFormatIndex) || (nFrameIndex != Props.wFrameIndex))
{
DEBUGMSG (ZONE_ERROR, (TEXT("Can only get still if format matches current stream\r\n")));
return ERROR_BUSY;
}
}
// Verify that the output buffer is large enough
rc = pdd_GetFormatParameters (pDrv, nFormatIndex, nFrameIndex, FALSE, &Props);
if (rc)
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Bad still format requested %d\r\n"), nFrameIndex));
return ERROR_INVALID_PARAMETER;
}
// See if they're just asking for the buffer size...
if (pOut == 0)
{
__try
{
*pdwBytesWritten = Props.dwMaxBuff;
return 0;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing pdwBytesWritten\r\n")));
return ERROR_INVALID_PARAMETER;
}
}
// See if output buffer is big enough
if (dwOut < Props.dwMaxBuff)
return ERROR_NOT_ENOUGH_MEMORY;
// Call the PDD to get the image. Since we're directly accessing the
// callers buffer here, protect with a try/except
__try
{
rc = pdd_GetStillImage (pDrv, nFrameIndex, nFormatIndex, pOut, dwOut, pdwBytesWritten);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing to output buffer\r\n")));
return ERROR_INVALID_PARAMETER;
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetStillImage-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_WaitOnCameraEvent - Waits on events within the driver.
//
int mdd_WaitOnCameraEvent (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut,
PDWORD pdwBytesWritten)
{
int rc;
DWORD dwWaitMask, dwTimeout, dwEventReason;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_WaitOnCameraEvent++\r\n")));
if (!pIn || !pOut || !pdwBytesWritten ||
(dwIn < sizeof(WAITEVENTSTUCT)) || (dwIn < sizeof(DWORD)))
return ERROR_INVALID_PARAMETER;
// Get the data from the input buffer
PWAITEVENTSTUCT pWait = (PWAITEVENTSTUCT)pIn;
__try
{
if (pWait->cbSize != sizeof (WAITEVENTSTUCT))
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Size field of WAITEVENTSTUCT not set\r\n")));
return ERROR_INVALID_PARAMETER;
}
dwWaitMask = pWait->dwWaitMask;
dwTimeout = pWait->dwTimeout;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception reading WAITEVENTSTUCT structure\r\n")));
return ERROR_INVALID_PARAMETER;
}
// See if we can write to the output buffer
__try
{
DWORD dwTest = *(DWORD *)pOut;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception reading output buffer\r\n")));
return ERROR_INVALID_PARAMETER;
}
// Validate the wait flags
if ((dwWaitMask & ~(WAITCAM_NEWFRAME /* & WAITCAM_BUTTONPRESS */)) != 0)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Invalid wait flags passed\r\n")));
return ERROR_INVALID_PARAMETER;
}
// Call the PDD to wait, first leave the driver CS. since this can block.
LeaveCriticalSection (&pDrv->csDCall);
__try
{
rc = pdd_WaitOnCameraEvent (pDrv, dwWaitMask, dwTimeout, &dwEventReason);
}
__finally
{
EnterCriticalSection (&pDrv->csDCall);
}
// Write the results to the output buffer
__try
{
*(DWORD *)pOut = dwEventReason;
*pdwBytesWritten = sizeof (DWORD);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing output buffer\r\n")));
return ERROR_INVALID_PARAMETER;
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_WaitOnCameraEvent-- rc %d\r\n"),rc));
return rc;
}
//----------------------------------------------------------------------
// AllocSharedObject - Allocates a memory mapped object
//
int AllocSharedObject (int nSize, PMMOBJSTRUCT obj)
{
if ((obj == 0) || (nSize == 0))
return ERROR_INVALID_PARAMETER;
// For 6.0, we can't use a Shared MM object any more. Use the shared
// heap. Its R/W from the driver and R/O for the app, but that's fine.
#if (_WIN32_WCE >= 600)
obj->p = (PBYTE) CeVirtualSharedAlloc (NULL, nSize, MEM_COMMIT|MEM_RESERVE);
#else
obj->h = CreateFileMapping ((HANDLE)-1, NULL, PAGE_READWRITE | SEC_COMMIT,
0, nSize, NULL);
if (obj->h == 0)
return GetLastError();
obj->p = (PBYTE)MapViewOfFile (obj->h, FILE_MAP_WRITE, 0, 0, 0);
if (obj->h == 0)
{
CloseHandle (obj->h);
return GetLastError();
}
#endif //_WIN32_WCE >= 600
return 0;
}
//----------------------------------------------------------------------
// FreeSharedObject - Frees a memory mapped object
//
int FreeSharedObject (PMMOBJSTRUCT obj)
{
if (obj == 0)
return ERROR_INVALID_PARAMETER;
// For 6.0, we can't use a Shared MM object any more. Use the shared
// heap. Its R/W from the driver and R/O for the app, but that's fine.
#if (_WIN32_WCE >= 600)
VirtualFree (obj->p, 0, MEM_RELEASE);
#else
UnmapViewOfFile (obj->p);
CloseHandle (obj->h);
#endif //_WIN32_WCE >= 600
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -