📄 webcam.cpp
字号:
nCnt = pdd_GetFeatureList (pDrv, NULL, 0);
DWORD dwOutSize = nCnt * sizeof (FEATUREPROP) + sizeof (FEATUREPROPS);
// See if they want the size of the buffer
if ((pOut == 0) && pdwBytesWritten)
{
__try
{
*pdwBytesWritten = dwOutSize;
return 0;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return ERROR_INVALID_PARAMETER;
}
}
// See if output buffer is big enough
if (dwOut < dwOutSize)
return ERROR_NOT_ENOUGH_MEMORY;
// Get the list of feature IDs
PDWORD pList = (PDWORD)LocalAlloc (LPTR, nCnt * sizeof (DWORD));
rc = pdd_GetFeatureList (pDrv, pList, nCnt);
if (rc == 0) // No features returned
{
LocalFree (pList);
return 0;
}
// Query each feature from the PDD and copy to the apps buffer
FEATUREPROP fp;
PFEATUREPROPS pfps = (PFEATUREPROPS)pOut;
__try
{
pfps->nNumProps = nCnt;
for (int i = 0; i < nCnt; i++)
{
rc = pdd_QueryFeature (pDrv, pList[i], &fp);
if (rc)
{
fp.dwFlags |= FLAG_FP_ERROR;
fp.nMax = rc;
fp.nMin = rc;
}
pfps->fpArray[i] = fp;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
rc = ERROR_INVALID_PARAMETER;
}
LocalFree ((PVOID)pList);
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetParameterList-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_GetParameter - Handles IOCTL_CAMERA_DEVICE_GETPARAMETER Ioctl command
//
int mdd_GetParameter (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut,
PDWORD pdwBytesWritten)
{
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetParameter++\r\n")));
// Check parameters
if (!pIn || (dwIn < sizeof (DWORD)) || !pOut || (dwOut < sizeof (DWORD)))
ERROR_INVALID_PARAMETER;
DWORD dwFeat;
DWORD dwVal;
int rc;
__try {
dwFeat = *pIn;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return ERROR_INVALID_PARAMETER;
}
rc = pdd_GetParameter (pDrv, dwFeat, &dwVal);
if (rc == 0)
{
__try
{
memcpy (pOut, &dwVal, sizeof (dwVal));
*pdwBytesWritten = sizeof (dwVal);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
rc = ERROR_INVALID_PARAMETER;
}
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetParameter-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_SetParameter - Handles IOCTL_CAMERA_DEVICE_SETPARAMETER Ioctl command
//
int mdd_SetParameter (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut,
PDWORD pdwBytesWritten)
{
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_SetParameter++\r\n")));
// Check parameters
if (!pIn || (dwIn < sizeof (SETFEATURESTRUCT)))
return ERROR_INVALID_PARAMETER;
DWORD dwFeat;
DWORD dwVal;
PSETFEATURESTRUCT pFeat = (PSETFEATURESTRUCT)pIn;
int rc;
__try {
if (pFeat->cbSize != sizeof (SETFEATURESTRUCT))
return ERROR_INVALID_PARAMETER;
dwFeat = pFeat->dwFeatureID;
dwVal = pFeat->dwVal;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return ERROR_INVALID_PARAMETER;
}
rc = pdd_SetParameter (pDrv, dwFeat, dwVal);
if ((rc == 0) && pOut && (dwOut >= sizeof (DWORD)))
{
// Now, if the user has specified an out buffer, query the feature just set
rc = pdd_GetParameter (pDrv, dwFeat, &dwVal);
if (rc == 0)
{
__try
{
memcpy (pOut, &dwVal, sizeof (dwVal));
*pdwBytesWritten = sizeof (dwVal);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
rc = ERROR_INVALID_PARAMETER;
}
}
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_SetParameter-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_QueryVideoFormats - Handles IOCTL_CAMERA_DEVICE_QUERYVIDEOFORMATS Ioctl command
//
int mdd_QueryVideoFormats (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut,
PDWORD pdwBytesWritten)
{
int rc = 0;
BYTE bFmt, bFrm;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_QueryVideoFormats++\r\n")));
// Check parameters
if (!pdwBytesWritten)
return ERROR_INVALID_PARAMETER;
// Get the number of frame sizes for each format
DWORD dwCnt = 0;
FORMATPROPS Props;
PFORMATPROPS pPropOut = (PFORMATPROPS)pOut;
for (bFmt = 0, rc = 0; (bFmt < 255) && (rc == 0); bFmt++)
{
DWORD dwCnt1 = dwCnt;
for (bFrm = 0; (bFrm < 255) && (rc == 0); bFrm++)
{
rc = pdd_GetFormatParameters (pDrv, bFmt, bFrm, FALSE, &Props);
if (rc == 0)
{
if (pPropOut)
{
if (dwOut > sizeof (FORMATPROPS))
{
// Write the data to the output buffer
__try
{
*pPropOut = Props;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return ERROR_INVALID_PARAMETER;
}
dwOut -= sizeof (FORMATPROPS);
pPropOut++;
}
else
return ERROR_NOT_ENOUGH_MEMORY;
}
dwCnt++;
}
}
// Did we get any frame for the current format?
if (dwCnt1 != dwCnt)
rc = 0;
}
__try
{
*pdwBytesWritten = dwCnt * sizeof (FORMATPROPS);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
rc = ERROR_INVALID_PARAMETER;
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_QueryVideoFormats-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// Handles IOCTL_CAMERA_DEVICE_GETVIDEOFORMAT Ioctl command
//
int mdd_GetVideoFormat (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PBYTE pOut, DWORD dwOut,
PDWORD pdwBytesWritten)
{
int rc;
int nFrameIndex, nFormatIndex;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetVideoFormat++\r\n")));
if (!pIn || (dwIn < sizeof (VIDFORMATSTRUCT)) || !pOut ||
(dwOut < sizeof (FORMATPROPS)) || !pdwBytesWritten)
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;
}
// Get the data
FORMATPROPS Props;
rc = pdd_GetFormatParameters (pDrv, nFormatIndex, nFrameIndex, FALSE, &Props);
if (rc == 0)
{
__try
{
memcpy (pOut, &Props, sizeof (FORMATPROPS));
*pdwBytesWritten = sizeof (FORMATPROPS);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception writing FORMATPROPS structure\r\n")));
rc = ERROR_INVALID_PARAMETER;
}
}
else
{
DEBUGMSG (ZONE_ERROR, (TEXT("Error calling pdd_GetFormatParameters rc %d\r\n"), rc));
rc = ERROR_INVALID_PARAMETER;
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_GetVideoFormat-- rc %d\r\n"),rc));
return rc;
}
//---------------------------------------------------------------------------------------
// mdd_SetVideoFormat - Handles IOCTL_CAMERA_DEVICE_STARTVIDEOSTREAM
//
int mdd_SetVideoFormat (PDRVCONTEXT pDrv, PBYTE pIn, DWORD dwIn, PDWORD pdwBytesWritten)
{
int rc;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("mdd_SetVideoFormat++\r\n")));
if (!pIn || (dwIn < sizeof (STARTVIDSTRUCT)) || !pdwBytesWritten)
return ERROR_INVALID_PARAMETER;
// Copying the struture will verify access. We'll need to use the original
// pointer when we call the PDD.
STARTVIDSTRUCT vsData;
__try
{
// Copy the data inside the driver
vsData = *(PSTARTVIDSTRUCT)pIn;
// verify the size of the structure
if (vsData.cbSize != sizeof (STARTVIDSTRUCT))
{
DEBUGMSG (ZONE_ERROR, (TEXT("cbSize field of STARTVIDSTRUCT structure doesn't match structure size\r\n")));
return ERROR_INVALID_PARAMETER;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Exception reading STARTVIDSTRUCT structure\r\n")));
return ERROR_INVALID_PARAMETER;
}
// See if for some reason, the app is trying a new stream before shutting down
// the old one.
if (pDrv->mmFrameBuff.p)
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Starting a new stream while another is running!\r\n")));
return ERROR_BUSY;
}
// Get data about the requested format
FORMATPROPS Props;
rc = pdd_GetFormatParameters (pDrv, (BYTE)vsData.wFormatIndex, (BYTE)vsData.wFrameIndex, FALSE, &Props);
if (rc)
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Bad still format requested Fmt:%d Frame:%d\r\n"),
vsData.wFormatIndex, vsData.wFrameIndex));
return ERROR_INVALID_PARAMETER;
}
//
// Create the frame buffers. Use a memory mapped object so we won't have to copy
// the frame data to the calling application.
//
// Verify that we at least have three buffers
if (vsData.dwNumBuffs < 3)
vsData.dwNumBuffs = 3;
// Allocate the memory mapped object
rc = AllocSharedObject (sizeof(VIDSTREAMSTRUCT) +
((Props.dwMaxBuff + vsData.dwPreBuffSize + vsData.dwPostBuffSize) * vsData.dwNumBuffs),
&pDrv->mmFrameBuff);
if (rc)
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Can't allocate memory mapped object rc = %d\r\n"), rc));
return ERROR_NOT_ENOUGH_MEMORY;
}
PVIDSTREAMSTRUCT pVid = (PVIDSTREAMSTRUCT)pDrv->mmFrameBuff.p;
memset (pVid, 0, sizeof (VIDSTREAMSTRUCT));
pVid->wFormatIndex = vsData.wFormatIndex;
pVid->wFrameIndex = vsData.wFrameIndex;
pVid->dwInterval = vsData.dwInterval;
pVid->dwBuffSize = Props.dwMaxBuff;
pVid->dwNumBuffs = vsData.dwNumBuffs;
pVid->dwReserved = (DWORD)CreateEvent (NULL, FALSE, FALSE, NULL);
InitializeCriticalSection (&pVid->csBuffSync);
// Fill in the buffer pointers.
for (DWORD i = 0; i < vsData.dwNumBuffs; i++)
{
pVid->pFrame[i].pBuff = pDrv->mmFrameBuff.p + // Start of mm object
sizeof (VIDSTREAMSTRUCT) + // Stream struct size
((vsData.dwNumBuffs-1) * sizeof(DWORD)) + // Size of ptr array after structure
vsData.dwPreBuffSize + // Offset into buff for prebuff
((Props.dwMaxBuff + vsData.dwPostBuffSize) * i); // Size of each buffer inc post buff
// Dump the buffer locations for debugging
DEBUGMSG (ZONE_VIDFRAME, (DTAG TEXT ("MM buffer at %0x\r\n"), pVid->pFrame[i].pBuff));
}
if (rc == 0)
{
// 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;
DWORD dwFrameFlags;
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 we're already in this call, waiting on a frame
if (pDrv->fBusy)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Error. Already in GetNextFrame call.\r\n")));
return ERROR_BUSY;
}
// 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;
// See if the caller wants the oldest or newest frame
dwFrameFlags = 0;
if (pGetFrStruct->dwFlags & GETFRAMEFLAG_GET_OLDESTFRAME)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -