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

📄 cameradevice.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//

#include <windows.h>
#include <pm.h>
#include "Cs.h"
#include "Csmedia.h"

#include "CameraPDDProps.h"
#include "dstruct.h"
#include "dbgsettings.h"
#include "CameraDriver.h"

#include "camera.h"
#include "PinDriver.h"

#include "CameraPDD.h"


DWORD MDD_HandleIO( LPVOID ModeContext, ULONG ulModeType )
{
    PPINDEVICE pPinDevice = (PPINDEVICE)ModeContext;
    if( NULL == pPinDevice )
    {
        return ERROR_INVALID_PARAMETER;
    }
    return pPinDevice->HandlePinIO() ;
}

CCameraDevice::CCameraDevice( )
{
    m_hStream        = NULL;
    m_hCallerProcess = NULL;

    m_dwVersion = 0;
    m_PowerState = D0;
    m_PDDContext = NULL;

    memset(&m_PDDFuncTbl, 0, sizeof(PDDFUNCTBL) );
    memset( &m_AdapterInfo, 0, sizeof(ADAPTERINFO ));
    InitializeCriticalSection( &m_csDevice );
    m_pStrmInstances = NULL;

}


CCameraDevice::~CCameraDevice( )
{
    DeleteCriticalSection( &m_csDevice );

    m_PDDFuncTbl.PDD_DeInit( m_PDDContext );

    if( NULL != m_pStrmInstances )
    {
        delete [] m_pStrmInstances;
        m_pStrmInstances = NULL;
    }

    if ( NULL != m_hStream )
    {
        DeactivateDevice( m_hStream );
        m_hStream = NULL;
    }
}


bool
CCameraDevice::Initialize(
    PVOID context
    )
{
    DWORD dwRet = ERROR_SUCCESS;
    m_hStream = ActivateDeviceEx( PIN_REG_PATH, NULL, 0, reinterpret_cast<LPVOID>( this ) );

    if ( NULL == m_hStream )
    {
        DEBUGMSG( ZONE_INIT|ZONE_ERROR, ( _T("CAM_Init: ActivateDevice on Pin failed\r\n") ) );
        return false;
    }

    m_PDDFuncTbl.dwSize = sizeof( PDDFUNCTBL );
    m_PDDContext = PDD_Init( context, &m_PDDFuncTbl );

    if( m_PDDContext == NULL )
    {
        return false;
    }       

    if( m_PDDFuncTbl.dwSize < sizeof( PDDFUNCTBL ) ||
        NULL == m_PDDFuncTbl.PDD_Init || 
        NULL == m_PDDFuncTbl.PDD_DeInit ||
        NULL == m_PDDFuncTbl.PDD_GetAdapterInfo ||
        NULL == m_PDDFuncTbl.PDD_HandleVidProcAmpChanges ||
        NULL == m_PDDFuncTbl.PDD_HandleCamControlChanges ||
        NULL == m_PDDFuncTbl.PDD_HandleVideoControlCapsChanges ||
        NULL == m_PDDFuncTbl.PDD_SetPowerState ||
        NULL == m_PDDFuncTbl.PDD_HandleAdapterCustomProperties ||
        NULL == m_PDDFuncTbl.PDD_InitSensorMode ||
        NULL == m_PDDFuncTbl.PDD_DeInitSensorMode ||
        NULL == m_PDDFuncTbl.PDD_SetSensorState ||
        NULL == m_PDDFuncTbl.PDD_TakeStillPicture ||
        NULL == m_PDDFuncTbl.PDD_GetSensorModeInfo ||
        NULL == m_PDDFuncTbl.PDD_SetSensorModeFormat ||
        NULL == m_PDDFuncTbl.PDD_FillBuffer ||
        NULL == m_PDDFuncTbl.PDD_HandleModeCustomProperties )
    {
        return false;
    }

    dwRet = m_PDDFuncTbl.PDD_GetAdapterInfo( m_PDDContext, &m_AdapterInfo );

    if( ERROR_SUCCESS != dwRet || DRIVER_VERSION > m_AdapterInfo.ulVersionID || DRIVER_VERSION_2 < m_AdapterInfo.ulVersionID )
    {
        return false;
    }

    m_dwVersion = m_AdapterInfo.ulVersionID;

    m_pStrmInstances = new STREAM_INSTANCES[m_AdapterInfo.ulCTypes];
    if( NULL == m_pStrmInstances )
    {
        return false;
    }
    memset( m_pStrmInstances, 0x0, sizeof ( STREAM_INSTANCES ) * m_AdapterInfo.ulCTypes );

    
    if( false == GetPDDPinInfo() )
    {
        delete m_pStrmInstances;
        m_pStrmInstances = NULL;
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("CAM_IOControl(%08x): Failed to retrieve sub-device information\r\n"), this)) ;
        return false ;
    }

    return true;
}

bool
CCameraDevice::GetPDDPinInfo()
{
    SENSORMODEINFO SensorModeInfo;
    if( NULL == m_pStrmInstances )
    {
        return false;
    }

    for( UINT i=0; i < m_AdapterInfo.ulCTypes; i++ )
    {
        if( ERROR_SUCCESS != PDDGetPinInfo( i, &SensorModeInfo ) )
        {
            return false ;
        }
        m_pStrmInstances[i].ulPossibleCount = SensorModeInfo.PossibleCount ;
        m_pStrmInstances[i].VideoCaps.DefaultVideoControlCaps = SensorModeInfo.VideoCaps.DefaultVideoControlCaps;
        m_pStrmInstances[i].VideoCaps.CurrentVideoControlCaps = SensorModeInfo.VideoCaps.CurrentVideoControlCaps;
        m_pStrmInstances[i].pVideoFormat = SensorModeInfo.pVideoFormat;
        
        if( SensorModeInfo.MemoryModel == CSPROPERTY_BUFFER_DRIVER &&
            ( NULL == m_PDDFuncTbl.PDD_AllocateBuffer || NULL == m_PDDFuncTbl.PDD_DeAllocateBuffer ) )
        {
            return false;
        }

        if( SensorModeInfo.MemoryModel != CSPROPERTY_BUFFER_DRIVER &&
            ( NULL == m_PDDFuncTbl.PDD_RegisterClientBuffer || NULL == m_PDDFuncTbl.PDD_UnRegisterClientBuffer ) )
        {
            return false;
        }
    }

    return true;

}

bool
CCameraDevice::BindApplicationProc(
    HANDLE hCurrentProc
    )
{
    if ( NULL != m_hCallerProcess )
    {
        return false;
    }

    m_hCallerProcess = hCurrentProc;

    return true;
}


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

    m_hCallerProcess = NULL;

    return true;
}

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

    return true;
}

bool
CCameraDevice::IncrCInstances(
    ULONG        ulPinId,
    CPinDevice * pPinDev
    )
{
    bool bRet = false;

    if( IsValidPin( ulPinId ) )
    {
        PSTREAM_INSTANCES pStreamInst = &m_pStrmInstances[ulPinId];
        if( pStreamInst->ulCInstances < pStreamInst->ulPossibleCount )
        {
            pStreamInst->ulCInstances++;
// TODO This is memory leak
            pStreamInst->pPinDev = pPinDev;
            bRet = true;
        }

    }

    return bRet;
}

bool
CCameraDevice::DecrCInstances(
    ULONG ulPinId
    )
{
    bool bRet = false;

    if( IsValidPin( ulPinId ) )
    {
        PSTREAM_INSTANCES pStreamInst = &m_pStrmInstances[ulPinId];
        if( 0 < pStreamInst->ulCInstances )
        {
            pStreamInst->ulCInstances--;
// TODO This is memory leak
            pStreamInst->pPinDev = NULL;
            bRet = true;
        }
    }
    return bRet;
}

bool
CCameraDevice::PauseCaptureAndPreview( void )
{
    if ( PREVIEW < m_AdapterInfo.ulCTypes )
    {
        if ( NULL != m_pStrmInstances[PREVIEW].pPinDev )
        {
            m_pStrmInstances[PREVIEW].pPinDev->SetState( CSSTATE_PAUSE, &m_pStrmInstances[PREVIEW].CsPrevState );
        }
    }

    if ( NULL != m_pStrmInstances[CAPTURE].pPinDev )
    {
        m_pStrmInstances[CAPTURE].pPinDev->SetState( CSSTATE_PAUSE, &m_pStrmInstances[CAPTURE].CsPrevState );
    }

    return true;
}

bool
CCameraDevice::RevertCaptureAndPreviewState( void )
{
    if ( PREVIEW < m_AdapterInfo.ulCTypes )
    {
        m_pStrmInstances[PREVIEW].pPinDev->SetState( m_pStrmInstances[PREVIEW].CsPrevState, NULL );
    }

    m_pStrmInstances[CAPTURE].pPinDev->SetState( m_pStrmInstances[CAPTURE].CsPrevState, NULL );

    return true;
}


bool
CCameraDevice::GetPinFormat(
    ULONG                 ulPinId,
    ULONG                 ulIndex,
    PCS_DATARANGE_VIDEO * ppCsDataRangeVid
    )
{
    if( false == IsValidPin( ulPinId ) )
    {
        return false;
    }

    if ( 0 >= ulIndex || ulIndex > m_pStrmInstances[ulPinId].pVideoFormat->ulAvailFormats )
    {
        return false;
    }

    *ppCsDataRangeVid = m_pStrmInstances[ulPinId].pVideoFormat->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_pStrmInstances[ulPinId].pVideoFormat->ulAvailFormats ; ulCount++ )
    {
        PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_pStrmInstances[ulPinId].pVideoFormat->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;
            }
            if( pCsDataRangeVideoToCompare->VideoInfoHeader.AvgTimePerFrame < pCsDataRangeVideo->ConfigCaps.MinFrameInterval  ||
                pCsDataRangeVideoToCompare->VideoInfoHeader.AvgTimePerFrame > pCsDataRangeVideo->ConfigCaps.MaxFrameInterval  )
            {
                continue;
            }

            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_pStrmInstances[ulPinId].pVideoFormat->ulAvailFormats ; ulCount++ )
    {
        PCS_DATARANGE_VIDEO pCsDataRangeVideo = m_pStrmInstances[ulPinId].pVideoFormat->pCsDataRangeVideo[ulCount];

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

        if ( true == fDetailedComparison )
        {
            if( pCsDataVIHToCompare->VideoInfoHeader.AvgTimePerFrame < pCsDataRangeVideo->ConfigCaps.MinFrameInterval  ||
                pCsDataVIHToCompare->VideoInfoHeader.AvgTimePerFrame > pCsDataRangeVideo->ConfigCaps.MaxFrameInterval  )
            {
                continue;
            }

            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 ) );
}


⌨️ 快捷键说明

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