📄 webcam.cpp
字号:
{
// Start the video stream
rc = pdd_StartVidStream (pDrv, (BYTE)vsData.wFormatIndex, (BYTE)vsData.wFrameIndex,
pVid, vsData.dwInterval);
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_SetVideoFormat-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_GetNextVideoFrame
//
int mdd_GetNextVideoFrame (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut, PDWORD pdwBytesWritten)
{
int rc;
PBYTE pFrameBuff = 0;
PBYTE *ppFrameBuff;
PBYTE pFrameRet;
DWORD dwValidFrames, dwFrameBytes, dwTimeout;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetNextVideoFrame++\r\n")));
if (!pIn || (dwIn < sizeof (GETFRAMESTRUCT)) || !pOut || (dwOut < sizeof (GETFRAMESTRUCTOUT)) || !pdwBytesWritten)
return ERROR_INVALID_PARAMETER;
PGETFRAMESTRUCT pGetFrStruct = (PGETFRAMESTRUCT)pIn;
PGETFRAMESTRUCTOUT pGetFrStructOut = (PGETFRAMESTRUCTOUT)pOut;
__try
{
// Test the structure by checking the size field. For speed reasons, I'm
// not copying the entire structure into the driver.
if (pGetFrStruct->cbSize != sizeof (GETFRAMESTRUCT))
{
DEBUGMSG (ZONE_ERROR, (TEXT("Bad size field in GETFRAMESTRUCT structure\r\n")));
return ERROR_INVALID_PARAMETER;
}
// Test the out structure by checking the size field.
if (pGetFrStructOut->cbSize != sizeof (GETFRAMESTRUCTOUT))
{
DEBUGMSG (ZONE_ERROR, (TEXT("Bad size field in GETFRAMESTRUCTOUT structure\r\n")));
return ERROR_INVALID_PARAMETER;
}
// See if app wants a new frame
if (pGetFrStruct->dwFlags & GETFRAMEFLAG_NOFRAME_WANTED)
ppFrameBuff = 0;
else
ppFrameBuff = &pFrameBuff;
// See if app is returning a buffer
if (pGetFrStruct->dwFlags & GETFRAMEFLAG_FREEBUFF_VALID)
pFrameRet = pGetFrStruct->pFrameDataRet;
else
pFrameRet = 0;
// Get timeout value
if (pGetFrStruct->dwFlags & GETFRAMEFLAG_TIMEOUT_VALID)
dwTimeout = pGetFrStruct->dwTimeout;
else
dwTimeout = DEFNEXTFRAMETIMEOUT;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception reading GETFRAMESTRUCT structure\r\n")));
return ERROR_INVALID_PARAMETER;
}
// Get the data, first leave the driver CS. since this can block.
LeaveCriticalSection (&pDrv->csDCall);
__try
{
rc = pdd_GetNextVideoFrame (pDrv, TRUE, ppFrameBuff, &dwFrameBytes, &dwValidFrames, pFrameRet, dwTimeout);
}
__finally
{
EnterCriticalSection (&pDrv->csDCall);
}
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
FreeMMObject (&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;
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;
}
return rc;
}
//----------------------------------------------------------------------
// AllocMMObject - Allocates a memory mapped object
//
int AllocMMObject (int nSize, PMMOBJSTRUCT obj)
{
if ((obj == 0) || (nSize == 0))
return ERROR_INVALID_PARAMETER;
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();
}
return 0;
}
//----------------------------------------------------------------------
// FreeMMObject - Frees a memory mapped object
//
int FreeMMObject (PMMOBJSTRUCT obj)
{
if (obj == 0)
return ERROR_INVALID_PARAMETER;
UnmapViewOfFile (obj->p);
CloseHandle (obj->h);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -