cameradevice.cpp

来自「该BSP是基于PXA270+WINCE的BSP」· C++ 代码 · 共 1,760 行 · 第 1/5 页

CPP
1,760
字号
            // Already open and bound to the process
            pCamOpenHandle->cRef++;

            LeaveCriticalSection(&m_csDevice);

            return pCamOpenHandle;
        }
        pEntry = pEntry->Flink;  // advance to next
    }

    // first open instance by the process
    //
    pCamOpenHandle = new CAMERAOPENHANDLE;

    if ( pCamOpenHandle )
    {
        pCamOpenHandle->pCamDevice     = this;
        pCamOpenHandle->cRef           = 1;
        pCamOpenHandle->hCallerProcess = hCurrentProc;

        InsertHeadList(&m_hCameraOpenHandles, &pCamOpenHandle->lList);
    }

    LeaveCriticalSection(&m_csDevice);

    return pCamOpenHandle;
}

void
CCameraDevice::UnBindApplicationProc(PCAMERAOPENHANDLE pCamOpenHandle)
{
    DEBUGMSG( ZONE_FUNCTION, ( _T("CAM_Close: Unbind application from camera device\r\n") ) );

    EnterCriticalSection(&m_csDevice);
    if(pCamOpenHandle->cRef-- == 1)
    {
        // Last open instance by the process
        RemoveEntryList(&pCamOpenHandle->lList);
    }
    LeaveCriticalSection(&m_csDevice);
    return;
}

bool
CCameraDevice::IsValidPin(
    ULONG ulPinId
    )
{
    if ( ulPinId >= m_ulCTypes )
    {
        return false;
    }

    return true;
}

bool
CCameraDevice::IncrCInstances(
    ULONG        ulPinId,
    CPinDevice * pPinDev
    )
{
    if ( false == IsValidPin( ulPinId ) || 1 == m_StrmInstances[ulPinId].ulCInstances )
    {
        return false;
    }
    else
    {
        m_StrmInstances[ulPinId].ulCInstances++;
        m_StrmInstances[ulPinId].pPinDev = pPinDev;
    }

    return true;
}

bool
CCameraDevice::DecrCInstances(
    ULONG ulPinId
    )
{
    if ( false == IsValidPin( ulPinId ) || 0 == m_StrmInstances[ulPinId].ulCInstances )
    {
        return false;
    }
    else
    {
        m_StrmInstances[ulPinId].ulCInstances--;
        m_StrmInstances[ulPinId].pPinDev = NULL;
    }

    return true;
}

bool
CCameraDevice::PauseCaptureAndPreview( void )
{
    /*if ( PREVIEW < m_ulCTypes )
    {
        if ( m_StrmInstances[PREVIEW].pPinDev )
        {
            m_StrmInstances[PREVIEW].pPinDev->SetState( CSSTATE_PAUSE, &m_StrmInstances[PREVIEW].CsPrevState );
        }
    }*/

    if ( m_StrmInstances[CAPTURE].pPinDev )
    {
        m_StrmInstances[CAPTURE].pPinDev->SetState( CSSTATE_PAUSE, &m_StrmInstances[CAPTURE].CsPrevState );
    }

    return true;
}

bool
CCameraDevice::RevertCaptureAndPreviewState( void )
{
    /*if ( PREVIEW < m_ulCTypes )
    {
        if ( m_StrmInstances[PREVIEW].pPinDev )
        {
            m_StrmInstances[PREVIEW].pPinDev->SetState( m_StrmInstances[PREVIEW].CsPrevState, NULL );
        }
    }*/

    if ( m_StrmInstances[CAPTURE].pPinDev )
    {
        m_StrmInstances[CAPTURE].pPinDev->SetState( m_StrmInstances[CAPTURE].CsPrevState, NULL );
    }

    return true;
}


bool
CCameraDevice::GetPinFormat(
    ULONG                 ulPinId,
    ULONG                 ulIndex,
    PCS_DATARANGE_VIDEO * ppCsDataRangeVid
    )
{
    if ( 0 >= ulIndex || ulIndex > m_PinVideoFormat[ulPinId].ulAvailFormats )
    {
        return false;
    }

    *ppCsDataRangeVid = m_PinVideoFormat[ulPinId].pCsDataRangeVideo[ulIndex-1];

    return true;
}


bool
CCameraDevice::AdapterCompareFormat(
    ULONG                       ulPinId,
    const PCS_DATARANGE_VIDEO   pCsDataRangeVideoToCompare,
    PCS_DATARANGE_VIDEO       * ppCsDataRangeVideoMatched,
    bool                        fDetailedComparison
    )
{
    for ( ULONG ulCount = 0 ; ulCount < m_PinVideoFormat[ulPinId].ulAvailFormats ; ulCount++ )
    {
        PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_PinVideoFormat[ulPinId].pCsDataRangeVideo[ulCount];

        if ( false == AdapterCompareGUIDsAndFormatSize( reinterpret_cast<PCSDATARANGE>( pCsDataRangeVideo ),
                                                        reinterpret_cast<PCSDATARANGE>( pCsDataRangeVideoToCompare ) ) )
        {
            continue;
        }

        if ( true == fDetailedComparison )
        {
            if ( ( pCsDataRangeVideoToCompare->bFixedSizeSamples != pCsDataRangeVideo->bFixedSizeSamples )
                  || ( pCsDataRangeVideoToCompare->bTemporalCompression   != pCsDataRangeVideo->bTemporalCompression )
                  || ( pCsDataRangeVideoToCompare->StreamDescriptionFlags != pCsDataRangeVideo->StreamDescriptionFlags )
                  || ( pCsDataRangeVideoToCompare->MemoryAllocationFlags  != pCsDataRangeVideo->MemoryAllocationFlags ) )
            {
                continue;
            }
            // Real Camera drivers can now do ConfigCaps related intersection. Null driver doesn't do such comparison
            if ( 0 != memcmp(&pCsDataRangeVideoToCompare->VideoInfoHeader.bmiHeader, &pCsDataRangeVideo->VideoInfoHeader.bmiHeader, sizeof (pCsDataRangeVideo->VideoInfoHeader.bmiHeader) ) )
            {
                continue;
            }

        }

        // You can now perform more granular comparison involving ConfigCaps and VIDOINFOHEADER etc.

        /////////////////////////////////////////
        if ( NULL != ppCsDataRangeVideoMatched )
        {
            *ppCsDataRangeVideoMatched = pCsDataRangeVideo;
        }

        return true;
    }

    return false;
}


bool
CCameraDevice::AdapterCompareFormat(
    ULONG                                  ulPinId,
    const PCS_DATAFORMAT_VIDEOINFOHEADER   pCsDataVIHToCompare,
    PCS_DATARANGE_VIDEO                  * ppCsDataRangeVideoMatched,
    bool                                   fDetailedComparison
    )
{
    for ( ULONG ulCount = 0 ; ulCount < m_PinVideoFormat[ulPinId].ulAvailFormats ; ulCount++ )
    {
        PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_PinVideoFormat[ulPinId].pCsDataRangeVideo[ulCount];

        if ( false == AdapterCompareGUIDsAndFormatSize( reinterpret_cast<PCSDATARANGE>( pCsDataRangeVideo ),
                                                        reinterpret_cast<PCSDATARANGE>( pCsDataVIHToCompare ) ) )
        {
            continue;
        }

        if ( true == fDetailedComparison )
        {
            if ( 0 != memcmp(&pCsDataVIHToCompare->VideoInfoHeader.bmiHeader, &pCsDataRangeVideo->VideoInfoHeader.bmiHeader, sizeof (pCsDataRangeVideo->VideoInfoHeader.bmiHeader) ) )
            {
                continue;
            }
        }

        // You can now perform more granular comparison involving ConfigCaps and VIDOINFOHEADER etc.

        /////////////////////////////////////////
        if ( NULL != ppCsDataRangeVideoMatched )
        {
            *ppCsDataRangeVideoMatched = pCsDataRangeVideo;
        }

        return true;
    }

    return false;
}


bool
CCameraDevice::AdapterCompareGUIDsAndFormatSize(
    const PCSDATARANGE DataRange1,
    const PCSDATARANGE DataRange2
    )
{
    return ( IsEqualGUID( DataRange1->MajorFormat, DataRange2->MajorFormat )
             && IsEqualGUID( DataRange1->SubFormat, DataRange2->SubFormat )
             && IsEqualGUID( DataRange1->Specifier, DataRange2->Specifier ) );
}


LPVOID
CCameraDevice::ValidateBuffer(
    LPVOID   lpBuff,
    ULONG    ulActualBufLen,
    ULONG    ulExpectedBuffLen,
    DWORD  * dwError
    )
{
    LPVOID lpMapped = NULL;

    if ( NULL == lpBuff )
    {
        DEBUGMSG( ZONE_IOCTL, (_T("IOControl(%08x): buffer is NULL\r\n"), this ) );
        *dwError = ERROR_INSUFFICIENT_BUFFER;

        return NULL;
    }

    if ( ulActualBufLen < ulExpectedBuffLen )
    {
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): buffer is not large enough\r\n"), this ) );
        *dwError = ERROR_INSUFFICIENT_BUFFER;

        return NULL;
    }

    if ( NULL == (lpMapped = MapCallerPtr( lpBuff, ulActualBufLen ) ) )
    {
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): MapCallerPtr failed for buffer.\r\n"), this ) );
        *dwError = ERROR_INVALID_USER_BUFFER;

        return NULL;
    }

    return lpMapped;
}


DWORD
CCameraDevice::AdapterHandleVersion( 
    PUCHAR pOutBuf,
    DWORD  OutBufLen,
    PDWORD pdwBytesTransferred
    )
{
    DWORD dwVersion = DRIVER_VERSION;

    if( OutBufLen < sizeof( DWORD ))
    {
        return ERROR_INSUFFICIENT_BUFFER;
    }

    *pdwBytesTransferred = sizeof( DWORD );

    if( !CeSafeCopyMemory( pOutBuf, &dwVersion, sizeof( DWORD )))
    {
        return ERROR_INVALID_USER_BUFFER;
    }

    return ERROR_SUCCESS;
}


DWORD
CCameraDevice::AdapterHandlePinRequests(
    PUCHAR pInBuf,
    DWORD  InBufLen,
    PUCHAR pOutBuf,
    DWORD  OutBufLen,
    PDWORD pdwBytesTransferred
    )
{
    DEBUGMSG( ZONE_IOCTL, ( _T("CAM_IOControl(%08x): HandlePinRequests\r\n"), this ) );

    DWORD                          dwError           = ERROR_INVALID_PARAMETER;
    PCSP_PIN                       pCsPin            = NULL;
    PCS_DATARANGE_VIDEO            pCsDataRangeVideo = NULL;
    PCSMULTIPLE_ITEM               pCsMultipleItem   = NULL;
    PCS_DATAFORMAT_VIDEOINFOHEADER pCsDataFormatVih  = NULL;
    PCSPIN_CINSTANCES              pCsPinCinstances  = NULL;

    CSPROPERTY                      csProp = {0};
    LONG                            lPinId = 0;

    if( !CeSafeCopyMemory( &csProp, pInBuf, sizeof( CSPROPERTY )))
    {
        return ERROR_INVALID_PARAMETER;
    }

    *pdwBytesTransferred = 0;

    // we support PROPSETID_Pin, so just return success
    if ( CSPROPERTY_TYPE_SETSUPPORT == csProp.Flags )
    {
        return ERROR_SUCCESS;
    }

    // we are here so the request is not SETSUPPORT and after this only GET requests will be entertained since
    // PROPSETID_Pin contains READ-ONLY properties

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?