cameradevice.cpp
来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,760 行 · 第 1/5 页
CPP
1,760 行
// Already open and bound to the process
pCamOpenHandle->cRef++;
LeaveCriticalSection(&m_csDevice);
return pCamOpenHandle;
}
pEntry = pEntry->Flink; // advance to next
}
// first open instance by the process
//
pCamOpenHandle = new CAMERAOPENHANDLE;
if ( pCamOpenHandle )
{
pCamOpenHandle->pCamDevice = this;
pCamOpenHandle->cRef = 1;
pCamOpenHandle->hCallerProcess = hCurrentProc;
InsertHeadList(&m_hCameraOpenHandles, &pCamOpenHandle->lList);
}
LeaveCriticalSection(&m_csDevice);
return pCamOpenHandle;
}
void
CCameraDevice::UnBindApplicationProc(PCAMERAOPENHANDLE pCamOpenHandle)
{
DEBUGMSG( ZONE_FUNCTION, ( _T("CAM_Close: Unbind application from camera device\r\n") ) );
EnterCriticalSection(&m_csDevice);
if(pCamOpenHandle->cRef-- == 1)
{
// Last open instance by the process
RemoveEntryList(&pCamOpenHandle->lList);
}
LeaveCriticalSection(&m_csDevice);
return;
}
bool
CCameraDevice::IsValidPin(
ULONG ulPinId
)
{
if ( ulPinId >= m_ulCTypes )
{
return false;
}
return true;
}
bool
CCameraDevice::IncrCInstances(
ULONG ulPinId,
CPinDevice * pPinDev
)
{
if ( false == IsValidPin( ulPinId ) || 1 == m_StrmInstances[ulPinId].ulCInstances )
{
return false;
}
else
{
m_StrmInstances[ulPinId].ulCInstances++;
m_StrmInstances[ulPinId].pPinDev = pPinDev;
}
return true;
}
bool
CCameraDevice::DecrCInstances(
ULONG ulPinId
)
{
if ( false == IsValidPin( ulPinId ) || 0 == m_StrmInstances[ulPinId].ulCInstances )
{
return false;
}
else
{
m_StrmInstances[ulPinId].ulCInstances--;
m_StrmInstances[ulPinId].pPinDev = NULL;
}
return true;
}
bool
CCameraDevice::PauseCaptureAndPreview( void )
{
/*if ( PREVIEW < m_ulCTypes )
{
if ( m_StrmInstances[PREVIEW].pPinDev )
{
m_StrmInstances[PREVIEW].pPinDev->SetState( CSSTATE_PAUSE, &m_StrmInstances[PREVIEW].CsPrevState );
}
}*/
if ( m_StrmInstances[CAPTURE].pPinDev )
{
m_StrmInstances[CAPTURE].pPinDev->SetState( CSSTATE_PAUSE, &m_StrmInstances[CAPTURE].CsPrevState );
}
return true;
}
bool
CCameraDevice::RevertCaptureAndPreviewState( void )
{
/*if ( PREVIEW < m_ulCTypes )
{
if ( m_StrmInstances[PREVIEW].pPinDev )
{
m_StrmInstances[PREVIEW].pPinDev->SetState( m_StrmInstances[PREVIEW].CsPrevState, NULL );
}
}*/
if ( m_StrmInstances[CAPTURE].pPinDev )
{
m_StrmInstances[CAPTURE].pPinDev->SetState( m_StrmInstances[CAPTURE].CsPrevState, NULL );
}
return true;
}
bool
CCameraDevice::GetPinFormat(
ULONG ulPinId,
ULONG ulIndex,
PCS_DATARANGE_VIDEO * ppCsDataRangeVid
)
{
if ( 0 >= ulIndex || ulIndex > m_PinVideoFormat[ulPinId].ulAvailFormats )
{
return false;
}
*ppCsDataRangeVid = m_PinVideoFormat[ulPinId].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_PinVideoFormat[ulPinId].ulAvailFormats ; ulCount++ )
{
PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_PinVideoFormat[ulPinId].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;
}
// Real Camera drivers can now do ConfigCaps related intersection. Null driver doesn't do such comparison
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_PinVideoFormat[ulPinId].ulAvailFormats ; ulCount++ )
{
PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_PinVideoFormat[ulPinId].pCsDataRangeVideo[ulCount];
if ( false == AdapterCompareGUIDsAndFormatSize( reinterpret_cast<PCSDATARANGE>( pCsDataRangeVideo ),
reinterpret_cast<PCSDATARANGE>( pCsDataVIHToCompare ) ) )
{
continue;
}
if ( true == fDetailedComparison )
{
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 ) );
}
LPVOID
CCameraDevice::ValidateBuffer(
LPVOID lpBuff,
ULONG ulActualBufLen,
ULONG ulExpectedBuffLen,
DWORD * dwError
)
{
LPVOID lpMapped = NULL;
if ( NULL == lpBuff )
{
DEBUGMSG( ZONE_IOCTL, (_T("IOControl(%08x): buffer is NULL\r\n"), this ) );
*dwError = ERROR_INSUFFICIENT_BUFFER;
return NULL;
}
if ( ulActualBufLen < ulExpectedBuffLen )
{
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): buffer is not large enough\r\n"), this ) );
*dwError = ERROR_INSUFFICIENT_BUFFER;
return NULL;
}
if ( NULL == (lpMapped = MapCallerPtr( lpBuff, ulActualBufLen ) ) )
{
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): MapCallerPtr failed for buffer.\r\n"), this ) );
*dwError = ERROR_INVALID_USER_BUFFER;
return NULL;
}
return lpMapped;
}
DWORD
CCameraDevice::AdapterHandleVersion(
PUCHAR pOutBuf,
DWORD OutBufLen,
PDWORD pdwBytesTransferred
)
{
DWORD dwVersion = DRIVER_VERSION;
if( OutBufLen < sizeof( DWORD ))
{
return ERROR_INSUFFICIENT_BUFFER;
}
*pdwBytesTransferred = sizeof( DWORD );
if( !CeSafeCopyMemory( pOutBuf, &dwVersion, sizeof( DWORD )))
{
return ERROR_INVALID_USER_BUFFER;
}
return ERROR_SUCCESS;
}
DWORD
CCameraDevice::AdapterHandlePinRequests(
PUCHAR pInBuf,
DWORD InBufLen,
PUCHAR pOutBuf,
DWORD OutBufLen,
PDWORD pdwBytesTransferred
)
{
DEBUGMSG( ZONE_IOCTL, ( _T("CAM_IOControl(%08x): HandlePinRequests\r\n"), this ) );
DWORD dwError = ERROR_INVALID_PARAMETER;
PCSP_PIN pCsPin = NULL;
PCS_DATARANGE_VIDEO pCsDataRangeVideo = NULL;
PCSMULTIPLE_ITEM pCsMultipleItem = NULL;
PCS_DATAFORMAT_VIDEOINFOHEADER pCsDataFormatVih = NULL;
PCSPIN_CINSTANCES pCsPinCinstances = NULL;
CSPROPERTY csProp = {0};
LONG lPinId = 0;
if( !CeSafeCopyMemory( &csProp, pInBuf, sizeof( CSPROPERTY )))
{
return ERROR_INVALID_PARAMETER;
}
*pdwBytesTransferred = 0;
// we support PROPSETID_Pin, so just return success
if ( CSPROPERTY_TYPE_SETSUPPORT == csProp.Flags )
{
return ERROR_SUCCESS;
}
// we are here so the request is not SETSUPPORT and after this only GET requests will be entertained since
// PROPSETID_Pin contains READ-ONLY properties
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?