📄 pindevice.cpp
字号:
{
DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): State to set = CSSTATE_STOP but we are already Stopped.\r\n"), this ) );
dwError = ERROR_SUCCESS;
break;
}
m_CsState = CSSTATE_STOP;
m_pCamAdapter->PDDSetPinState( m_ulPinId, m_CsState );
// The buffer queue needs to be emptied if the driver is not allocating the buffers
FlushBufferQueue();
dwError = ERROR_SUCCESS;
break;
case CSSTATE_PAUSE:
if ( CSSTATE_PAUSE == m_CsState )
{
DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): State to set = CSSTATE_PAUSE but we are already Paused.\r\n"), this ) );
dwError = ERROR_SUCCESS;
break;
}
dwError = PauseStream();
break;
case CSSTATE_RUN:
if ( CSSTATE_STOP == m_CsState )
{
DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): CSSTATE_STOP to CSSTATE_RUN is not a supported transition .\r\n"), this ) );
dwError = ERROR_INVALID_STATE;
break;
}
// We only allow Still Pin to goto Run state through PROPSETID_VIDCAP_VIDEOCONTROL
if ( STILL == m_ulPinId )
{
dwError = ERROR_SUCCESS;
break;
}
m_CsState = CSSTATE_RUN;
m_msStart = 0xFFFFFFFF;
m_pCamAdapter->PDDSetPinState( m_ulPinId, m_CsState );
dwError = ERROR_SUCCESS;
break;
default :
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Incorrect State\r\n"), this ) );
dwError = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&m_csStreamIO);
break;
default:
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Invalid Request\r\n"), this ) );
break;
}
return dwError;
}
DWORD
CPinDevice::PinHandleCustomRequests(
PUCHAR pInBuf, // Warning: This is an unsafe buffer, access with care
DWORD InBufLen,
PUCHAR pOutBuf, // Warning: This is an unsafe buffer, access with care
DWORD OutBufLen,
PDWORD pdwBytesTransferred // Warning: This is an unsafe buffer, access with care
)
{
return m_pCamAdapter->PDDHandlePinCustomProperties( m_ulPinId, pInBuf, InBufLen, pOutBuf, OutBufLen, pdwBytesTransferred );
}
DWORD
CPinDevice::PinHandleConnDataFormatSubReqs(
ULONG ulReqFlags,
PCS_DATAFORMAT_VIDEOINFOHEADER pCsDataFormatVidInfoHdr, // Warning: this buffer is unsafe, use with caution
PDWORD pdwBytesTransferred
)
{
DWORD dwError = ERROR_INVALID_PARAMETER;
PCSSTATE pCsState = NULL;
PCS_DATARANGE_VIDEO pCsDataRangeVideoMatched = NULL;
// We must have called IOCTL_STREAM_INSTANTIATE before setting format
if ( -1 == m_ulPinId )
{
return dwError;
}
// The incoming video info header is unsafe. The data might change on a separate thread
// while it's being accessed. For security purposes, let's make a copy of the data
// before any attempt to access them is done, and then work off the copy
switch( ulReqFlags )
{
case CSPROPERTY_TYPE_SET:
if ( true == m_pCamAdapter->AdapterCompareFormat( m_ulPinId, pCsDataFormatVidInfoHdr, &pCsDataRangeVideoMatched, true ) )
{
// We found our format
memcpy( &m_CsDataRangeVideo, pCsDataRangeVideoMatched, sizeof ( CS_DATARANGE_VIDEO ) );
memcpy( &m_CsDataRangeVideo, &pCsDataFormatVidInfoHdr->DataFormat, sizeof ( CSDATARANGE ) );
memcpy( &m_CsDataRangeVideo.VideoInfoHeader, &pCsDataFormatVidInfoHdr->VideoInfoHeader, sizeof ( CS_VIDEOINFOHEADER ) );
m_RtAveTimePerFrame = m_CsDataRangeVideo.VideoInfoHeader.AvgTimePerFrame;
dwError = m_pCamAdapter->PDDSetPinFormat( m_ulPinId, &m_CsDataRangeVideo );
*pdwBytesTransferred = 0;
}
break;
default:
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Invalid Request\r\n"), this ) );
}
return dwError;
}
DWORD
CPinDevice::AllocateBuffer( PCS_STREAM_DESCRIPTOR pCsDescriptor, LPVOID pOutBuf, DWORD OutBufLen, DWORD *pdwBytesTransferred )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
DWORD dwResult = -1;
PCS_STREAM_DESCRIPTOR pCsDescriptorOut = (PCS_STREAM_DESCRIPTOR) pOutBuf;
MarshalledBuffer_t MarshalledStreamDesc(pCsDescriptor, sizeof(CS_STREAM_DESCRIPTOR), ARG_O_PTR, FALSE, TRUE);
pCsDescriptor = reinterpret_cast<PCS_STREAM_DESCRIPTOR>( MarshalledStreamDesc.ptr() );
if( NULL == pCsDescriptor )
{
return dwError;
}
// There are 2 cases here: the buffer comes from the hardware or from the software.
// If the buffer comes from the software, we generate a new entry in the table up to the maximum allowed.
// If the buffer comes from the hardware, we setup the application stream descriptor
EnterCriticalSection( &m_csStreamBuffer );
//Check the BufferCount after the critical section is entered.
//This prevents synch issues with validating the BufferCount
if( m_dwBufferCount >= m_ulMaxNumOfBuffers )
{
dwError = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
if( m_dwMemoryModel == CSPROPERTY_BUFFER_DRIVER )
{
if( NULL == pOutBuf || OutBufLen < sizeof(CS_STREAM_DESCRIPTOR) )
{
goto Cleanup;
}
// pOutBuf has already been validated through MapCallerPtr in the IOCTL function
if( pCsDescriptorOut == NULL )
{
goto Cleanup;
}
// Get one of the hardware buffers, and setup the descriptor
ASSERT( m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy == FALSE );
dwError = HwSetupStreamDescriptor( m_dwBufferCount );
if( dwError != ERROR_SUCCESS )
{
goto Cleanup;
}
if( !CeSafeCopyMemory( pCsDescriptorOut, &(m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow), sizeof( CS_STREAM_DESCRIPTOR )))
{
dwError = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
m_pStreamDescriptorList[ m_dwBufferCount ].pCsStreamDescriptorExternal = NULL;
m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy = TRUE;
m_dwBufferCount++;
if( pdwBytesTransferred )
{
*pdwBytesTransferred = sizeof(CS_STREAM_DESCRIPTOR);
}
}
else if( m_dwMemoryModel == CSPROPERTY_BUFFER_CLIENT_LIMITED )
{
// The software is allocated by the software, let's copy the descriptor and generate a handle
ASSERT( m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy == FALSE );
//RETAILMSG(1,(TEXT("AllocBuffer:CeSafeCopyMemory\n")));
if( !CeSafeCopyMemory( &( m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow ), pCsDescriptor, sizeof( CS_STREAM_DESCRIPTOR )))
{
dwError = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
//RETAILMSG(1,(TEXT("AllocBuffer:SwSetupStreamDescriptor\n")));
// Let's populate the handle and the buffer field.
dwError = SwSetupStreamDescriptor( m_dwBufferCount, &( m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow ), pCsDescriptor );
if( dwError != ERROR_SUCCESS )
{
goto Cleanup;
}
//RETAILMSG(1,(TEXT("AllocBuffer:OKay!!!\n")));
m_pStreamDescriptorList[ m_dwBufferCount ].pCsStreamDescriptorExternal = NULL;
m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy = TRUE;
m_dwBufferCount++;
}
else if( m_dwMemoryModel == CSPROPERTY_BUFFER_CLIENT_UNLIMITED )
{
// let's find a slot available
DWORD dwAvailableRow = -1;
for( DWORD i = 0; ( i < m_ulMaxNumOfBuffers ) && ( dwAvailableRow == -1 ); i++ )
{
if( m_pStreamDescriptorList[ i ].m_fBusy == FALSE )
{
dwAvailableRow = i;
}
}
if( dwAvailableRow == -1 )
{
goto Cleanup;
}
if( !CeSafeCopyMemory( &( m_pStreamDescriptorList[ dwAvailableRow ].csStreamDescriptorShadow ), pCsDescriptor, sizeof( CS_STREAM_DESCRIPTOR )))
{
dwError = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
dwError = SwSetupStreamDescriptor( dwAvailableRow, &( m_pStreamDescriptorList[ dwAvailableRow ].csStreamDescriptorShadow ), pCsDescriptor );
if( dwError != ERROR_SUCCESS )
{
goto Cleanup;
}
m_pStreamDescriptorList[ dwAvailableRow ].pCsStreamDescriptorExternal = NULL;
m_pStreamDescriptorList[ dwAvailableRow ].m_fBusy = TRUE;
m_dwBufferCount++;
}
Cleanup:
LeaveCriticalSection( &m_csStreamBuffer );
return dwError;
}
DWORD
CPinDevice::DeallocateBuffer( PCS_STREAM_DESCRIPTOR pCsDescriptor )
{
LPVOID lpBuffer;
DWORD dwHandle;
LONG lIndex;
DWORD dwError = ERROR_SUCCESS;
MarshalledBuffer_t MarshalledStreamDesc(pCsDescriptor, sizeof(CS_STREAM_DESCRIPTOR), ARG_O_PTR, FALSE, TRUE);
pCsDescriptor = reinterpret_cast<PCS_STREAM_DESCRIPTOR>( MarshalledStreamDesc.ptr() );
if( NULL == pCsDescriptor )
{
return dwError;
}
lpBuffer = pCsDescriptor->CsStreamHeader.Data;
dwHandle = pCsDescriptor->CsStreamHeader.Handle;
// Get the entry for this buffer in the internal list
EnterCriticalSection( &m_csStreamBuffer );
//Check if there are any buffers to deallocate
if(0 == m_dwBufferCount)
{
dwError = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
lIndex = GetIndexFromHandle( dwHandle, lpBuffer );
if( lIndex == -1 )
{
dwError = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
// If the row is not in use, let's make it available
if( m_pStreamDescriptorList[ lIndex ].pCsStreamDescriptorExternal != NULL )
{
dwError = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
ASSERT( m_pStreamDescriptorList[ lIndex ].m_fBusy == TRUE );
m_pStreamDescriptorList[ lIndex ].m_fBusy = FALSE;
m_dwBufferCount--;
if( m_dwMemoryModel == CSPROPERTY_BUFFER_DRIVER )
{
// We release the buffer.
dwError = m_pCamAdapter->PDDDeAllocatePinBuffer( m_ulPinId, m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data );
m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data = NULL;
pCsDescriptor->CsStreamHeader.Data = NULL;
}
else
{
dwError = m_pCamAdapter->PDDUnRegisterClientBuffer( m_ulPinId, m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data );
m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data = NULL;
pCsDescriptor->CsStreamHeader.Data = NULL;
}
Cleanup:
LeaveCriticalSection( &m_csStreamBuffer );
return dwError;
}
DWORD
CPinDevice::SwSetupStreamDescriptor(
DWORD dwIndex,
PCS_STREAM_DESCRIPTOR pCsStreamDesc,
LPVOID pBuffer // Warning: This is an unsafe buffer, use with caution
)
{
DWORD dwHandle;
PCS_STREAM_DESCRIPTOR pCsStreamDescExt = ( PCS_STREAM_DESCRIPTOR ) pBuffer;
if(( pCsStreamDesc == NULL ) || ( pBuffer == NULL ))
{
return ERROR_INVALID_PARAMETER;
}
dwHandle = CreateHandle( dwIndex, pBuffer );
__try
{
pCsStreamDescExt->CsStreamHeader.Handle = dwHandle;
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
return ERROR_INVALID_PARAMETER;
}
// Note: This is the place to setup DMA for the buffer.
pCsStreamDesc->CsStreamHeader.Handle = dwHandle;
return m_pCamAdapter->PDDRegisterClientBuffer( m_ulPinId, pCsStreamDesc->CsStreamHeader.Data );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -