📄 pindevice.cpp
字号:
else
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Timer already created.\r\n"), this));
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: TimerCallBack
//
// DESCRIPTION: Handle the call back of timer
//
// PARAMETERS: None
//
// RETURNS: TRUE if success, otherwise FALSE.
//------------------------------------------------------------------------------
void CPinDevice :: TimerCallBack( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 )
{
UNREFERENCED_PARAMETER(uTimerID) ;
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(dw1);
UNREFERENCED_PARAMETER(dw2);
PPINDEVICE pPinDevice = reinterpret_cast<PPINDEVICE>(dwUser) ;
if (NULL == pPinDevice)
{
DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl: TimerCallBack PinDevice is NULL.\r\n"))) ;
}
else
{
pPinDevice->HandlePinIO() ;
}
}
//------------------------------------------------------------------------------
//
// FUNCTION: InitMsgQueueDescriptor
//
// DESCRIPTION: Handle the call back of timer
//
// PARAMETERS: None
//
// RETURNS: TRUE if success, otherwise FALSE.
//------------------------------------------------------------------------------
BOOL CPinDevice::InitMsgQueueDescriptor (
PCS_MSGQUEUE_BUFFER pCsMsgQBuff,
PCS_STREAM_DESCRIPTOR pCsStreamDesc,
PVOID pMappedData,
PVOID pUnmappedData,
BOOL bBufferFill
)
{
PCSSTREAM_HEADER pCsStreamHeader = reinterpret_cast<PCSSTREAM_HEADER>(pCsStreamDesc);
PCS_FRAME_INFO pCsFrameInfo = reinterpret_cast<PCS_FRAME_INFO>(pCsStreamHeader + 1);
if ((pCsStreamHeader == NULL) || (pCsFrameInfo == NULL))
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("InitMsgQueueDescriptor(%08x): Invalid Stream Descriptor\r\n"), this));
return FALSE;
}
if (bBufferFill)
{
// The buffer fill function must use the pointer that's been mapped into this process.
pCsStreamHeader->Data = pMappedData;
//BUFFERFILLPARAMS buffFillParams;
//m_pCamAdapter->GetBrightness( &(buffFillParams.ulBrightness) );
//m_pCamAdapter->GetZoom( &(buffFillParams.ulZoom) );
EnterCriticalSection(&m_csStreamBuffer) ;
pCsStreamHeader->DataUsed = m_pfnBufferFill( (PUCHAR) pMappedData, reinterpret_cast<PCS_VIDEOINFOHEADER>(&m_CsDataRangeVideo.VideoInfoHeader), IMAGE_GRAY_INCREASING, FALSE, (LPVOID)this ) ;
LeaveCriticalSection(&m_csStreamBuffer) ;
pCsFrameInfo->PictureNumber = (LONGLONG)++m_ulPictureNumber;
pCsFrameInfo->DropCount = (LONGLONG)m_ulFramesDropped;
}
// The message queue requires the original pointer value.
pCsStreamHeader->Data = pUnmappedData;
// Init the flags to zero
pCsStreamHeader->OptionsFlags = 0;
// Set the discontinuity flag if frames have been previously
// dropped, and then reset our internal flag
if (TRUE == m_fDiscontinuity)
{
pCsStreamHeader->OptionsFlags |= CSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY;
m_fDiscontinuity = FALSE;
}
DWORD msNow = GetTickCount();
if (m_msStart == 0xFFFFFFFF)
{
m_msStart = msNow;
}
//
// Return the timestamp for the frame
//
pCsStreamHeader->PresentationTime.Numerator = 1;
pCsStreamHeader->PresentationTime.Denominator = 1;
pCsStreamHeader->Duration = m_RtAveTimePerFrame;
DWORD prevPT = m_msLastPT;
if (bBufferFill)
{
m_msLastPT = msNow - m_msStart;
pCsStreamHeader->PresentationTime.Time = (LONGLONG) m_msLastPT * 10000; // presentation time stamp in 100s of ns
}
else
{
pCsStreamHeader->PresentationTime.Time = 0;
}
DEBUGMSG(ZONE_FUNCTION, (_T("InitMsgQueueDescriptor: LastPT = %d, elapsed = %d\n"), m_msLastPT, m_msLastPT - prevPT));
// clear the timestamp valid flags
pCsStreamHeader->OptionsFlags &= ~( CSSTREAM_HEADER_OPTIONSF_TIMEVALID | CSSTREAM_HEADER_OPTIONSF_DURATIONVALID );
// Every frame we generate is a key frame (aka SplicePoint)
// Delta frames (B or P) should not set this flag
pCsStreamHeader->OptionsFlags |= CSSTREAM_HEADER_OPTIONSF_SPLICEPOINT;
pCsMsgQBuff->CsMsgQueueHeader.Size = sizeof(CS_MSGQUEUE_HEADER);
pCsMsgQBuff->CsMsgQueueHeader.Flags = FLAG_MSGQ_FRAME_BUFFER;
pCsMsgQBuff->CsMsgQueueHeader.Context = NULL;
//Get the unmarshalled StreamDescriptor in order to send the message to the application
pCsMsgQBuff->pStreamDescriptor = NULL;
for (UINT ii = 0; ii < m_dwBufferCount; ii++)
{
if(m_pStreamDescriptorList[ii].csStreamDescriptorShadow.CsStreamHeader.Data == pUnmappedData)
{
pCsMsgQBuff->pStreamDescriptor = m_pStreamDescriptorList[ii].m_pUnMarshalledStreamDesc;
break;
}
}
if(NULL == pCsMsgQBuff->pStreamDescriptor)
{
DEBUGMSG(ZONE_FUNCTION, (_T("InitMsgQueueDescriptor(%08x): Unable to find Unmarshalled Stream Desc\n"), this));
return FALSE;
}
DEBUGMSG(ZONE_FUNCTION, (_T("InitMsgQueueDescriptor(%08x): Frame buf queued: %d (dropped %d), start %d, time %d\n"),
this,
(LONG)pCsFrameInfo->PictureNumber,
(LONG)pCsFrameInfo->DropCount,
(LONG)m_msStart,
(LONG)(pCsStreamHeader->PresentationTime.Time / 10000)));
return TRUE;
}
//------------------------------------------------------------------------------
//
// FUNCTION: FlushBufferQueue
//
// DESCRIPTION: Flush Buffer Queue
//
// PARAMETERS: None
//
// RETURNS: None
//------------------------------------------------------------------------------
void CPinDevice::FlushBufferQueue()
{
PCS_STREAM_DESCRIPTOR pCsStreamDesc = NULL;
PVOID pMappedData = NULL;
PVOID pUnmappedData = NULL;
CS_MSGQUEUE_BUFFER CsMsgQBuff ;
DWORD dwSavedPermissions = SetProcPermissions( (DWORD)-1 ) ;
while (( TRUE == RemoveBufferFromList( &pCsStreamDesc, &pMappedData, &pUnmappedData )) && ( NULL != pCsStreamDesc ) && ( m_hMsgQ != NULL ))
{
if (!InitMsgQueueDescriptor (&CsMsgQBuff, pCsStreamDesc, pMappedData, pUnmappedData, FALSE))
{
continue;
}
if ( FALSE == WriteMsgQueue( m_hMsgQ, reinterpret_cast<LPVOID>(&CsMsgQBuff), sizeof(CS_MSGQUEUE_BUFFER), PIN_TIMEOUT, 0 ) )
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("PIN_Function(%08x): WriteMsgQueue returned false\r\n"), this));
}
}
SetProcPermissions( dwSavedPermissions );
return;
}
//------------------------------------------------------------------------------
//
// FUNCTION: HandlePinIO
//
// DESCRIPTION: Handle Pin IO request
//
// PARAMETERS: None
//
// RETURNS: None
//------------------------------------------------------------------------------
void CPinDevice :: HandlePinIO()
{
DEBUGMSG(ZONE_FUNCTION, (_T("HandlePinIO(%08x): HandlePinIO\r\n"), this)) ;
if ( CSSTATE_RUN != m_CsState )
{
DEBUGMSG(ZONE_FUNCTION, (_T("HandlePinIO(%08x): CSSTATE_RUN != m_CsState\r\n"), this)) ;
return;
}
DEBUGMSG(ZONE_FUNCTION, (_T("HandlePinIO(%08x): CSSTATE_RUN == m_CsState\r\n"), this)) ;
if ( STILL == m_ulPinId )
{
DEBUGMSG(ZONE_IOCTL, (_T("HandlePinIO(%08x): Preparing for STILL capture.\r\n"), this));
m_pCamAdapter->PauseCaptureAndPreview( ) ;
}
DWORD dwSavedPermissions = SetProcPermissions( (DWORD)-1 ) ;
PCS_STREAM_DESCRIPTOR pCsStreamDesc = NULL;
PVOID pMappedData = NULL;
PVOID pUnmappedData = NULL;
CS_MSGQUEUE_BUFFER CsMsgQBuff ;
if ( FALSE == RemoveBufferFromList( &pCsStreamDesc, &pMappedData, &pUnmappedData ) || NULL == pCsStreamDesc )
{
// We dropped a frame
m_ulFramesDropped++;
m_fDiscontinuity = TRUE;
SetProcPermissions( dwSavedPermissions );
return;
}
if (!InitMsgQueueDescriptor (&CsMsgQBuff, pCsStreamDesc, pMappedData, pUnmappedData, TRUE))
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("HandlePinIO(%08x): Invalid Stream Descriptor\r\n"), this)) ;
SetProcPermissions(dwSavedPermissions);
return ;
}
if (NULL == m_hMsgQ)
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("HandlePinIO(%08x): MsgQueue is not opened\r\n"), this)) ;
SetProcPermissions( dwSavedPermissions ) ;
return ;
}
if ( FALSE == WriteMsgQueue( m_hMsgQ, reinterpret_cast<LPVOID>(&CsMsgQBuff), sizeof(CS_MSGQUEUE_BUFFER), PIN_TIMEOUT, 0 ) )
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("HandlePinIO(%08x): WriteMsgQueue returned FALSE\r\n"), this)) ;
}
if (STILL == m_ulPinId)
{
DEBUGMSG(ZONE_IOCTL, (_T("HandlePinIO(%08x): Reverting state after STILL capture.\r\n"), this));
m_CsState = CSSTATE_PAUSE;
m_pCamAdapter->RevertCaptureAndPreviewState( );
}
SetProcPermissions( dwSavedPermissions );
return;
}
//------------------------------------------------------------------------------
//
// FUNCTION: BufferFill
//
// DESCRIPTION: Fill data to buffer
//
// PARAMETERS: PUCHAR pImage,
// PCS_VIDEOINFOHEADER pCsVideoInfoHdr,
// IMAGECOMMAND Command,
// BOOL FlipHorizontal,
// LPVOID lpParam
//
// RETURNS: The size of the image filled
//------------------------------------------------------------------------------
UINT CPinDevice::PinBufferFill(
PUCHAR pImage,
PCS_VIDEOINFOHEADER pCsVideoInfoHdr,
IMAGECOMMAND Command,
BOOL FlipHorizontal,
LPVOID lpParam
)
{
ULONG ulPinId;
DEBUGMSG(ZONE_FUNCTION, (TEXT("PIN_Function(%08x): +BufferFill\r\n"), this));
UNREFERENCED_PARAMETER( Command );
UNREFERENCED_PARAMETER( FlipHorizontal );
DEBUGMSG(ZONE_FUNCTION, (TEXT("PIN_Function(%08x):+BufferFill: EnterCriticalSection\r\n"),this));
ULONG BufferSize = abs(CS__DIBSIZE (pCsVideoInfoHdr->bmiHeader));
PUINT8 pbySrcBuffer, pbyDstBuffer;
prpBufferData prpBuffData;
UINT retVal = 0;
if (m_ulPinId == STILL)
{
ulPinId = m_pCamAdapter->m_StillPinInherited;
}
else
{
ulPinId = m_ulPinId;
}
while (1)
{
switch (ulPinId)
{
case PREVIEW:
{
if (WaitForSingleObject(m_pCamAdapter->m_pPrp->m_hVfEOFEvent, WAIT_BUFFER_TIMEOUT) != WAIT_OBJECT_0)
{
ERRORMSG(ZONE_ERROR, (TEXT("+BufferFill:WaitForSingleObject m_hPrPBuffFilled timeout!\r\n")));
// If camera driver get a fame from PrP timeout. Restart the channel.
m_pCamAdapter->m_pPrp->PrpStopVfChannel();
m_pCamAdapter->m_pPrp->PrpStartVfChannel();
return -1;
}
if (FALSE == m_pCamAdapter->m_pPrp->PrpGetVfBufFilled(&prpBuffData))
{
DEBUGMSG(ZONE_ERROR, (TEXT("+BufferFill:Get viewfinding filled buffer error!\r\n")));
return -1;
}
if (FALSE == m_bDirectMode)
{
//For normal mode, we free the buffer automatically.or we should free it manually.
m_pCamAdapter->m_pPrp->PrpPutVfBufIdle(&prpBuffData);
}
}
break;
case CAPTURE:
{
if (WaitForSingleObject(m_pCamAdapter->m_pPrp->m_hEncEOFEvent, WAIT_BUFFER_TIMEOUT) != WAIT_OBJECT_0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("+BufferFill:WaitForSingleObject m_hPrPBuffFilled timeout!\r\n")));
// If camera driver get a fame from PrP timeout. Restart the channel.
m_pCamAdapter->m_pPrp->PrpStopEncChannel();
m_pCamAdapter->m_pPrp->PrpStartEncChannel();
return -1;
}
if (FALSE == m_pCamAdapter->m_pPrp->PrpGetEncBufFilled(&prpBuffData))
{
DEBUGMSG(ZONE_ERROR, (TEXT("+BufferFill:Get encoder filled buffer error!\r\n")));
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -