📄 nullpdd.cpp
字号:
m_pModeVideoFormat[STILL].pCsDataRangeVideo[0] = &DCAM_StreamMode_0;
m_pModeVideoFormat[STILL].pCsDataRangeVideo[1] = &DCAM_StreamMode_1;
if( 3 == m_ulCTypes )
{
m_pModeVideoFormat[PREVIEW].categoryGUID = PINNAME_VIDEO_PREVIEW;
m_pModeVideoFormat[PREVIEW].ulAvailFormats = 5;
m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo = new PCS_DATARANGE_VIDEO[m_pModeVideoFormat[PREVIEW].ulAvailFormats];
if( NULL == m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo )
{
return ERROR_INSUFFICIENT_BUFFER;
}
m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo[0] = &DCAM_StreamMode_0;
m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo[1] = &DCAM_StreamMode_1;
m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo[2] = &DCAM_StreamMode_2;
m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo[3] = &DCAM_StreamMode_6;
m_pModeVideoFormat[PREVIEW].pCsDataRangeVideo[4] = &DCAM_StreamMode_7;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
m_pModeVideoCaps = NULL;
// Allocate Video Control Caps specific array.
m_pModeVideoCaps = new VIDCONTROLCAPS[m_ulCTypes];
if( NULL == m_pModeVideoCaps )
{
return ERROR_INSUFFICIENT_BUFFER;
}
// Video Control Caps
m_pModeVideoCaps[CAPTURE].DefaultVideoControlCaps = DefaultVideoControlCaps[CAPTURE];
m_pModeVideoCaps[CAPTURE].CurrentVideoControlCaps = DefaultVideoControlCaps[CAPTURE];;
m_pModeVideoCaps[STILL].DefaultVideoControlCaps = DefaultVideoControlCaps[STILL];
m_pModeVideoCaps[STILL].CurrentVideoControlCaps = DefaultVideoControlCaps[STILL];;
if( 3 == m_ulCTypes )
{
// Note PREVIEW control caps are the same, so we don't differentiate
m_pModeVideoCaps[PREVIEW].DefaultVideoControlCaps = DefaultVideoControlCaps[PREVIEW];
m_pModeVideoCaps[PREVIEW].CurrentVideoControlCaps = DefaultVideoControlCaps[PREVIEW];;
}
// Timer specific variables. Only to be used in this NULL PDD
m_hTimerDll = NULL;
m_pfnTimeSetEvent = NULL;
m_pfnTimeKillEvent = NULL;
memset( &m_TimerIdentifier, 0, MAX_SUPPORTED_PINS * sizeof(MMRESULT));
m_SensorModeInfo[CAPTURE].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
m_SensorModeInfo[CAPTURE].MaxNumOfBuffers = 1;
m_SensorModeInfo[CAPTURE].PossibleCount = 1;
m_SensorModeInfo[STILL].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
m_SensorModeInfo[STILL].MaxNumOfBuffers = 1;
m_SensorModeInfo[STILL].PossibleCount = 1;
if( 3 == m_ulCTypes )
{
m_SensorModeInfo[PREVIEW].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED;
m_SensorModeInfo[PREVIEW].MaxNumOfBuffers = 1;
m_SensorModeInfo[PREVIEW].PossibleCount = 1;
}
m_ppModeContext = new LPVOID[m_ulCTypes];
if ( NULL == m_ppModeContext )
{
return ERROR_INSUFFICIENT_BUFFER;
}
m_pCurrentFormat = new CS_DATARANGE_VIDEO[m_ulCTypes];
if( NULL == m_pCurrentFormat )
{
return ERROR_INSUFFICIENT_BUFFER;
}
return ERROR_SUCCESS;
}
DWORD CNullPdd::GetAdapterInfo( PADAPTERINFO pAdapterInfo )
{
pAdapterInfo->ulCTypes = m_ulCTypes;
pAdapterInfo->PowerCaps = PowerCaps;
pAdapterInfo->ulVersionID = DRIVER_VERSION_2; //Camera MDD and DShow support DRIVER_VERSION and DRIVER_VERSION_2. Defined in camera.h
memcpy( &pAdapterInfo->SensorProps, &m_SensorProps, sizeof(m_SensorProps));
return ERROR_SUCCESS;
}
DWORD CNullPdd::HandleVidProcAmpChanges( DWORD dwPropId, LONG lFlags, LONG lValue )
{
PSENSOR_PROPERTY pDevProp = NULL;
pDevProp = m_SensorProps + dwPropId;
if( CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL == lFlags )
{
pDevProp->ulCurrentValue = lValue;
}
pDevProp->ulFlags = lFlags;
return ERROR_SUCCESS;
}
DWORD CNullPdd::HandleCamControlChanges( DWORD dwPropId, LONG lFlags, LONG lValue )
{
PSENSOR_PROPERTY pDevProp = NULL;
pDevProp = m_SensorProps + dwPropId;
if( CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL == lFlags )
{
pDevProp->ulCurrentValue = lValue;
}
pDevProp->ulFlags = lFlags;
return ERROR_SUCCESS;
}
DWORD CNullPdd::HandleVideoControlCapsChanges( LONG lModeType ,ULONG ulCaps )
{
m_pModeVideoCaps[lModeType].CurrentVideoControlCaps = ulCaps;
return ERROR_SUCCESS;
}
DWORD CNullPdd :: SetPowerState( CEDEVICE_POWER_STATE PowerState )
{
return E_NOTIMPL;
}
DWORD CNullPdd::HandleAdapterCustomProperties( PUCHAR pInBuf, DWORD InBufLen, PUCHAR pOutBuf, DWORD OutBufLen, PDWORD pdwBytesTransferred )
{
DEBUGMSG( ZONE_IOCTL, ( _T("IOControl Adapter PDD: Unsupported PropertySet Request\r\n")) );
return ERROR_NOT_SUPPORTED;
}
DWORD CNullPdd::InitSensorMode( ULONG ulModeType, LPVOID ModeContext )
{
ASSERT( ModeContext );
m_ppModeContext[ulModeType] = ModeContext;
return ERROR_SUCCESS;
}
DWORD CNullPdd::DeInitSensorMode( ULONG ulModeType )
{
return ERROR_SUCCESS;
}
DWORD CNullPdd::SetSensorState( ULONG lModeType, CSSTATE csState )
{
DWORD dwError = ERROR_SUCCESS;
switch ( csState )
{
case CSSTATE_STOP:
m_CsState[lModeType] = CSSTATE_STOP;
// Kill the timer to conserve resources
if ( NULL != m_TimerIdentifier[lModeType] )
{
ASSERT( m_pfnTimeKillEvent );
m_pfnTimeKillEvent(m_TimerIdentifier[lModeType]);
m_TimerIdentifier[lModeType] = NULL;
dwError = ERROR_INVALID_PARAMETER;
}
if( STILL == lModeType )
{
m_bStillCapInProgress = false;
}
break;
case CSSTATE_PAUSE:
m_CsState[lModeType] = CSSTATE_PAUSE;
break;
case CSSTATE_RUN:
m_CsState[lModeType] = CSSTATE_RUN;
if ( NULL == m_TimerIdentifier[lModeType] )
{
dwError = ( CreateTimer( lModeType ) ? ERROR_SUCCESS : ERROR_NOT_READY );
}
break;
default:
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("IOControl(%08x): Incorrect State\r\n"), this ) );
dwError = ERROR_INVALID_PARAMETER;
}
return dwError;
}
DWORD CNullPdd::TakeStillPicture( LPVOID pBurstModeInfo )
{
DWORD dwError = ERROR_SUCCESS;
m_bStillCapInProgress = true;
//Ignore pBurstModeInfo
m_CsState[STILL] = CSSTATE_RUN;
if ( NULL == m_TimerIdentifier[STILL] )
{
dwError = ( CreateTimer( STILL ) ? ERROR_SUCCESS : ERROR_NOT_READY );
}
return dwError;
}
DWORD CNullPdd::GetSensorModeInfo( ULONG ulModeType, PSENSORMODEINFO pSensorModeInfo )
{
pSensorModeInfo->MemoryModel = m_SensorModeInfo[ulModeType].MemoryModel;
pSensorModeInfo->MaxNumOfBuffers = m_SensorModeInfo[ulModeType].MaxNumOfBuffers;
pSensorModeInfo->PossibleCount = m_SensorModeInfo[ulModeType].PossibleCount;
pSensorModeInfo->VideoCaps.DefaultVideoControlCaps = DefaultVideoControlCaps[ulModeType];
pSensorModeInfo->VideoCaps.CurrentVideoControlCaps = m_pModeVideoCaps[ulModeType].CurrentVideoControlCaps;
pSensorModeInfo->pVideoFormat = &m_pModeVideoFormat[ulModeType];
return ERROR_SUCCESS;
}
DWORD CNullPdd::SetSensorModeFormat( ULONG ulModeType, PCS_DATARANGE_VIDEO pCsDataRangeVideo )
{
memcpy( &m_pCurrentFormat[ulModeType], pCsDataRangeVideo, sizeof ( CS_DATARANGE_VIDEO ) );
return ERROR_SUCCESS;
}
PVOID CNullPdd::AllocateBuffer( ULONG ulModeType )
{
// Real PDD may want to save off this allocated pointer
// in an array.
ULONG ulFrameSize = CS__DIBSIZE (m_pCurrentFormat[ulModeType].VideoInfoHeader.bmiHeader);
return RemoteLocalAlloc( LPTR, ulFrameSize );
}
DWORD CNullPdd::DeAllocateBuffer( ULONG ulModeType, PVOID pBuffer )
{
RemoteLocalFree( pBuffer );
return ERROR_SUCCESS;
}
DWORD CNullPdd::RegisterClientBuffer( ULONG ulModeType, PVOID pBuffer )
{
// Real PDD may want to save pBuffer which is a pointer to buffer that DShow created.
return ERROR_SUCCESS;
}
DWORD CNullPdd::UnRegisterClientBuffer( ULONG ulModeType, PVOID pBuffer )
{
// DShow is not going to use pBuffer (which was originally allocated by DShow) anymore. If the PDD
// is keeping a cached pBuffer pointer (in RegisterClientBuffer()) then this is the right place to
// stop using it and maybe set the cached pointer to NULL.
// Note: PDD must not delete this pointer as it will be deleted by DShow itself
return ERROR_SUCCESS;
}
DWORD CNullPdd::HandleSensorModeCustomProperties( ULONG ulModeType, PUCHAR pInBuf, DWORD InBufLen, PUCHAR pOutBuf, DWORD OutBufLen, PDWORD pdwBytesTransferred )
{
DEBUGMSG( ZONE_IOCTL, ( _T("IOControl: Unsupported PropertySet Request\r\n")) );
return ERROR_NOT_SUPPORTED;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The following code is only meant for this sample pdd
// The real PDD should not contain any of the code below.
// Instead the real PDD should implement its own FillPinBuffer()
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern "C" { WINGDIAPI HBITMAP WINAPI CreateBitmapFromPointer( CONST BITMAPINFO *pbmi, int iStride, PVOID pvBits); }
DWORD CNullPdd::FillBuffer( ULONG ulModeType, PUCHAR pImage )
{
PCS_VIDEOINFOHEADER pCsVideoInfoHdr = &m_pCurrentFormat[ulModeType].VideoInfoHeader;
UINT biWidth = pCsVideoInfoHdr->bmiHeader.biWidth;
UINT biHeight = pCsVideoInfoHdr->bmiHeader.biHeight;
UINT biSizeImage = pCsVideoInfoHdr->bmiHeader.biSizeImage;
UINT biWidthBytes = CS_DIBWIDTHBYTES (pCsVideoInfoHdr->bmiHeader);
UINT biBitCount = pCsVideoInfoHdr->bmiHeader.biBitCount;
UINT LinesToCopy = abs (biHeight);
DWORD biCompression = pCsVideoInfoHdr->bmiHeader.biCompression;
HBITMAP hbmp = NULL;
HDC hdc = NULL;
if ( (FOURCC_YUY2 == (biCompression & ~BI_SRCPREROTATE)) ||
(FOURCC_YV12 == (biCompression & ~BI_SRCPREROTATE)) )
{
return YUVBufferFill( ulModeType, pImage );
}
// BUGBUG: The bmiheader is actually a bmi, the videoinfoheader is actually a videoinfo.
// BUGBUG: the driver seems to be confused about what a videoinfo is versus a videoinfoheader.
hbmp = CreateBitmapFromPointer((BITMAPINFO*) &(pCsVideoInfoHdr->bmiHeader), biWidthBytes, (PVOID) pImage);
if (hbmp)
{
if(hdc = CreateCompatibleDC(NULL))
{
SelectObject(hdc, hbmp);
// make the box width/height 1/8th of the screen, so it's visible but doesn't
// overwhelm
int nBoxWidth = biWidth/BOXWIDTHDIVIDER;
int nBoxHeight = biHeight/BOXHEIGHTDIVIDER;
float fWidthStep = (float) (biWidth - nBoxWidth)/LOCATIONWIDTHMASK;
float fHeightStep = (float) (biHeight - nBoxHeight)/LOCATIONHEIGHTMASK;
int x, y;
int nTickCount;
int nDirection;
int nLocationX, nLocationY;
nTickCount = GetTickCount() >> SPEEDSHIFT;
// and the result with 0x3 so the value ranges between 0 and 3 for the direction.
nDirection = (nTickCount >> LOCATIONSHIFT) & 0x3;
nLocationX = (int) (fWidthStep * (nTickCount & LOCATIONWIDTHMASK));
nLocationY = (int) (fHeightStep * (nTickCount & LOCATIONHEIGHTMASK));
switch(nDirection)
{
case 0:
x = nLocationX;
y = 0;
break;
case 1:
x = biWidth - nBoxWidth;
y = nLocationY;
break;
case 2:
x = (biWidth - nBoxWidth) - nLocationX;
y = biHeight - nBoxHeight;
break;
case 3:
x = 0;
y = (biHeight - nBoxHeight) - nLocationY;
break;
}
PatBlt(hdc, 0, 0, biWidth, biHeight, WHITENESS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -