📄 pindevice.cpp
字号:
DWORD
CPinDevice::HwSetupStreamDescriptor(
DWORD dwIndex
)
{
PCSSTREAM_HEADER pCsStreamHeader;
PCS_FRAME_INFO pCsFrameInfo;
if( dwIndex > m_dwBufferCount )
{
return ERROR_INVALID_PARAMETER;
}
m_ulFrameSize = CS__DIBSIZE (m_CsDataRangeVideo.VideoInfoHeader.bmiHeader);
pCsStreamHeader = &( m_pStreamDescriptorList[ dwIndex ].csStreamDescriptorShadow.CsStreamHeader );
pCsFrameInfo = &( m_pStreamDescriptorList[ dwIndex ].csStreamDescriptorShadow.CsFrameInfo );
pCsStreamHeader->Size = sizeof(CSSTREAM_HEADER);
pCsStreamHeader->TypeSpecificFlags = 0;
pCsStreamHeader->PresentationTime.Time = 0;
pCsStreamHeader->PresentationTime.Numerator = 1;
pCsStreamHeader->PresentationTime.Denominator = 1;
pCsStreamHeader->Duration = 0;
pCsStreamHeader->FrameExtent = m_ulFrameSize;
pCsStreamHeader->DataUsed = m_ulFrameSize;
pCsStreamHeader->OptionsFlags = CSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY;
pCsFrameInfo->ExtendedHeaderSize = sizeof(CS_FRAME_INFO);
pCsFrameInfo->dwFrameFlags = CS_VIDEO_FLAG_FRAME;
pCsFrameInfo->PictureNumber = 0;
pCsFrameInfo->DropCount = 0;
// Note: RemoteLocalAlloc can't really trigger an exception, the __try/__except block is here
// to highlight the fact that this call has to be protected in the case of a hardware access.
__try
{
pCsStreamHeader->Data = m_pCamAdapter->PDDAllocatePinBuffer( m_ulPinId );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
return ERROR_INTERNAL_ERROR;
}
if( NULL == pCsStreamHeader->Data )
{
return ERROR_OUTOFMEMORY;
}
// And setup the handle
pCsStreamHeader->Handle = CreateHandle( dwIndex, pCsStreamHeader->Data );
return ERROR_SUCCESS;
}
DWORD
CPinDevice::CreateHandle(
DWORD dwIndex,
LPVOID pBuffer
)
{
DWORD dwHandle;
DWORD dwProcessId = GetCallerVMProcessId();
dwHandle = dwProcessId ^ (( dwIndex << 16 ) + ( (DWORD)pBuffer & 0xFFFF ));
return dwHandle;
}
LONG
CPinDevice::GetIndexFromHandle(
DWORD dwHandle,
LPVOID pBuffer // Warning: This is an unsafe buffer, use with caution
)
{
LONG lIndex = -1;
DWORD dwProcessId = GetCallerVMProcessId();
// let's retrieve the index from the handle table and make sure we have a match
lIndex = ( dwHandle ^ dwProcessId ) >> 16;
if( lIndex >= (LONG)m_ulMaxNumOfBuffers || lIndex < 0 )
{
// Invalid index, bail out
return -1;
}
if( ( m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data != pBuffer )
||( m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Handle != dwHandle ))
{
// Something's wrong, bail out
return -1;
}
return lIndex;
}
DWORD
CPinDevice::EnqueueDescriptor( PCS_STREAM_DESCRIPTOR pUnMarshalCsDescriptor )
{
LPVOID lpBuffer, lpMappedBuffer;
DWORD dwHandle;
LONG lIndex;
DWORD dwSize;
DWORD dwError = ERROR_INVALID_PARAMETER;
PCS_VIDEOINFOHEADER pCsVideoInfoHdr;
PCS_STREAM_DESCRIPTOR pCsDescriptor = NULL;
MarshalledBuffer_t *pMarshalledStreamDesc = NULL;
DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): EnqueueDescriptor\r\n"), this ) );
if( m_CsState == CSSTATE_STOP )
{
return ERROR_SERVICE_NOT_ACTIVE;
}
{
MarshalledBuffer_t MarshalledStreamDesc(pUnMarshalCsDescriptor, sizeof(CS_STREAM_DESCRIPTOR), ARG_O_PTR, FALSE, TRUE);
pCsDescriptor = reinterpret_cast<PCS_STREAM_DESCRIPTOR>( MarshalledStreamDesc.ptr() );
if( NULL == pCsDescriptor )
{
return dwError;
}
// First, let's use the handle and the buffer to retrieve the shadow copy
// If an exception happens during the following 2 lines, it will be trapped by the upper level
lpBuffer = pCsDescriptor->CsStreamHeader.Data;
dwHandle = pCsDescriptor->CsStreamHeader.Handle;
}
EnterCriticalSection( &m_csStreamBuffer );
// Get the entry for this buffer in the internal list
lIndex = GetIndexFromHandle( dwHandle, lpBuffer );
if( lIndex == -1 )
{
goto Cleanup;
}
// Is the row in use?
if( m_pStreamDescriptorList[ lIndex ].m_fBusy == FALSE )
{
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): The buffer has not be prepared. Call CS_ALLOCATE first.\r\n"), this ) );
goto Cleanup;
}
if( m_pStreamDescriptorList[ lIndex ].pCsStreamDescriptorExternal != NULL )
{
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): This buffer has already be enqueued.\r\n"), this ) );
goto Cleanup;
}
// Now, let's probe the incoming buffer
pCsVideoInfoHdr = reinterpret_cast<PCS_VIDEOINFOHEADER>( &m_CsDataRangeVideo.VideoInfoHeader );
//dwSize = m_CsDataRangeVideo.VideoInfoHeader.bmiHeader.biSizeImage;
dwSize = m_CsDataRangeVideo.DataRange.SampleSize;
if( m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer != NULL &&
NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->ptr() )
{
m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->Unmarshal();
}
if( m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc != NULL &&
NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->ptr() )
{
m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->Unmarshal();
}
if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc )
{
m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc = new MarshalledBuffer_t();
if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc )
{
dwError = ERROR_OUTOFMEMORY;
goto Cleanup;
}
}
m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->Marshal(pUnMarshalCsDescriptor, sizeof(CS_STREAM_DESCRIPTOR), ARG_O_PTR|MARSHAL_FORCE_ALIAS, FALSE, TRUE);
pCsDescriptor = reinterpret_cast<PCS_STREAM_DESCRIPTOR>( m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->ptr() );
if( NULL == pCsDescriptor )
{
goto Cleanup;
}
//Marshal the data buffer
if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer )
{
m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer = new MarshalledBuffer_t();
if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer )
{
dwError = ERROR_OUTOFMEMORY;
goto Cleanup;
}
}
if(FAILED(m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->Marshal(lpBuffer, //Unmarshalled Src
dwSize, //Size of buffer
ARG_O_PTR|MARSHAL_FORCE_ALIAS, //Pointer is output
FALSE, //Don't force Duplicate
TRUE) //Enable asynch access
))
{
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Unable to marshal data buffer for asynch access.\r\n"), this ) );
dwError = ERROR_OUTOFMEMORY;
goto Cleanup;
}
lpMappedBuffer = m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->ptr();
m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data = lpMappedBuffer;
m_pStreamDescriptorList[ lIndex ].pCsStreamDescriptorExternal = pCsDescriptor;
m_pStreamDescriptorList[ lIndex ].m_pUnMarshalledStreamDesc = (PCS_STREAM_DESCRIPTOR)pUnMarshalCsDescriptor;
if ( false == m_fClientInitialized && CSSTATE_PAUSE == m_CsState )
{
m_fClientInitialized = true;
}
dwError = ERROR_SUCCESS;
Cleanup:
if( ERROR_SUCCESS != dwError && lIndex >= 0 )
{
if( NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer &&
NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->ptr() )
{
m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->Unmarshal();
}
if( NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc &&
NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->ptr() )
{
m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->Unmarshal();
}
}
LeaveCriticalSection( &m_csStreamBuffer );
return dwError;
}
bool
CPinDevice::RemoveBufferFromList(
PCS_STREAM_DESCRIPTOR * ppCsStreamDesc,
PVOID * ppMappedData,
PVOID * ppUnmappedData
)
{
DWORD dwCounter = 0;
bool RetVal = true;
// Let's look in the list of buffers for the first buffer that has a non null external stream descriptor
DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): RemoveBufferFromList\r\n"), this ) );
if(( ppCsStreamDesc == NULL ) || ( ppMappedData == NULL ) || ( ppUnmappedData == NULL ))
{
DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): RemoveBufferFromList - Null pointer has been passed in.\r\n"), this ) );
return RetVal;
}
//Initialize arguments
*ppCsStreamDesc = NULL;
*ppMappedData = NULL;
*ppUnmappedData = NULL;
EnterCriticalSection( &m_csStreamBuffer );
//while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))
while(( dwCounter < m_ulMaxNumOfBuffers ) && ( *ppCsStreamDesc == NULL )) //For "camera and DShow integration test" sub-case 603
{
if( m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal != NULL )
{
//REVIEW: All buffers accessed here should have been marshalled, check if try/except is needed
__try
{
// We found one registered buffer. Let's return it.
*ppCsStreamDesc = m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal;
*ppMappedData = m_pStreamDescriptorList[ dwCounter ].csStreamDescriptorShadow.CsStreamHeader.Data;
*ppUnmappedData = m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal->CsStreamHeader.Data;
m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal = NULL;
m_pStreamDescriptorList[ dwCounter ].csStreamDescriptorShadow.CsStreamHeader.Data = *ppUnmappedData;
break;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl: RemoveBufferFromList - Access Violation.\r\n"))) ;
RetVal = false;
}
}
dwCounter++;
}
LeaveCriticalSection( &m_csStreamBuffer );
if(NULL == *ppMappedData)
{
RetVal = false;
}
return RetVal;
}
bool
CPinDevice::ResetBufferList()
{
EnterCriticalSection( &m_csStreamBuffer );
if( m_pStreamDescriptorList )
{
for( DWORD i = 0; i < m_ulMaxNumOfBuffers; i++ )
{
if(m_pStreamDescriptorList[ i ].m_pMarshalledDataBuffer != NULL)
{
delete m_pStreamDescriptorList[ i ].m_pMarshalledDataBuffer;
m_pStreamDescriptorList[ i ].m_pMarshalledDataBuffer = NULL;
}
if(m_pStreamDescriptorList[ i ].m_pMarshalledStreamDesc != NULL)
{
delete m_pStreamDescriptorList[ i ].m_pMarshalledStreamDesc;
m_pStreamDescriptorList[ i ].m_pMarshalledStreamDesc = NULL;
}
m_pStreamDescriptorList[ i ].pCsStreamDescriptorExternal = NULL;
m_pStreamDescriptorList[ i ].m_fBusy = FALSE;
}
}
LeaveCriticalSection( &m_csStreamBuffer );
return true;
}
ULONG CPinDevice :: PictureNumber( ) const
{
return m_ulPictureNumber;
}
ULONG CPinDevice :: FramesDropped( ) const
{
return m_ulFramesDropped;
}
ULONG CPinDevice :: FrameSize( ) const
{
return m_ulFrameSize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -