📄 cameradevice.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include <windows.h>
#include <pm.h>
#include "Cs.h"
#include "Csmedia.h"
#include "CameraPDDProps.h"
#include "dstruct.h"
#include "dbgsettings.h"
#include "CameraDriver.h"
#include "camera.h"
#include "PinDriver.h"
#include "CameraPDD.h"
DWORD MDD_HandleIO( LPVOID ModeContext, ULONG ulModeType )
{
PPINDEVICE pPinDevice = (PPINDEVICE)ModeContext;
if( NULL == pPinDevice )
{
return ERROR_INVALID_PARAMETER;
}
return pPinDevice->HandlePinIO() ;
}
CCameraDevice::CCameraDevice( )
{
m_hStream = NULL;
m_hCallerProcess = NULL;
m_dwVersion = 0;
m_PowerState = D0;
m_PDDContext = NULL;
memset(&m_PDDFuncTbl, 0, sizeof(PDDFUNCTBL) );
memset( &m_AdapterInfo, 0, sizeof(ADAPTERINFO ));
InitializeCriticalSection( &m_csDevice );
m_pStrmInstances = NULL;
}
CCameraDevice::~CCameraDevice( )
{
DeleteCriticalSection( &m_csDevice );
m_PDDFuncTbl.PDD_DeInit( m_PDDContext );
if( NULL != m_pStrmInstances )
{
delete [] m_pStrmInstances;
m_pStrmInstances = NULL;
}
if ( NULL != m_hStream )
{
DeactivateDevice( m_hStream );
m_hStream = NULL;
}
}
bool
CCameraDevice::Initialize(
PVOID context
)
{
DWORD dwRet = ERROR_SUCCESS;
m_hStream = ActivateDeviceEx( PIN_REG_PATH, NULL, 0, reinterpret_cast<LPVOID>( this ) );
if ( NULL == m_hStream )
{
DEBUGMSG( ZONE_INIT|ZONE_ERROR, ( _T("CAM_Init: ActivateDevice on Pin failed\r\n") ) );
return false;
}
m_PDDFuncTbl.dwSize = sizeof( PDDFUNCTBL );
m_PDDContext = PDD_Init( context, &m_PDDFuncTbl );
if( m_PDDContext == NULL )
{
return false;
}
if( m_PDDFuncTbl.dwSize < sizeof( PDDFUNCTBL ) ||
NULL == m_PDDFuncTbl.PDD_Init ||
NULL == m_PDDFuncTbl.PDD_DeInit ||
NULL == m_PDDFuncTbl.PDD_GetAdapterInfo ||
NULL == m_PDDFuncTbl.PDD_HandleVidProcAmpChanges ||
NULL == m_PDDFuncTbl.PDD_HandleCamControlChanges ||
NULL == m_PDDFuncTbl.PDD_HandleVideoControlCapsChanges ||
NULL == m_PDDFuncTbl.PDD_SetPowerState ||
NULL == m_PDDFuncTbl.PDD_HandleAdapterCustomProperties ||
NULL == m_PDDFuncTbl.PDD_InitSensorMode ||
NULL == m_PDDFuncTbl.PDD_DeInitSensorMode ||
NULL == m_PDDFuncTbl.PDD_SetSensorState ||
NULL == m_PDDFuncTbl.PDD_TakeStillPicture ||
NULL == m_PDDFuncTbl.PDD_GetSensorModeInfo ||
NULL == m_PDDFuncTbl.PDD_SetSensorModeFormat ||
NULL == m_PDDFuncTbl.PDD_FillBuffer ||
NULL == m_PDDFuncTbl.PDD_HandleModeCustomProperties )
{
return false;
}
dwRet = m_PDDFuncTbl.PDD_GetAdapterInfo( m_PDDContext, &m_AdapterInfo );
if( ERROR_SUCCESS != dwRet || DRIVER_VERSION > m_AdapterInfo.ulVersionID || DRIVER_VERSION_2 < m_AdapterInfo.ulVersionID )
{
return false;
}
m_dwVersion = m_AdapterInfo.ulVersionID;
m_pStrmInstances = new STREAM_INSTANCES[m_AdapterInfo.ulCTypes];
if( NULL == m_pStrmInstances )
{
return false;
}
memset( m_pStrmInstances, 0x0, sizeof ( STREAM_INSTANCES ) * m_AdapterInfo.ulCTypes );
if( false == GetPDDPinInfo() )
{
delete m_pStrmInstances;
m_pStrmInstances = NULL;
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("CAM_IOControl(%08x): Failed to retrieve sub-device information\r\n"), this)) ;
return false ;
}
return true;
}
bool
CCameraDevice::GetPDDPinInfo()
{
SENSORMODEINFO SensorModeInfo;
if( NULL == m_pStrmInstances )
{
return false;
}
for( UINT i=0; i < m_AdapterInfo.ulCTypes; i++ )
{
if( ERROR_SUCCESS != PDDGetPinInfo( i, &SensorModeInfo ) )
{
return false ;
}
m_pStrmInstances[i].ulPossibleCount = SensorModeInfo.PossibleCount ;
m_pStrmInstances[i].VideoCaps.DefaultVideoControlCaps = SensorModeInfo.VideoCaps.DefaultVideoControlCaps;
m_pStrmInstances[i].VideoCaps.CurrentVideoControlCaps = SensorModeInfo.VideoCaps.CurrentVideoControlCaps;
m_pStrmInstances[i].pVideoFormat = SensorModeInfo.pVideoFormat;
if( SensorModeInfo.MemoryModel == CSPROPERTY_BUFFER_DRIVER &&
( NULL == m_PDDFuncTbl.PDD_AllocateBuffer || NULL == m_PDDFuncTbl.PDD_DeAllocateBuffer ) )
{
return false;
}
if( SensorModeInfo.MemoryModel != CSPROPERTY_BUFFER_DRIVER &&
( NULL == m_PDDFuncTbl.PDD_RegisterClientBuffer || NULL == m_PDDFuncTbl.PDD_UnRegisterClientBuffer ) )
{
return false;
}
}
return true;
}
bool
CCameraDevice::BindApplicationProc(
HANDLE hCurrentProc
)
{
if ( NULL != m_hCallerProcess )
{
return false;
}
m_hCallerProcess = hCurrentProc;
return true;
}
bool
CCameraDevice::UnBindApplicationProc( )
{
DEBUGMSG( ZONE_FUNCTION, ( _T("CAM_Close: Unbind application from camera device\r\n") ) );
m_hCallerProcess = NULL;
return true;
}
bool
CCameraDevice::IsValidPin(
ULONG ulPinId
)
{
if ( ulPinId >= m_AdapterInfo.ulCTypes )
{
return false;
}
return true;
}
bool
CCameraDevice::IncrCInstances(
ULONG ulPinId,
CPinDevice * pPinDev
)
{
bool bRet = false;
if( IsValidPin( ulPinId ) )
{
PSTREAM_INSTANCES pStreamInst = &m_pStrmInstances[ulPinId];
if( pStreamInst->ulCInstances < pStreamInst->ulPossibleCount )
{
pStreamInst->ulCInstances++;
// TODO This is memory leak
pStreamInst->pPinDev = pPinDev;
bRet = true;
}
}
return bRet;
}
bool
CCameraDevice::DecrCInstances(
ULONG ulPinId
)
{
bool bRet = false;
if( IsValidPin( ulPinId ) )
{
PSTREAM_INSTANCES pStreamInst = &m_pStrmInstances[ulPinId];
if( 0 < pStreamInst->ulCInstances )
{
pStreamInst->ulCInstances--;
// TODO This is memory leak
pStreamInst->pPinDev = NULL;
bRet = true;
}
}
return bRet;
}
bool
CCameraDevice::PauseCaptureAndPreview( void )
{
if ( PREVIEW < m_AdapterInfo.ulCTypes )
{
if ( NULL != m_pStrmInstances[PREVIEW].pPinDev )
{
m_pStrmInstances[PREVIEW].pPinDev->SetState( CSSTATE_PAUSE, &m_pStrmInstances[PREVIEW].CsPrevState );
}
}
if ( NULL != m_pStrmInstances[CAPTURE].pPinDev )
{
m_pStrmInstances[CAPTURE].pPinDev->SetState( CSSTATE_PAUSE, &m_pStrmInstances[CAPTURE].CsPrevState );
}
return true;
}
bool
CCameraDevice::RevertCaptureAndPreviewState( void )
{
if ( PREVIEW < m_AdapterInfo.ulCTypes )
{
m_pStrmInstances[PREVIEW].pPinDev->SetState( m_pStrmInstances[PREVIEW].CsPrevState, NULL );
}
m_pStrmInstances[CAPTURE].pPinDev->SetState( m_pStrmInstances[CAPTURE].CsPrevState, NULL );
return true;
}
bool
CCameraDevice::GetPinFormat(
ULONG ulPinId,
ULONG ulIndex,
PCS_DATARANGE_VIDEO * ppCsDataRangeVid
)
{
if( false == IsValidPin( ulPinId ) )
{
return false;
}
if ( 0 >= ulIndex || ulIndex > m_pStrmInstances[ulPinId].pVideoFormat->ulAvailFormats )
{
return false;
}
*ppCsDataRangeVid = m_pStrmInstances[ulPinId].pVideoFormat->pCsDataRangeVideo[ulIndex-1];
return true;
}
bool
CCameraDevice::AdapterCompareFormat(
ULONG ulPinId,
const PCS_DATARANGE_VIDEO pCsDataRangeVideoToCompare,
PCS_DATARANGE_VIDEO * ppCsDataRangeVideoMatched,
bool fDetailedComparison
)
{
for ( ULONG ulCount = 0 ; ulCount < m_pStrmInstances[ulPinId].pVideoFormat->ulAvailFormats ; ulCount++ )
{
PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_pStrmInstances[ulPinId].pVideoFormat->pCsDataRangeVideo[ulCount];
if ( false == AdapterCompareGUIDsAndFormatSize( reinterpret_cast<PCSDATARANGE>( pCsDataRangeVideo ),
reinterpret_cast<PCSDATARANGE>( pCsDataRangeVideoToCompare ) ) )
{
continue;
}
if ( true == fDetailedComparison )
{
if ( ( pCsDataRangeVideoToCompare->bFixedSizeSamples != pCsDataRangeVideo->bFixedSizeSamples )
|| ( pCsDataRangeVideoToCompare->bTemporalCompression != pCsDataRangeVideo->bTemporalCompression )
|| ( pCsDataRangeVideoToCompare->StreamDescriptionFlags != pCsDataRangeVideo->StreamDescriptionFlags )
|| ( pCsDataRangeVideoToCompare->MemoryAllocationFlags != pCsDataRangeVideo->MemoryAllocationFlags ) )
{
continue;
}
if( pCsDataRangeVideoToCompare->VideoInfoHeader.AvgTimePerFrame < pCsDataRangeVideo->ConfigCaps.MinFrameInterval ||
pCsDataRangeVideoToCompare->VideoInfoHeader.AvgTimePerFrame > pCsDataRangeVideo->ConfigCaps.MaxFrameInterval )
{
continue;
}
if ( 0 != memcmp(&pCsDataRangeVideoToCompare->VideoInfoHeader.bmiHeader, &pCsDataRangeVideo->VideoInfoHeader.bmiHeader, sizeof (pCsDataRangeVideo->VideoInfoHeader.bmiHeader) ) )
{
continue;
}
}
// You can now perform more granular comparison involving ConfigCaps and VIDOINFOHEADER etc.
/////////////////////////////////////////
if ( NULL != ppCsDataRangeVideoMatched )
{
*ppCsDataRangeVideoMatched = pCsDataRangeVideo;
}
return true;
}
return false;
}
bool
CCameraDevice::AdapterCompareFormat(
ULONG ulPinId,
const PCS_DATAFORMAT_VIDEOINFOHEADER pCsDataVIHToCompare,
PCS_DATARANGE_VIDEO * ppCsDataRangeVideoMatched,
bool fDetailedComparison
)
{
for ( ULONG ulCount = 0 ; ulCount < m_pStrmInstances[ulPinId].pVideoFormat->ulAvailFormats ; ulCount++ )
{
PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_pStrmInstances[ulPinId].pVideoFormat->pCsDataRangeVideo[ulCount];
if ( false == AdapterCompareGUIDsAndFormatSize( reinterpret_cast<PCSDATARANGE>( pCsDataRangeVideo ),
reinterpret_cast<PCSDATARANGE>( pCsDataVIHToCompare ) ) )
{
continue;
}
if ( true == fDetailedComparison )
{
if( pCsDataVIHToCompare->VideoInfoHeader.AvgTimePerFrame < pCsDataRangeVideo->ConfigCaps.MinFrameInterval ||
pCsDataVIHToCompare->VideoInfoHeader.AvgTimePerFrame > pCsDataRangeVideo->ConfigCaps.MaxFrameInterval )
{
continue;
}
if ( 0 != memcmp(&pCsDataVIHToCompare->VideoInfoHeader.bmiHeader, &pCsDataRangeVideo->VideoInfoHeader.bmiHeader, sizeof (pCsDataRangeVideo->VideoInfoHeader.bmiHeader) ) )
{
continue;
}
}
// You can now perform more granular comparison involving ConfigCaps and VIDOINFOHEADER etc.
/////////////////////////////////////////
if ( NULL != ppCsDataRangeVideoMatched )
{
*ppCsDataRangeVideoMatched = pCsDataRangeVideo;
}
return true;
}
return false;
}
bool
CCameraDevice::AdapterCompareGUIDsAndFormatSize(
const PCSDATARANGE DataRange1,
const PCSDATARANGE DataRange2
)
{
return ( IsEqualGUID( DataRange1->MajorFormat, DataRange2->MajorFormat )
&& IsEqualGUID( DataRange1->SubFormat, DataRange2->SubFormat )
&& IsEqualGUID( DataRange1->Specifier, DataRange2->Specifier ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -