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

📄 pindevice.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.
//

#define PININTERFACE
#include <windows.h>
#include <pm.h>
#include <Msgqueue.h>
#include <pwinbase.h>

#include "Cs.h"
#include "Csmedia.h"

#include "CameraPDDProps.h"
#include "dstruct.h"
#include "dbgsettings.h"
#include <camera.h>
#include "CameraDriver.h"
#include "PinDriver.h"
#include "wchar.h"


CPinDevice :: CPinDevice( )
{
    m_dwMemoryModel             = CSPROPERTY_BUFFER_CLIENT_LIMITED;
    m_fClientInitialized        = false;
    m_fDiscontinuity            = true;
    m_ulPinId                   = -1; // Invalid Pin Id
    m_ulMaxNumOfBuffers         = 0;
    m_ulFrameSize               = 0;
    m_ulFramesDropped           = 0;
    m_ulPictureNumber           = 0;
    m_RtAveTimePerFrame         = 0;
    m_hMsgQ                     = NULL;
    m_CsState                   = CSSTATE_STOP;
    m_msStart                   = 0xFFFFFFFF;
    m_msLastPT                  = 0;
    m_pStreamDescriptorList     = NULL;
    m_dwBufferCount             = 0;
    m_lStillCount               = 0;    

    InitializeCriticalSection( &m_csStreamBuffer );    
    InitializeCriticalSection( &m_csStreamIO );    
}

CPinDevice :: ~CPinDevice( )
{
    ResetBufferList( );
    
    if ( NULL != m_hMsgQ )
    {
        CloseMsgQueue( m_hMsgQ );
    }

    if ( NULL != m_pStreamDescriptorList )
    {
        LocalFree( m_pStreamDescriptorList );
        m_pStreamDescriptorList = NULL;
    }

    m_CsState = CSSTATE_STOP;
    DeleteCriticalSection( &m_csStreamBuffer );
    DeleteCriticalSection( &m_csStreamIO );
}

bool CPinDevice :: InitializeSubDevice( PCAMERADEVICE pCamDevice )
{
    TCHAR *tszLibraryName = NULL;
    TCHAR *tszFunctionName = NULL;
    DWORD dwDataSize = 0;
    DWORD dwDataType = 0;

    m_pCamAdapter = pCamDevice ;
    if (NULL == m_pCamAdapter)
    {
        return false ;   
    }

    return true ;
}

DWORD CPinDevice :: CloseSubDevice()
{
    DWORD dwRet = FALSE;
    dwRet = m_pCamAdapter->DecrCInstances( m_ulPinId ) ;
    if( dwRet )
    {
        dwRet = m_pCamAdapter->PDDClosePin( m_ulPinId );
    }

    return dwRet;
}


DWORD CPinDevice :: StreamInstantiate( PCSPROPERTY_STREAMEX_S pCsPropStreamEx, PUCHAR pOutBuf, DWORD  OutBufLen, PDWORD pdwBytesTransferred )
{
    DWORD   dwError  = ERROR_INVALID_PARAMETER;
    HANDLE  hProcess = NULL;
    PCS_DATARANGE_VIDEO pCsDataRangeVid = NULL;

    
    if ( -1 != m_ulPinId )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Pin %d is already instantiated.\r\n"), this, m_ulPinId )) ;
        return dwError ;
    }

    if( NULL == m_pCamAdapter )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Initialization incomplete.\r\n"), this, m_ulPinId )) ;
        return dwError;
    }

    if ( false == m_pCamAdapter->IsValidPin( pCsPropStreamEx->CsPin.PinId ) )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Invalid Pin Id\r\n"), this)) ;
        return dwError ;
    }
    
    m_ulPinId = pCsPropStreamEx->CsPin.PinId ;
    
    SENSORMODEINFO SensorModeInfo;
    if( ERROR_SUCCESS != m_pCamAdapter->PDDGetPinInfo( m_ulPinId, &SensorModeInfo ) )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Failed to retrieve sub-device information\r\n"), this)) ;
        return dwError ;
    }

    m_dwMemoryModel     = SensorModeInfo.MemoryModel;
    m_ulMaxNumOfBuffers = SensorModeInfo.MaxNumOfBuffers;
    
    // Let us set a default format for this pin

    if ( false == m_pCamAdapter->GetPinFormat( m_ulPinId, 1, &pCsDataRangeVid ) )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): No Pin Format provided for pin\r\n"), this)) ;
        return dwError ;
    }
    
    memcpy(&m_CsDataRangeVideo,pCsDataRangeVid, sizeof(CS_DATARANGE_VIDEO) ) ;

    if ( NULL == pCsPropStreamEx->hMsgQueue )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): NULL Handle provided for msgqueue\r\n"), this)) ;
        return dwError ;
    }    

    //TODO : Check whether the client created msgqueue with enough buffersize and number of buffers.

    MSGQUEUEOPTIONS msgQueueOptions;
    msgQueueOptions.bReadAccess = FALSE; // we need write-access to msgqueue
    msgQueueOptions.dwSize      = sizeof(MSGQUEUEOPTIONS);

    hProcess = OpenProcess(NULL, FALSE, GetCallerVMProcessId());
    if(NULL == hProcess)
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Failed to open Process\r\n"), this)) ;
        return dwError ;
    }

    ASSERT( m_hMsgQ == NULL );

    if ( NULL == (m_hMsgQ = OpenMsgQueue(hProcess, pCsPropStreamEx->hMsgQueue, &msgQueueOptions ) ) )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Failed to open MsgQueue\r\n"), this)) ;
        CloseHandle(hProcess);
        return dwError ;
    }

    CloseHandle(hProcess);

    if ( false == m_pCamAdapter->IncrCInstances( m_ulPinId, this ) )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Pin %d is already instantiated.\r\n"), this, m_ulPinId)) ;
        return dwError ;
    }

    return ERROR_SUCCESS ;
}

void CPinDevice :: SetState( CSSTATE CsState, CSSTATE *CsPrevState )
{
    EnterCriticalSection(&m_csStreamIO);
    if ( NULL != CsPrevState )
    {
        *CsPrevState = m_CsState ;
    }

     //Check if we are not already in the target state
    if(m_CsState != CsState)
    {
        m_CsState = CsState ;

        if ( STILL != m_ulPinId || CSSTATE_RUN != CsState )
        {
            m_pCamAdapter->PDDSetPinState( m_ulPinId, CsState );
        }

        if( STILL == m_ulPinId && CSSTATE_RUN == CsState )
        {
            m_fDiscontinuity = true;
        }
        
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("Pin: %d Setting State to 0x%X\r\n"), m_ulPinId, CsState)) ;
    }
    LeaveCriticalSection(&m_csStreamIO);
    return ;
}

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);
    //    RETAILMSG(1,(TEXT("InitMsgQueueDescriptor\n")));
    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.
        //RETAILMSG(1,(TEXT("bBufferFill\n")));
        pCsStreamHeader->Data = pMappedData;

        EnterCriticalSection(&m_csStreamBuffer) ;
        pCsStreamHeader->DataUsed = m_pCamAdapter->PDDFillPinBuffer( m_ulPinId, (PUCHAR) pMappedData ) ;
        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;

    m_msLastPT = msNow - m_msStart;
    pCsStreamHeader->PresentationTime.Time        = (LONGLONG) m_msLastPT * 10000;  // presentation time stamp in 100s of ns


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

void  CPinDevice::FlushBufferQueue()
{
    PCS_STREAM_DESCRIPTOR pCsStreamDesc = NULL;
    PVOID                 pMappedData   = NULL;
    PVOID                 pUnmappedData = NULL;
    CS_MSGQUEUE_BUFFER    CsMsgQBuff ;    

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

    return;
}

DWORD CPinDevice :: HandlePinIO()
{    
    DWORD dwRet = ERROR_SUCCESS;
    BOOL bOK = TRUE;

    EnterCriticalSection(&m_csStreamIO);
    if ( CSSTATE_RUN != m_CsState ) 
    {
        LeaveCriticalSection(&m_csStreamIO);
        return ERROR_INVALID_STATE;
    }
   	//RETAILMSG(1,(TEXT("HandlePinIO\n")));
    PCS_STREAM_DESCRIPTOR pCsStreamDesc = NULL;
    PVOID                 pMappedData   = NULL;
    PVOID                 pUnmappedData = NULL;

⌨️ 快捷键说明

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