⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pindevice.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    {
        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 + -