📄 pindevice.cpp
字号:
//------------------------------------------------------------------------------
ULONG CPinDevice :: FrameSize( ) const
{
return m_ulFrameSize;
}
//------------------------------------------------------------------------------
//
// FUNCTION: StreamInstantiate
//
// DESCRIPTION: Initiate a stream instance
//
// PARAMETERS: PCSPROPERTY_STREAMEX_S pCsPropStreamEx,
// PUCHAR pOutBuf,
// DWORD OutBufLen,
// PDWORD pdwBytesTransferred
//
// RETURNS: ERROR_SUCCESS if successfully, otherwise return ERROR_INVALID_PARAMETER
//
//------------------------------------------------------------------------------
DWORD CPinDevice :: StreamInstantiate( PCSPROPERTY_STREAMEX_S pCsPropStreamEx, PUCHAR pOutBuf, DWORD OutBufLen, PDWORD pdwBytesTransferred )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
HANDLE hProcess = NULL;
PCS_DATARANGE_VIDEO pCsDataRangeVid = NULL;
DEBUGMSG(ZONE_IOCTL, (_T("+StreamInstantiate\r\n")));
if ( -1 != m_ulPinId )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Pin %d is already instantiated.\r\n"), this, m_ulPinId )) ;
return dwError ;
}
if ( FALSE == m_pCamAdapter->IsValidPin( pCsPropStreamEx->CsPin.PinId ) )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Invalid Pin Id\r\n"), this)) ;
return dwError ;
}
m_ulPinId = pCsPropStreamEx->CsPin.PinId ;
DEBUGMSG(ZONE_FUNCTION, (_T("PIN_IOControl(%08x): m_ulPinId = %d \r\n"),this, m_ulPinId)) ;
// Let us set a default format for this pin
// for STILL Pin, we can only use the format that Preview or Capture pin use.
if (m_ulPinId == STILL)
{
if (m_pCamAdapter->m_StrmInstances[PREVIEW].pPinDev != NULL)
{
memcpy(&m_CsDataRangeVideo, &m_pCamAdapter->m_StrmInstances[PREVIEW].pPinDev->m_CsDataRangeVideo, sizeof(CS_DATARANGE_VIDEO));
m_RtAveTimePerFrame = m_CsDataRangeVideo.VideoInfoHeader.AvgTimePerFrame;
m_pCamAdapter->m_StillPinInherited = PREVIEW;
}
else if (m_pCamAdapter->m_StrmInstances[CAPTURE].pPinDev != NULL)
{
memcpy(&m_CsDataRangeVideo, &m_pCamAdapter->m_StrmInstances[CAPTURE].pPinDev->m_CsDataRangeVideo, sizeof(CS_DATARANGE_VIDEO));
m_RtAveTimePerFrame = m_CsDataRangeVideo.VideoInfoHeader.AvgTimePerFrame;
m_pCamAdapter->m_StillPinInherited = CAPTURE;
}
else
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Still pin can not be initiated before capture and preview pins.\r\n"), this)) ;
return dwError;
}
}
else
{
if (FALSE == m_pCamAdapter->GetPinFormat(m_ulPinId, 1, &pCsDataRangeVid))
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): No Pin Format provided for pin\r\n"), this)) ;
return dwError ;
}
memcpy(&m_CsDataRangeVideo, pCsDataRangeVid, sizeof(CS_DATARANGE_VIDEO)) ;
m_RtAveTimePerFrame = m_CsDataRangeVideo.VideoInfoHeader.AvgTimePerFrame;
}
DEBUGMSG(ZONE_IOCTL, (_T("StreamInstantiate: Setting a default format for this pin done.\r\n")));
m_pCamAdapter->CameraMarkAsModified(m_ulPinId);
// Initialize Preprocessor buffer filled event if not already created.
if (m_hPrPBuffFilled == NULL)
{
m_hPrPBuffFilled = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hPrPBuffFilled == NULL)
{
ERRORMSG(ZONE_ERROR, (TEXT("CSI_Init: CreateEvent m_hPrPBuffFilled failed!\r\n")));
return dwError;
}
}
if ( NULL == pCsPropStreamEx->hMsgQueue )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): NULL Handle provided for msgqueue\r\n"), this)) ;
return dwError ;
}
if ( FALSE == m_pCamAdapter->IncrCInstances( m_ulPinId, this ) )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Pin %d is already instantiated.\r\n"), this, m_ulPinId)) ;
return dwError ;
}
//TODO : Check whether the client created msgqueue with enough buffersize and number of buffers.
MSGQUEUEOPTIONS msgQueueOptions;
msgQueueOptions.bReadAccess = FALSE; // we need write-access to msgqueue
msgQueueOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
hProcess = OpenProcess(NULL, FALSE, GetCallerVMProcessId());
if( NULL == hProcess )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Failed to open Process\r\n"), this));
return dwError;
}
if ( NULL == (m_hMsgQ = OpenMsgQueue(hProcess, pCsPropStreamEx->hMsgQueue, &msgQueueOptions ) ) )
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Failed to open MsgQueue\r\n"), this));
m_pCamAdapter->DecrCInstances( m_ulPinId ) ;
return dwError ;
}
//if (GetCurrentMemoryModel() == CSPROPERTY_BUFFER_DRIVER)
//{
// Initialize driver buffers
// AllocateDriverBuffers();
//}
DEBUGMSG(ZONE_IOCTL, (_T("-StreamInstantiate\r\n")));
return ERROR_SUCCESS ;
}
//------------------------------------------------------------------------------
//
// FUNCTION: SetState
//
// DESCRIPTION: Set Pin state
//
// PARAMETERS: CSSTATE csState
// CSSTATE *CsPrevState
//
// RETURNS: None
//
//------------------------------------------------------------------------------
DWORD CPinDevice :: SetState(CSSTATE csState, CSSTATE *CsPrevState)
{
DWORD dwError = ERROR_INVALID_PARAMETER;
UINT32 pinId;
if (NULL != CsPrevState)
*CsPrevState = m_CsState ;
if (csState == m_CsState)
{
dwError = ERROR_SUCCESS;
return dwError;
}
switch (csState)
{
case CSSTATE_STOP:
DEBUGMSG(ZONE_IOCTL, (_T("SetState(%08x): Set CSSTATE_STOP\r\n"), this));
m_ulPictureNumber = 0;
m_ulFramesDropped = 0;
m_msLastPT = 0;
m_CsState = CSSTATE_STOP;
// Kill the timer to conserve resources
if (NULL != m_TimerIdentifier)
{
ASSERT(m_pfnTimeKillEvent);
m_pfnTimeKillEvent(m_TimerIdentifier);
m_TimerIdentifier = NULL;
m_fClientInitialized = FALSE;
}
// The buffer queue needs to be emptied if the driver is not allocating the buffers
FlushBufferQueue();
if ((m_ulPinId == PREVIEW))
{
if (FALSE == m_pCamAdapter->m_pPrp->PrpStopVfChannel())
{
break;
}
}
else if ((m_ulPinId == CAPTURE))
{
if (FALSE == m_pCamAdapter->m_pPrp->PrpStopEncChannel())
{
break;
}
}
dwError = ERROR_SUCCESS;
break;
case CSSTATE_PAUSE:
DEBUGMSG(ZONE_IOCTL, (_T("SetState(%08x): Set CSSTATE_PAUSE\r\n"), this));
pinId = m_ulPinId;
if (FALSE == m_pCamAdapter->CameraConfig(pinId, m_ulMaxNumOfBuffers))
{
DEBUGMSG(ZONE_IOCTL, (_T("PIN_IOControl(%08x): Config camera failed!\r\n"), this));
break;
}
dwError = PauseStream();
break;
case CSSTATE_RUN:
DEBUGMSG(ZONE_IOCTL, (_T("SetState(%08x): Set CSSTATE_RUN\r\n"), this));
//TODO : not sure if we should completely block transitioning from STOP->RUN state.
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;
}
m_CsState = CSSTATE_RUN;
m_msStart = 0xFFFFFFFF;
if (m_ulPinId == PREVIEW)
{
if (FALSE == m_pCamAdapter->m_pPrp->PrpStartVfChannel())
{
break;
}
}
else if (m_ulPinId == CAPTURE)
{
if (FALSE == m_pCamAdapter->m_pPrp->PrpStartEncChannel())
{
break;
}
}
dwError = ERROR_SUCCESS;
if (NULL == m_TimerIdentifier)
{
dwError = (CreateTimer() ? ERROR_SUCCESS : ERROR_NOT_READY);
}
break;
default :
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Incorrect State\r\n"), this));
dwError = ERROR_INVALID_PARAMETER;
}
return dwError;
}
//------------------------------------------------------------------------------
//
// FUNCTION: AllocateDriverBuffers
//
// DESCRIPTION: Allocates driver buffers.
// This function is called when a stream is
// initialized.client calls
// IOCTL_CS_ALLOCATE_BUFFERS, or when the data
// format changes and the buffers must be
// reallocated.
//
// PARAMETERS: None
//
// RETURNS: TRUE if success, otherwise FALSE.
//
//------------------------------------------------------------------------------
BOOL CPinDevice :: AllocateDriverBuffers()
{
DEBUGMSG(ZONE_IOCTL, ( _T("PIN_IOControl(%08x): AllocateDriverBuffers\r\n"), this));
m_ulFrameSize = abs(CS__DIBSIZE(m_CsDataRangeVideo.VideoInfoHeader.bmiHeader)); // by bytes
// Call down to Prp to allocate new buffers
switch (m_ulPinId)
{
case PREVIEW:
if (!m_pCamAdapter->m_pPrp->PrpAllocateVfBuffers(m_ulMaxNumOfBuffers, m_ulFrameSize))
{
DEBUGMSG(ZONE_ERROR,(_T("AllocateDriverBuffers: Prp Buffer allocation failed.\r\n")));
return FALSE;
}
break;
case CAPTURE:
if (!m_pCamAdapter->m_pPrp->PrpAllocateEncBuffers(m_ulMaxNumOfBuffers, m_ulFrameSize))
{
DEBUGMSG(ZONE_ERROR,(_T("AllocateDriverBuffers: Prp Buffer allocation failed.\r\n")));
return FALSE;
}
break;
case STILL:
// No need to allocate buffers in the Prp, as those buffers
// will already have been allocated by the Still Pin's
// channel (enc or vf).
break;
default:
DEBUGMSG(ZONE_ERROR,(_T("AllocateDriverBuffers: Invalid pin id.\r\n"))) ;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: CreateTimer
//
// DESCRIPTION: Creat timer for each pin.
//
// PARAMETERS: None
//
// RETURNS: TRUE if success, otherwise FALSE.
//------------------------------------------------------------------------------
BOOL CPinDevice :: CreateTimer()
{
if (NULL == m_hTimerDll)
{
m_hTimerDll = LoadLibrary(L"mmtimer.dll");
m_pfnTimeSetEvent = (FNTIMESETEVENT)GetProcAddress(m_hTimerDll, L"timeSetEvent");
m_pfnTimeKillEvent = (FNTIMEKILLEVENT)GetProcAddress(m_hTimerDll, L"timeKillEvent");
if (NULL == m_pfnTimeSetEvent || NULL == m_pfnTimeKillEvent)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): GetProcAddress Returned Null.\r\n"), this));
return FALSE;
}
}
if (NULL == m_hTimerDll)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): LoadLibrary failedr.\r\n"), this));
return FALSE;
}
ASSERT( m_pfnTimeSetEvent );
if (NULL == m_TimerIdentifier)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Creating new timer. m_RtAveTimePerFrame = %d\r\n"), this, m_RtAveTimePerFrame)) ;
//m_TimerIdentifier = m_pfnTimeSetEvent((ULONG)m_RtAveTimePerFrame/10000, 100, CPinDevice::TimerCallBack, reinterpret_cast<DWORD>(this), TIME_PERIODIC|TIME_CALLBACK_FUNCTION);
m_TimerIdentifier = m_pfnTimeSetEvent( (ULONG)m_RtAveTimePerFrame/10000, 10, CPinDevice::TimerCallBack, reinterpret_cast<DWORD>(this), TIME_PERIODIC|TIME_CALLBACK_FUNCTION);
if (NULL == m_TimerIdentifier)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Timer could not be created.\r\n"), this)) ;
return FALSE;
}
DEBUGMSG(ZONE_IOCTL, (_T("PIN_IOControl(%08x): Timer created successfully.\r\n"), this)) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -