📄 pddvclas.cpp
字号:
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);
if (rc)
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Error setting original probe vals rc %d\r\n"), rc));
if (rc == 0)
{
// Get minimum quality value
p->bFormatIndex = bFormatIndex;
p->bFrameIndex = bFrameIndex;
p->dwFrameInterval = dwFrameInterval;
rc = DoVendorTransfer (pDrv, USBVID_GET_MIN, USB_VIDEO_VS_CS_PROBE_CTL,
bInterface, bUnit, (PBYTE)p, wProbeLen);
if (rc)
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Error getting min value. rc %d\r\n"), rc));
*pwCompMin = p->wCompQuality;
}
if (rc == 0)
{
// Get maximum quality value
p->bFormatIndex = bFormatIndex;
p->bFrameIndex = bFrameIndex;
p->dwFrameInterval = dwFrameInterval;
rc = DoVendorTransfer (pDrv, USBVID_GET_MAX, USB_VIDEO_VS_CS_PROBE_CTL,
bInterface, bUnit, (PBYTE)p, wProbeLen);
if (rc)
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Error getting max value. rc %d\r\n"), rc));
*pwCompMax = p->wCompQuality;
}
if (rc == 0)
{
// Get maximum quality value
p->bFormatIndex = bFormatIndex;
p->bFrameIndex = bFrameIndex;
p->dwFrameInterval = dwFrameInterval;
rc = DoVendorTransfer (pDrv, USBVID_GET_RES, USB_VIDEO_VS_CS_PROBE_CTL,
bInterface, bUnit, (PBYTE)p, wProbeLen);
if (rc)
DEBUGMSG (ZONE_ERROR, (DTAG TEXT("Error getting inc value. rc %d\r\n"), rc));
*pwCompInc = p->wCompQuality;
}
DEBUGMSG (ZONE_FUNC, (DTAG TEXT("GetMinMaxQuality-- rc %d\r\n"), rc));
return rc;
}
//-----------------------------------------------------------------------
// ProbeCommitVidStream - Negotiates the streaming parameters
//
int ProbeCommitVidStream (PDRVCONTEXT pDrv, BYTE bFormatIndex, BYTE bFrameIndex,
DWORD *pdwFrameInterval, WORD wCompression, PDWORD pdwMaxBandwidth)
{
int rc = 0;
BYTE bInterface = VID_IF_STREAM;
BYTE bUnit = 0;
WORD wProbeLen = sizeof (PSTREAM_PROBE_CONTROLSTRUCT);
DEBUGMSG (ZONE_FUNC | ZONE_PROBE,
(DTAG TEXT("ProbeCommitVidStream++ Fmt: %d Frm: %d Interval %d Compression %d\r\n"),
bFormatIndex, bFrameIndex, *pdwFrameInterval, wCompression));
// Get our pdd specific context
PPDDCONTEXT pPDD = (PPDDCONTEXT)pDrv->dwPddContext;
// Get the length of this struct, since it changes between cameras
rc = GetVendorTransferLen (pDrv, USB_VIDEO_VS_CS_PROBE_CTL, bInterface, bUnit, &wProbeLen);
// Clear the buffer. We use this because the USB stack (or camera) sometimes returns more
// data than the size of the STREAM_PROBE_CONTROLSTRUCT structure.
STREAM_PROBE_CONTROLSTRUCT pSPC;
memset (&pSPC, 0, sizeof (STREAM_PROBE_CONTROLSTRUCT));
// Set probe values
pSPC.bFormatIndex = bFormatIndex;
pSPC.bFrameIndex = bFrameIndex;
pSPC.dwFrameInterval = *pdwFrameInterval;
pSPC.wCompQuality = wCompression;
pSPC.bmHint = USB_VIDEO_PROBE_HINT_FRAMEINTERVAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -