⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pddvclas.cpp

📁 基于webCan方面的源程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	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 + -