📄 pddvclas.cpp
字号:
//-------------------------------------------------------------------------
// <copyright file="pddVClas.cpp" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are covered by the
// Microsoft Limited Permissive License (Ms-LPL)
// http://www.microsoft.com/resources/sharedsource/licensingbasics/limitedpermissivelicense.mspx
// which can be found in the file MS-LPL.txt at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license.
//
// You must not remove this notice, or any other, from this software.
// </copyright>
//
// <summary>
// Low level USB video interface code
// </summary>
//-------------------------------------------------------------------------
//======================================================================
// pddVClas.cpp - Low level USB video interface code
//
// Author: Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <USBdi.h> // USB includes
#include <usb100.h> // USB includes
#include <usbclient.h> // USB client driver helper code
#include "usbvideo.h" // USB Video Specification defs
#include "webcamsdk.h" // IOCTL defs for driver
#include "WebCam.h" // Local driver includes
#include "pddVClas.h" // PDD defs
//
// Controllable features of the Camera. The order of this table must be the same as the bitfields of the
// Camera input descriptor feature bit fields.
//
/*
FEATURESTRUCT CamFeatures[] =
{
// Feature ID USB Video Class Command ID Unit ID Interface Length
{FEAT_SCANNING_MODE, USB_VIDEO_CT_CS_SCANNING_MODE_CTL, USB_VIDEO_VC_INPUT_TERMINAL, 0, 1},
{FEAT_AUTO_EXPOSURE_MODE, USB_VIDEO_CT_CS_AE_MODE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 1},
{FEAT_AUTO_EXPOSURE_PRI, USB_VIDEO_CT_CS_AE_PRIORITY_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 1},
{FEAT_EXPOSURE_TIME_ABS, USB_VIDEO_CT_CS_EXPOSURE_TIME_ABSOLUTE_CTL, USB_VIDEO_VC_INPUT_TERMINAL, 0, 4},
{FEAT_EXPOSURE_TIME_REL, USB_VIDEO_CT_CS_EXPOSURE_TIME_RELATIVE_CTL, USB_VIDEO_VC_INPUT_TERMINAL, 0, 1},
{FEAT_FOCUS_ABS, USB_VIDEO_CT_CS_FOCUS_ABSOLUTE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 2},
{FEAT_FOCUS_REL, USB_VIDEO_CT_CS_FOCUS_RELATIVE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 2},
{FEAT_IRIS_ABS, USB_VIDEO_CT_CS_IRIS_ABSOLUTE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 1},
{FEAT_IRIS_REL, USB_VIDEO_CT_CS_IRIS_RELATIVE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 2},
{FEAT_ZOOM_ABS, USB_VIDEO_CT_CS_ZOOM_ABSOLUTE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 1},
{FEAT_ZOOM_REL, USB_VIDEO_CT_CS_ZOOM_RELATIVE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 2},
{FEAT_PANTILT_ABS, USB_VIDEO_CT_CS_PANTILT_ABSOLUTE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 3},
{FEAT_PANTILT_REL, USB_VIDEO_CT_CS_PANTILT_RELATIVE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 8},
{FEAT_ROLL_ABS, USB_VIDEO_CT_CS_ROLL_ABSOLUTE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 4},
{FEAT_ROLL_REL, USB_VIDEO_CT_CS_ROLL_RELATIVE_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 2},
{FEAT_UNSUPPORTED, 0, 0, 0, 0}, //Reserved
{FEAT_UNSUPPORTED, 0, 0, 0, 0}, //Reserved
{FEAT_FOCUS_AUTO , USB_VIDEO_CT_CS_FOCUS_AUTO_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 2},
{FEAT_PRIVACY , USB_VIDEO_CT_CS_PRIVACY_CTL , USB_VIDEO_VC_INPUT_TERMINAL, 0, 1},
};*/
FEATURESTRUCT CamFeatures[] =
{
// Feature ID USB Video Class Command ID Unit ID Interface Length
{FEAT_SCANNING_MODE, USB_VIDEO_CT_CS_SCANNING_MODE_CTL, FEAT_UNSUPPORTED, 0, 1},
{FEAT_AUTO_EXPOSURE_MODE, USB_VIDEO_CT_CS_AE_MODE_CTL , FEAT_UNSUPPORTED, 0, 1},
{FEAT_AUTO_EXPOSURE_PRI, USB_VIDEO_CT_CS_AE_PRIORITY_CTL , FEAT_UNSUPPORTED, 0, 1},
{FEAT_EXPOSURE_TIME_ABS, USB_VIDEO_CT_CS_EXPOSURE_TIME_ABSOLUTE_CTL, FEAT_UNSUPPORTED, 0, 4},
{FEAT_EXPOSURE_TIME_REL, USB_VIDEO_CT_CS_EXPOSURE_TIME_RELATIVE_CTL, FEAT_UNSUPPORTED, 0, 1},
{FEAT_FOCUS_ABS, USB_VIDEO_CT_CS_FOCUS_ABSOLUTE_CTL , FEAT_UNSUPPORTED, 0, 2},
{FEAT_FOCUS_REL, USB_VIDEO_CT_CS_FOCUS_RELATIVE_CTL , FEAT_UNSUPPORTED, 0, 2},
{FEAT_IRIS_ABS, USB_VIDEO_CT_CS_IRIS_ABSOLUTE_CTL , FEAT_UNSUPPORTED, 0, 1},
{FEAT_IRIS_REL, USB_VIDEO_CT_CS_IRIS_RELATIVE_CTL , FEAT_UNSUPPORTED, 0, 2},
{FEAT_ZOOM_ABS, USB_VIDEO_CT_CS_ZOOM_ABSOLUTE_CTL , FEAT_UNSUPPORTED, 0, 1},
{FEAT_ZOOM_REL, USB_VIDEO_CT_CS_ZOOM_RELATIVE_CTL , FEAT_UNSUPPORTED, 0, 2},
{FEAT_PANTILT_ABS, USB_VIDEO_CT_CS_PANTILT_ABSOLUTE_CTL , FEAT_UNSUPPORTED, 0, 3},
{FEAT_PANTILT_REL, USB_VIDEO_CT_CS_PANTILT_RELATIVE_CTL , FEAT_UNSUPPORTED, 0, 8},
{FEAT_ROLL_ABS, USB_VIDEO_CT_CS_ROLL_ABSOLUTE_CTL , FEAT_UNSUPPORTED, 0, 4},
{FEAT_ROLL_REL, USB_VIDEO_CT_CS_ROLL_RELATIVE_CTL , FEAT_UNSUPPORTED, 0, 2},
{FEAT_UNSUPPORTED, 0, FEAT_UNSUPPORTED, 0, 0}, //Reserved
{FEAT_UNSUPPORTED, 0, FEAT_UNSUPPORTED, 0, 0}, //Reserved
{FEAT_FOCUS_AUTO , USB_VIDEO_CT_CS_FOCUS_AUTO_CTL , FEAT_UNSUPPORTED, 0, 2},
{FEAT_PRIVACY , USB_VIDEO_CT_CS_PRIVACY_CTL , FEAT_UNSUPPORTED, 0, 1},
};
//
// Controllable features of the processor unit
//
/*
FEATURESTRUCT ProcFeatures[] =
{
{FEAT_BRIGHTNESS, USB_VIDEO_PU_CS_BRIGHTNESS_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_CONTRAST, USB_VIDEO_PU_CS_CONTRAST_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_HUE, USB_VIDEO_PU_CS_HUE_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_SATURATION, USB_VIDEO_PU_CS_SATURATION_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_SHARPNESS, USB_VIDEO_PU_CS_SHARPNESS_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_GAMMA, USB_VIDEO_PU_CS_GAMMA_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_WHITE_BAL_TEMP, USB_VIDEO_PU_CS_WHITE_BALANCE_TEMP_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_WHITE_BAL_COMPONENT, USB_VIDEO_PU_CS_WHITE_BALANCE_COMPONENT_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 4},
{FEAT_BACKLIGHT_COMPENSATION, USB_VIDEO_PU_CS_BACKLIGHT_COMPENSATION_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_GAIN, USB_VIDEO_PU_CS_GAIN_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_POWER_LINE_FREQ, USB_VIDEO_PU_CS_POWER_LINE_FREQUENCY_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 1},
{FEAT_AUTO_HUE, USB_VIDEO_PU_CS_HUE_AUTO_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 1},
{FEAT_AUTO_WHITE_BAL_TEMP, USB_VIDEO_PU_CS_WHITE_BALANCE_TEMP_AUTO_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 1},
{FEAT_AUTO_WHITE_BAL_COMPONENT, USB_VIDEO_PU_CS_WHITE_BALANCE_COMPONENT_AUTO_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 1},
{FEAT_DIGITAL_MULTIPLIER, USB_VIDEO_PU_CS_DIGITAL_MULTIPLIER_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_DIGITAL_MULTIPLIER_LIMIT, USB_VIDEO_PU_CS_DIGITAL_MULTIPLIER_LIMIT_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 2},
{FEAT_ANALOG_VIDEO_STANDARD, USB_VIDEO_PU_CS_ANALOG_VIDEO_STANDARD_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 1},
{FEAT_ANALOG_VIDEO_LOCK_STATUS, USB_VIDEO_PU_CS_ANALOG_LOCK_STATUS_CTL, USB_VIDEO_VC_PROCESSING_UNIT, 0, 1},
};
*/
FEATURESTRUCT ProcFeatures[] =
{
{FEAT_BRIGHTNESS, USB_VIDEO_PU_CS_BRIGHTNESS_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_CONTRAST, USB_VIDEO_PU_CS_CONTRAST_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_HUE, USB_VIDEO_PU_CS_HUE_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_SATURATION, USB_VIDEO_PU_CS_SATURATION_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_SHARPNESS, USB_VIDEO_PU_CS_SHARPNESS_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_GAMMA, USB_VIDEO_PU_CS_GAMMA_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_WHITE_BAL_TEMP, USB_VIDEO_PU_CS_WHITE_BALANCE_TEMP_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_WHITE_BAL_COMPONENT, USB_VIDEO_PU_CS_WHITE_BALANCE_COMPONENT_CTL, FEAT_UNSUPPORTED, 0, 4},
{FEAT_BACKLIGHT_COMPENSATION, USB_VIDEO_PU_CS_BACKLIGHT_COMPENSATION_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_GAIN, USB_VIDEO_PU_CS_GAIN_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_POWER_LINE_FREQ, USB_VIDEO_PU_CS_POWER_LINE_FREQUENCY_CTL, FEAT_UNSUPPORTED, 0, 1},
{FEAT_AUTO_HUE, USB_VIDEO_PU_CS_HUE_AUTO_CTL, FEAT_UNSUPPORTED, 0, 1},
{FEAT_AUTO_WHITE_BAL_TEMP, USB_VIDEO_PU_CS_WHITE_BALANCE_TEMP_AUTO_CTL, FEAT_UNSUPPORTED, 0, 1},
{FEAT_AUTO_WHITE_BAL_COMPONENT, USB_VIDEO_PU_CS_WHITE_BALANCE_COMPONENT_AUTO_CTL, FEAT_UNSUPPORTED, 0, 1},
{FEAT_DIGITAL_MULTIPLIER, USB_VIDEO_PU_CS_DIGITAL_MULTIPLIER_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_DIGITAL_MULTIPLIER_LIMIT, USB_VIDEO_PU_CS_DIGITAL_MULTIPLIER_LIMIT_CTL, FEAT_UNSUPPORTED, 0, 2},
{FEAT_ANALOG_VIDEO_STANDARD, USB_VIDEO_PU_CS_ANALOG_VIDEO_STANDARD_CTL, FEAT_UNSUPPORTED, 0, 1},
{FEAT_ANALOG_VIDEO_LOCK_STATUS, USB_VIDEO_PU_CS_ANALOG_LOCK_STATUS_CTL, FEAT_UNSUPPORTED, 0, 1},
};
//-----------------------------------------------------------------------
// Pdd_DeviceAttach - Called by MDD during USBDeviceAttach.
// Return:
// 0 - Not my interface, ignore
// 1 - Claim interface
// 2 - Pass along interface to LoadGenericInterfaceDriver
//
int pdd_DeviceAttach (USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface, LPCWSTR szUniqueDriverId,
LPCUSB_DRIVER_SETTINGS lpDriverSettings, DWORD *pdwContext)
{
int rc = 0;
// Call the device to query all interfaces
LPCUSB_DEVICE lpUsbDev = (lpUsbFuncs->lpGetDeviceInfo)(hDevice);
if (!lpUsbDev)
return 0;
// See if this device has the interface we need...
// Only accept video control interface
if ((DWORD)lpInterface != 0)
{
if (lpInterface->Descriptor.bInterfaceSubClass == 0x02)
{
return 2;
}
}
// Allocate the Phys dev driver context structure. We'll add this
// pointer to the pdd field available in the device driver context
// structure.
PPDDCONTEXT pPDD = (PPDDCONTEXT)LocalAlloc (LPTR, sizeof (PDDCONTEXT));
if (pPDD == 0)
{
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
pPDD->dwSize = sizeof (PDDCONTEXT);
InitializeCriticalSection (&pPDD->csStill);
pPDD->hStillEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
pPDD->wReadThreadState = STREAMTHD_STOPPED;
pPDD->wCurrFormatIndex = 0xffff;
pPDD->wCurrFrameIndex = 0xffff;
pPDD->hVendorEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
pPDD->hNewFrameEvent = CreateEvent (NULL, TRUE, FALSE, NULL); // Manual reset event
// Set up default stream receive buffer
pPDD->strStreamDefault.dwNumBuffs = NUMDEFBUFFS;
InitializeCriticalSection (&pPDD->strStreamDefault.csBuffSync);
pPDD->strStreamDefault.hNewFrame = NULL;
pPDD->strStreamDefault.dwBuffSize = 0;
pPDD->strStreamDefault.pFrame[0].pBuff = 0;
pPDD->strStreamDefault.pFrame[1].pBuff = 0;
// See if we can find the proper interfaces. First, look for the
// standard Video Class Device interfaces...
if (!ParseStreamInterfaces (pPDD, lpUsbDev, 0x0e, 1, 0x0e, 2))
{
// If failed to open std interface, try vendor specific
if (!ParseStreamInterfaces (pPDD, lpUsbDev, 0xff, 1, 0xff, 2))
{
FreePDDContext (pPDD);
return 0;
}
}
DEBUGMSG(ZONE_USBLOAD, (DTAG TEXT("Video Class interface found.\n"), rc));
// Parse to see what features are supported by the camera
if (ParseFeatureParameters (pPDD))
DEBUGMSG(ZONE_USBLOAD, (DTAG TEXT("Error calling ParseFeatureParameters\n")));
rc = 1; // We accept the device
// Save our hardware context in the driver context structure.
*pdwContext = (DWORD)pPDD;
return rc;
}
//---------------------------------------------------------------------------------------
// FreePDDContext - Free the PDD context structure.
//
void FreePDDContext (PPDDCONTEXT pPDD)
{
int i;
if (pPDD == 0)
return;
__try
{
if (pPDD->dwSize == sizeof (PDDCONTEXT))
{
// Stop the read thread if its running.
StopReadThread (pPDD);
DeleteCriticalSection (&pPDD->csStill);
if (pPDD->hStillEvent)
CloseHandle (pPDD->hStillEvent);
// Free the stream descriptors
if (pPDD->usbstrmIF)
{
for (i = 0; i < pPDD->nStreamInterfaces; i++)
if (pPDD->usbstrmIF[i].lpepExtDesc)
LocalFree (pPDD->usbstrmIF[i].lpepExtDesc);
LocalFree (pPDD->usbstrmIF);
}
// Free any control interface extended descriptor
if (pPDD->usbctlIF.lpepExtDesc)
LocalFree (pPDD->usbctlIF.lpepExtDesc);
if (pPDD->hReadThread)
CloseHandle (pPDD->hReadThread);
if (pPDD->strStreamDefault.dwReserved)
CloseHandle ((HANDLE)pPDD->strStreamDefault.dwReserved);
for (DWORD i = 0; i < pPDD->strStreamDefault.dwNumBuffs; i++)
if (pPDD->strStreamDefault.pFrame[i].pBuff)
LocalFree (pPDD->strStreamDefault.pFrame[i].pBuff);
DeleteCriticalSection (&pPDD->strStreamDefault.csBuffSync);
if (pPDD->hVendorEvent)
CloseHandle (pPDD->hVendorEvent);
if (pPDD->hNewFrameEvent)
CloseHandle (pPDD->hNewFrameEvent);
}
LocalFree (pPDD);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG(ZONE_ERROR, (DTAG TEXT("Exception freeing PDD context structure\n")));
}
return;
}
//-----------------------------------------------------------------------
// Pdd_DeviceDetach - Called by MDD during unload notification but
// before the stream driver is deactivated.
//
int pdd_DeviceDetach (PDRVCONTEXT pDrv)
{
// Set the stream interface to turn off the video stream.
int rc = SetStreamInterface (pDrv, 1, 0);
// Free up PDD context structure
FreePDDContext ((PPDDCONTEXT)pDrv->dwPddContext);
return 0;
}
//---------------------------------------------------------------------------------------
//
//
int pdd_DrvInit (PDRVCONTEXT pDrv)
{
return 1;
}
//---------------------------------------------------------------------------------------
//
//
void pdd_DrvUninit (PDRVCONTEXT pDrv)
{
return;
}
//---------------------------------------------------------------------------------------
// pdd_DrvOpen - Called when driver is opened
//
int pdd_DrvOpen (PDRVCONTEXT pDrv)
{
BOOL fPwr;
// Make sure the camera is powered
GetPower (pDrv, &fPwr);
if (!fPwr)
SetPower (pDrv, TRUE);
return 1;
}
//---------------------------------------------------------------------------------------
// pdd_DrvClose - Called when driver is closed
//
void pdd_DrvClose (PDRVCONTEXT pDrv)
{
int rc;
rc = pdd_StopVidStream (pDrv);
// Turn off the camera
SetPower (pDrv, FALSE);
return;
}
//---------------------------------------------------------------------------------------
// Return a list of Feature IDs that is supported by this camera
//
int pdd_GetFeatureList (PDRVCONTEXT pDrv, DWORD *pList, int nListSize)
{
int nCnt = 0;
int i;
// Count the number of supported features
for (i = 0; i < dim (CamFeatures); i++)
{
// if (CamFeatures[i].bFeatureID != FEAT_UNSUPPORTED)
if (CamFeatures[i].bUnit != FEAT_UNSUPPORTED)
nCnt++;
}
for (i = 0; i < dim (ProcFeatures); i++)
{
// if (ProcFeatures[i].bFeatureID != FEAT_UNSUPPORTED)
if (ProcFeatures[i].bUnit != FEAT_UNSUPPORTED)
nCnt++;
}
// See if they're just asking for the number of features
if (pList == 0)
return nCnt;
if (nListSize < nCnt)
return 0;
// Now compile the list of supported IDs
for (i = 0; i < dim (CamFeatures); i++)
{
// if (CamFeatures[i].bFeatureID != FEAT_UNSUPPORTED)
if (CamFeatures[i].bUnit != FEAT_UNSUPPORTED)
*pList++ = CamFeatures[i].bFeatureID;
}
for (i = 0; i < dim (ProcFeatures); i++)
{
// if (ProcFeatures[i].bFeatureID != FEAT_UNSUPPORTED)
if (ProcFeatures[i].bUnit != FEAT_UNSUPPORTED)
*pList++ = ProcFeatures[i].bFeatureID;
}
return nCnt;
}
//-----------------------------------------------------------------------
// pdd_QueryFeature - Gets the min and max values value of a feature
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -