📄 pddvclas.cpp
字号:
//
int DoVendorTransfer (PDRVCONTEXT pDrv, BYTE bRequest, BYTE bCmd, BYTE bInterface,
BYTE bUnit, PBYTE pVal, WORD wLen)
{
USB_DEVICE_REQUEST req;
DWORD dwBytes;
DWORD dw, dwErr;
BOOL fSet;
static BYTE bTBuff[512];
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("DoVendorTransfer++\r\n")));
if (bRequest == USBVID_SET_CUR)
fSet = TRUE;
else
fSet = FALSE;
// Get our pdd specific context
PPDDCONTEXT pPDD = (PPDDCONTEXT)pDrv->dwPddContext;
//
// Set transfer flags depending on read or write
//
if (fSet)
req.bmRequestType = USB_REQUEST_HOST_TO_DEVICE | USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE;
else
req.bmRequestType = USB_REQUEST_DEVICE_TO_HOST | USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE;
req.bRequest = bRequest;
req.wValue = MAKEWORD (0, bCmd);
req.wIndex = MAKEWORD (bInterface, bUnit);
req.wLength = wLen;
dwBytes = 0;
dwErr = USB_NO_ERROR;
dw = IssueVendorTransfer (pDrv->lpUsbFuncs, pDrv->hDevice,
DefaultTransferComplete, pPDD->hVendorEvent,
(fSet ? USB_OUT_TRANSFER : USB_IN_TRANSFER) | USB_SHORT_TRANSFER_OK,
&req, fSet && (req.wLength < sizeof (bTBuff)) ? pVal : bTBuff,
NULL, &dwBytes, 2000, &dwErr);
if (dw)
DEBUGMSG (ZONE_ERROR,
(DTAG TEXT("Error calling IssueVendorTransfer rc: %d ExtErr: %d\r\n"),
dw, GetLastError()));
// If no data transferred, stuff in an error
if (!dw && (dwBytes != wLen))
{
DEBUGMSG (ZONE_ERROR,
(DTAG TEXT("IssueVendorTransfer returned different length than requested len: %d expected: %d\r\n"),
dwBytes, wLen));
dw = ERROR_BAD_LENGTH;
}
// Copy data to output buffer
if (!dw && !fSet && (dwBytes <= req.wLength))
memcpy (pVal, bTBuff, dwBytes);
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("DoVendorTransfer-- rc %d\r\n"), dw));
return dw;
}
//-----------------------------------------------------------------------
// GetVendorTransferLen - Called to query the data length request
// for a particular command.
//
int GetVendorTransferLen (PDRVCONTEXT pDrv, BYTE bCmd, BYTE bInterface,
BYTE bUnit, WORD *pwLen)
{
USB_DEVICE_REQUEST req;
DWORD dwBytes;
DWORD dw, dwErr;
static BYTE bTBuff[512];
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetVendorTransferLen++\r\n")));
// Get our pdd specific context
PPDDCONTEXT pPDD = (PPDDCONTEXT)pDrv->dwPddContext;
req.bmRequestType = USB_REQUEST_DEVICE_TO_HOST | USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE;
req.bRequest = USBVID_GET_LEN;
req.wValue = MAKEWORD (0, bCmd);
req.wIndex = MAKEWORD (bInterface, bUnit);
req.wLength = 2;
dwBytes = 0;
dwErr = USB_NO_ERROR;
dw = IssueVendorTransfer (pDrv->lpUsbFuncs, pDrv->hDevice,
DefaultTransferComplete, pPDD->hVendorEvent,
USB_IN_TRANSFER, &req, bTBuff,
NULL, &dwBytes, 2000, &dwErr);
if ((dw == 0) && (dwBytes == 2))
{
*pwLen = *(WORD *)bTBuff;
}
else
{
DEBUGMSG (ZONE_ERROR,
(DTAG TEXT("Error calling IssueVendorTransfer rc: %d ExtErr: %d\r\n"),
dw, GetLastError()));
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetVendorTransferLen-- len %d rc %d\r\n"), *pwLen, dw));
return dw;
}
//-----------------------------------------------------------------------
// FindFeatureInfo - Look up feature in the table to get parameter
// information.
//
PFEATURESTRUCT FindFeatureInfo (BYTE bFeatureID)
{
int i;
for (i = 0; i < dim (CamFeatures); i++)
{
if (bFeatureID == CamFeatures[i].bFeatureID)
return &CamFeatures[i];
}
for (i = 0; i < dim (ProcFeatures); i++)
{
if (bFeatureID == ProcFeatures[i].bFeatureID)
return &ProcFeatures[i];
}
return 0;
}
//-----------------------------------------------------------------------
// EnableSupportedFeatures - Given a bit array from the interface
// descriptor, fill the feature table with the necessary data.
//
int EnableSupportedFeatures (PBYTE pCtlBytes, int nCtlBytes, PFEATURESTRUCT pFeatArray,
int nFeatArraySize, BYTE bUnit)
{
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("EnableSupportedFeatures++\r\n")));
BYTE bm;
BYTE index;
// Loop through, Check the bit for each feature
for (index = 0; index < nFeatArraySize; index++)
{
// Do we need another byte?
if ((index % 8) == 0)
{
// if no more bytes, leave
if (nCtlBytes == 0)
break;
bm = *pCtlBytes++;
nCtlBytes--;
}
if (bm & 0x01)
pFeatArray[index].bUnit = bUnit;
else
pFeatArray[index].bUnit = FEAT_UNSUPPORTED;
bm = bm >> 1;
}
// BUGFIX: Reported by Himangshu Roy
// Delete any features at the end of the list
for (; index < nFeatArraySize; index++)
pFeatArray[index].bUnit = FEAT_UNSUPPORTED;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("EnableSupportedFeatures--\r\n")));
return 0;
}
//-----------------------------------------------------------------------
// ParseFeatureParameters - Parses the device interface descriptor to
// see what features this camera supports.
//
// CDB 6-4-2006: Removed all references to "pData + #". Added missing descriptors
// and changed all size checks to use descriptor sizes. These
// changes allow this function work for ARM and MIPSIV compilers.
//
int ParseFeatureParameters (PPDDCONTEXT pPDD)
{
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("ParseFeatureParameters++\r\n")));
// Find the Control descriptors
PUSBVIDCTLIFDESCRIPTOR pHdr = (PUSBVIDCTLIFDESCRIPTOR)pPDD->usbctlIF.lpepExtDesc;
__try {
// Sanity check on header IDs
if ((pHdr->bType != 0x24) || (pHdr->bSubtype != 1))
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Bad Extended Stream Descriptor\r\n")));
return -1;
}
PBYTE pData = (PBYTE)pHdr;
PBYTE pEnd = (PBYTE)pHdr + pHdr->wTotalLen;
PUSBVIDSTDDESCHDR pStd = (PUSBVIDSTDDESCHDR)pHdr;
// Loop through all the descriptors
while (pData + pStd->bLen < pEnd)
{
pData += pStd->bLen;
pStd = (PUSBVIDSTDDESCHDR)pData;
if (pStd->bType != USB_VIDEO_CS_INTERFACE)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Unexpected header type %xh\r\n"), pStd->bType));
break;
}
switch (pStd->bSubtype)
{
case USB_VIDEO_VC_PROCESSING_UNIT:
// Verify structure length
if (pStd->bLen >= sizeof(USBVIDPUNITIFDESCRIPTOR))
{
PUSBVIDPUNITIFDESCRIPTOR pPUnit = (PUSBVIDPUNITIFDESCRIPTOR)pData;
BYTE bCtlSize = pPUnit->bControlSize;
PBYTE pCtls = pPUnit->bmControls;
BYTE bUnit = pPUnit->bUnitID;
EnableSupportedFeatures (pCtls, bCtlSize, ProcFeatures,
dim(ProcFeatures), bUnit);
}
break;
case USB_VIDEO_VC_INPUT_TERMINAL:
{
WORD wType = pStd->wTermType;
// Verify that it's the camera
if ((wType == USB_VIDEO_ITT_CAMERA) ||
(wType == USB_VIDEO_TT_STREAMING))
{
// Verify structure length
if (pStd->bLen >= sizeof(USBVIDCAMINPUTTERMIFDESCRIPTOR))
{
PUSBVIDCAMINPUTTERMIFDESCRIPTOR pCamInputTerm =
(PUSBVIDCAMINPUTTERMIFDESCRIPTOR)pData;
BYTE bCtlSize = pCamInputTerm->bControlSize;
PBYTE pCtls = pCamInputTerm->bmControls;
BYTE bTerm = pCamInputTerm->bTerminalID;
EnableSupportedFeatures (pCtls, bCtlSize, CamFeatures,
dim(CamFeatures), bTerm);
}
}
}
break;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG (1, (TEXT("Exception scanning extended control descriptor\r\n")));
return -2;
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("ParseFeatureParameters--\r\n")));
return 0;
}
//-----------------------------------------------------------------------
// ProcessFrameFormats - Helper function that examines the frame information
// for each format and returns information on the given frame.
//
int ProcessFrameFormats (PPDDCONTEXT pPDD, PUSBVIDSTDDESCHDR pStd, BYTE bDescID,
BYTE bFormatIndex, BYTE bFrameIndex,
PFORMATPROPS pProps, BOOL *pfFound)
{
PUSBVIDSTREAMIF_FORMATDESCRIPTOR pFmt = (PUSBVIDSTREAMIF_FORMATDESCRIPTOR)pStd;
BYTE bCnt = pFmt->bNumFrameDescriptors;
*pfFound = FALSE;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("ProcessFrameFormats++\r\n")));
if (bFrameIndex > bCnt)
return -1;
// See if this is the format we want
if (pFmt->bFormatIndex != bFormatIndex)
return 0;
// Get the pointer to the first frame descriptor
PUSBVIDSTREAMIF_MJPEGFRAMEDESCRIPTOR pFrmMJPEG = (PUSBVIDSTREAMIF_MJPEGFRAMEDESCRIPTOR)( (PBYTE)pStd+pStd->bLen);
if (pFrmMJPEG->bSubtype != bDescID)
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("ERROR: Expected Frame descriptor to follow format descriptor\r\n")));
return -2;
}
// Loop through Frame descriptors looking for matching index
for (int i = 0; i < bCnt; i++)
{
// See if this is the descriptor we want
if (pFrmMJPEG->bFrameIndex == bFrameIndex)
{
// Grab the info we want
pProps->cbSize = sizeof (FORMATPROPS);
pProps->wFormatType = bDescID;
pProps->wFormatIndex = bFormatIndex;
pProps->wFrameIndex = bFrameIndex;
pProps->dwHeight = pFrmMJPEG->wHeight;
pProps->dwWidth = pFrmMJPEG->wWidth;
pProps->dwMaxBuff = pFrmMJPEG->dwMaxVideoFrameBufferSize;
if (pFrmMJPEG->bFrameIntervalType)
{
pProps->nNumInterval = pFrmMJPEG->bFrameIntervalType;
for (int k = 0; k < pFrmMJPEG->bFrameIntervalType; k++)
{
pProps->dwInterval[k] = pFrmMJPEG->Interval.dwDescrete[k];
}
}
else
{
// Cont interval
pProps->nNumInterval = -1;
pProps->dwInterval[0] = pFrmMJPEG->Interval.strCont.dwMinFrameInterval;
pProps->dwInterval[1] = pFrmMJPEG->Interval.strCont.dwMaxFrameInterval;
pProps->dwInterval[2] = pFrmMJPEG->Interval.strCont.dwFrameIntervalStep;
}
*pfFound = TRUE;
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("ProcessFrameFormats--\r\n")));
return 0;
}
pFrmMJPEG = (PUSBVIDSTREAMIF_MJPEGFRAMEDESCRIPTOR)((PBYTE)pFrmMJPEG + pFrmMJPEG->bLen);
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("ProcessFrameFormats--\r\n")));
return -3; // We didn't find the index requested
}
//-----------------------------------------------------------------------
// StopReadThread - Stops the isoch read thread
//
void StopReadThread (PPDDCONTEXT pPDD)
{
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("StopReadThread++\r\n")));
// We need to stop the read thread if its running...
if (pPDD->wReadThreadState != STREAMTHD_STOPPED)
{
pPDD->wReadThreadState = STREAMTHD_STOPPED;
int rc = WaitForSingleObject (pPDD->hReadThread, 2000);
if (rc != WAIT_OBJECT_0)
{
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Can't stop read thread!\r\n")));
TerminateThread (pPDD->hReadThread, -1);
}
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("StopReadThread--\r\n")));
return;
}
//-----------------------------------------------------------------------
// GetMinMaxQuality - Returns the min, max, and increment values for
// the compression paramter for a given format, frame size, and, frame rate
//
int GetMinMaxQuality (PDRVCONTEXT pDrv, BYTE bFormatIndex, BYTE bFrameIndex, DWORD dwFrameInterval,
WORD *pwCompMin, WORD *pwCompMax, WORD *pwCompInc)
{
BYTE buff[64];
int rc = 0;
BYTE bInterface = VID_IF_STREAM;
BYTE bUnit = 0;
WORD wProbeLen = sizeof (PSTREAM_PROBE_CONTROLSTRUCT);
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetMinMaxQuality++\r\n")));
// Get our pdd specific context
PPDDCONTEXT pPDD = (PPDDCONTEXT)pDrv->dwPddContext;
memset (buff, 0, sizeof (buff));
PSTREAM_PROBE_CONTROLSTRUCT p = (PSTREAM_PROBE_CONTROLSTRUCT)buff;
// Get the length of this struct, since it changes between cameras
rc = GetVendorTransferLen (pDrv, USB_VIDEO_VS_CS_PROBE_CTL, bInterface, bUnit, &wProbeLen);
// Set current probe vals
memset (p, 0, sizeof (0));
p->bFormatIndex = bFormatIndex;
p->bFrameIndex = bFrameIndex;
p->dwFrameInterval = dwFrameInterval;
rc = DoVendorTransfer (pDrv, USBVID_SET_CUR, USB_VIDEO_VS_CS_PROBE_CTL,
bInterface, bUnit, (PBYTE)p, wProbeLen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -