📄 pindevice.cpp
字号:
{
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/20000, 15, 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;
}
else
DEBUGMSG(ZONE_IOCTL, (_T("PIN_IOControl(%08x): Timer created successfully.\r\n"), this)) ;
}
else
{
DEBUGMSG(ZONE_IOCTL, (_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: 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)
m_pCamAdapter->PauseCaptureAndPreview();
DWORD dwSavedPermissions = SetProcPermissions((DWORD)-1);
PCS_STREAM_DESCRIPTOR pCsStreamDesc = NULL;
if (false == RemoveBufferFromList(&pCsStreamDesc) || NULL == pCsStreamDesc)
{
// We dropped a frame
m_ulFramesDropped++ ;
m_fDiscontinuity = true ;
SetProcPermissions(dwSavedPermissions) ;
return ;
}
DEBUGMSG(ZONE_FUNCTION, (_T("HandlePinIO(%08x): RemoveBufferFromList done!\r\n"), this)) ;
PCSSTREAM_HEADER pCsStreamHeader = reinterpret_cast<PCSSTREAM_HEADER>(pCsStreamDesc) ;
PCS_FRAME_INFO pCsFrameInfo = reinterpret_cast<PCS_FRAME_INFO>(pCsStreamHeader + 1) ;
if ( NULL == pCsStreamHeader || NULL == pCsFrameInfo )
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("HandlePinIO(%08x): Invalid Stream Descriptor\r\n"), this)) ;
SetProcPermissions(dwSavedPermissions);
return ;
}
pCsFrameInfo->PictureNumber = (LONGLONG)++m_ulPictureNumber;
pCsFrameInfo->DropCount = (LONGLONG)m_ulFramesDropped;
// Copy data from driver buffer to stream
BufferFill(pCsStreamHeader, pCsFrameInfo, IMAGE_GRAY_INCREASING, false);
// 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 ;
}
//
// Return the timestamp for the frame
//
pCsStreamHeader->PresentationTime.Numerator = 1;
pCsStreamHeader->PresentationTime.Denominator = 1;
pCsStreamHeader->Duration = m_RtAveTimePerFrame;
//
// Since driver does not provide a clock, so just mark the time as unknown
// Incase we need to provide a clock, then we'll have to put a check for preview stream which,
// under no circumstances, uses a clock.
//
pCsStreamHeader->PresentationTime.Time = 0;
// 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;
if (NULL == m_hMsgQ)
{
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("HandlePinIO(%08x): MsgQueue is not opened\r\n"), this)) ;
SetProcPermissions(dwSavedPermissions);
return ;
}
CS_MSGQUEUE_BUFFER CsMsgQBuff;
CsMsgQBuff.CsMsgQueueHeader.Size = sizeof(CS_MSGQUEUE_HEADER);
CsMsgQBuff.CsMsgQueueHeader.Flags = FLAG_MSGQ_FRAME_BUFFER;
CsMsgQBuff.CsMsgQueueHeader.Context = NULL;
CsMsgQBuff.pStreamDescriptor = pCsStreamDesc;
if (CsMsgQBuff.pStreamDescriptor == NULL)
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("HandlePinIO(%08x):fillbuffer return NULL.\r\n"), this)) ;
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)
{
m_CsState = CSSTATE_PAUSE;
m_pCamAdapter->RevertCaptureAndPreviewState();
}
SetProcPermissions(dwSavedPermissions);
return ;
}
/********************************************************************
*
* FUNCTION: BufferFill
*
* DESCRIPTION: Fill data to buffer
*
* PARAMETERS: PCSSTREAM_HEADER pCsStreamHeader,
* PCS_FRAME_INFO pCsFrameInfo,
* IMAGECOMMAND Command,
* bool FlipHorizontal
*
* RETURNS: None
********************************************************************/
void CPinDevice :: BufferFill(
PCSSTREAM_HEADER pCsStreamHeader,
PCS_FRAME_INFO pCsFrameInfo,
IMAGECOMMAND Command,
bool FlipHorizontal
)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("PIN_Function(%08x): +BufferFill\r\n"), this));
UNREFERENCED_PARAMETER( Command );
UNREFERENCED_PARAMETER( FlipHorizontal );
EnterCriticalSection(&m_csStreamBuffer) ;
DEBUGMSG(ZONE_FUNCTION, (TEXT("PIN_Function(%08x):+BufferFill: EnterCriticalSection\r\n"),this));
PCS_VIDEOINFOHEADER pCsVideoInfoHdr = reinterpret_cast<PCS_VIDEOINFOHEADER>(&m_CsDataRangeVideo.VideoInfoHeader) ;
ULONG BufferSize = CS__DIBSIZE (pCsVideoInfoHdr->bmiHeader);
PUINT8 pbySrcBuffer, pbyDstBuffer;
DWORD ReferencePin;
while (1)
{
switch (m_ulPinId)
{
case PREVIEW:
if (WaitForSingleObject(m_pCamAdapter->m_pPrp->m_hVfEOFEvent, INFINITE) != WAIT_OBJECT_0)
{
ERRORMSG(ZONE_ERROR, (TEXT("+BufferFill:WaitForSingleObject m_hPrPBuffFilled timeout!\r\n")));
break;
}
pbySrcBuffer = (UINT8 *)m_pCamAdapter->m_pPrp->PrpGetVfBufFilled();
break;
case CAPTURE:
if (WaitForSingleObject(m_pCamAdapter->m_pPrp->m_hEncEOFEvent, INFINITE) != WAIT_OBJECT_0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("+BufferFill:WaitForSingleObject m_hPrPBuffFilled timeout!\r\n")));
break;
}
pbySrcBuffer = (UINT8 *) m_pCamAdapter->m_pPrp->PrpGetEncBufFilled();
break;
case STILL:
ReferencePin = m_pCamAdapter->m_StillPinInherited;
if (ReferencePin == PREVIEW)
{
if (WaitForSingleObject(m_pCamAdapter->m_pPrp->m_hVfEOFEvent, INFINITE) != WAIT_OBJECT_0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("+BufferFill:WaitForSingleObject m_hVfEOFEvent timeout!\r\n")));
break;
}
DEBUGMSG(ZONE_FUNCTION,(_T("BufferFill: m_pVirtAddrVfBuf.\r\n"))) ;
pbySrcBuffer = (UINT8*) m_pCamAdapter->m_pPrp->PrpGetVfBufFilled();
}
else if (ReferencePin = CAPTURE)
{
if (WaitForSingleObject(m_pCamAdapter->m_pPrp->m_hEncEOFEvent, INFINITE) != WAIT_OBJECT_0)
{
DEBUGMSG(ZONE_ERROR, (TEXT("+BufferFill:WaitForSingleObject m_hEncEOFEvent timeout!\r\n")));
break;
}
RETAILMSG(ZONE_FUNCTION,(_T("BufferFill: m_pVirtAddrEncBuf2.\r\n"))) ;
pbySrcBuffer = (UINT8 *) m_pCamAdapter->m_pPrp->PrpGetEncBufFilled();
}
break;
default:
DEBUGMSG(ZONE_ERROR,(_T("BufferFill: Invalid pin id.\r\n"))) ;
LeaveCriticalSection(&m_csStreamBuffer);
return;
}
// If we got a buffer from Prp, exit loop and continue.
// If there was no buffer returned, loop again and wait for one.
if (pbySrcBuffer != NULL)
{
break;
}
}
pbyDstBuffer = reinterpret_cast<PUINT8>(pCsStreamHeader->Data);
memcpy(pbyDstBuffer, pbySrcBuffer, BufferSize);
//DEBUGMSG(ZONE_FUNCTION, (TEXT("+BufferFill:buffer filled success!\r\n")));
/*for(UINT8 i = 0; i < 8; i++)
DEBUGMSG(1, (TEXT("0x%02x "), pbyDstBuffer[i]));
DEBUGMSG(1, (TEXT("\r\n")));*/
pCsStreamHeader->DataUsed = BufferSize;
LeaveCriticalSection(&m_csStreamBuffer);
DEBUGMSG(ZONE_FUNCTION, (TEXT("-BufferFill\r\n")));
}
/********************************************************************
*
* FUNCTION: PauseStream
*
* DESCRIPTION: Pause stream. if not creat timer, creat it.
*
* PARAMETERS: None
*
* RETURNS: Returns m_fClientInitialized
********************************************************************/
bool CPinDevice :: PauseStream()
{
m_CsState = CSSTATE_PAUSE;
if (false == m_fClientInitialized)
{
// By this time the buffers must be allocated
m_fClientInitialized = CreateTimer();
}
return m_fClientInitialized;
}
/********************************************************************
*
* FUNCTION: PinHandleConnectionRequests
*
* DESCRIPTION: Examine or set the state of a connection on a pin
*
* PARAMETERS: PUCHAR pInBuf,
* DWORD InBufLen,
* PUCHAR pOutBuf,
* DWORD OutBufLen,
* PDWORD pdwBytesTransferred
*
* RETURNS: Returns ERROR_SUCCESS if the operation completes successfully;
* otherwise, returns a Microsoft Win32 error code.
*
********************************************************************/
DWORD CPinDevice :: PinHandleConnectionRequests(
PUCHAR pInBuf,
DWORD InBufLen,
PUCHAR pOutBuf,
DWORD OutBufLen,
PDWORD pdwBytesTransferred
)
{
DEBUGMSG(ZONE_IOCTL, (_T("PIN_IOControl(%08x): PinHandleConnectionRequests\r\n"), this));
PCSPROPERTY pCsProp = NULL;
DWORD dwError = ERROR_INVALID_PARAMETER;
PCSALLOCATOR_FRAMING pCsAllocatorFraming = NULL;
PCS_DATAFORMAT_VIDEOINFOHEADER pCsDataFormatVidInfoHdr = NULL;
pCsProp = reinterpret_cast<PCSPROPERTY>(m_pCamAdapter->ValidateBuffer(pInBuf, InBufLen, sizeof(CSPROPERTY), &dwError));
if (NULL == pCsProp)
{
return dwError;
}
*pdwBytesTransferred = 0;
// we support PROPSETID_Pin, so just return success
if (CSPROPERTY_TYPE_SETSUPPORT == pCsProp->Flags)
{
return ERROR_SUCCESS;
}
switch (pCsProp->Id)
{
case CSPROPERTY_CONNECTION_STATE:
dwError = PinHandleConnStateSubReqs(pCsProp->Flags, pOutBuf, OutBufLen, pdwBytesTransferred);
break;
case CSPROPERTY_CONNECTION_DATAFORMAT:
if(NULL == (pCsDataFormatVidInfoHdr = reinterpret_cast<PCS_DATAFORMAT_VIDEOINFOHEADER>(m_pCamAdapter->ValidateBuffer(pOutBuf,
OutBufLen, sizeof(CS_DATAFORMAT_VIDEOINFOHEADER), &dwError))))
{
return dwError;
}
dwError = PinHandleConnDataFormatSubReqs(pCsProp->Flags, pCsDataFormatVidInfoHdr, pdwBytesTransferred);
break;
case CSPROPERTY_CONNECTION_ALLOCATORFRAMING:
switch (pCsProp->Flags)
{
case CSPROPERTY_TYPE_GET:
*pdwBytesTransferred = sizeof(CSALLOCATOR_FRAMING);
if(NULL == (pCsAllocatorFraming = reinterpret_cast<PCSALLOCATOR_FRAMING>(m_pCamAdapter->ValidateBuffer(pOutBuf, OutBufLen, sizeof(CSALLOCATOR_FRAMING), &dwError))))
{
dwError = ERROR_MORE_DATA;
break;
}
pCsAllocatorFraming->RequirementsFlags = CSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY |CSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY;
pCsAllocatorFraming->PoolType = PagedPool;
//TODO : put PIN_GUID specific decision about number of max. frames
pCsAllocatorFraming->Frames = m_ulMaxNumOfBuffers;
pCsAllocatorFraming->FrameSize = m_CsDataRangeVideo.VideoInfoHeader.bmiHeader.biSizeImage;
pCsAllocatorFraming->FileAlignment = FILE_BYTE_ALIGNMENT;
pCsAllocatorFraming->Reserved = 0;
dwError = ERROR_SUCCESS;
break ;
case CSPROPERTY_TYPE_SET:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -