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

📄 pindevice.cpp

📁 windows ce 6.0 camera driver
💻 CPP
📖 第 1 页 / 共 4 页
字号:


DWORD
CPinDevice::HwSetupStreamDescriptor(
    DWORD   dwIndex
)
{
    PCSSTREAM_HEADER      pCsStreamHeader; 
    PCS_FRAME_INFO        pCsFrameInfo;

    if( dwIndex > m_dwBufferCount )
    {
        return ERROR_INVALID_PARAMETER;
    }

    m_ulFrameSize = CS__DIBSIZE (m_CsDataRangeVideo.VideoInfoHeader.bmiHeader);

    pCsStreamHeader = &( m_pStreamDescriptorList[ dwIndex ].csStreamDescriptorShadow.CsStreamHeader );
    pCsFrameInfo = &( m_pStreamDescriptorList[ dwIndex ].csStreamDescriptorShadow.CsFrameInfo );

    pCsStreamHeader->Size                         = sizeof(CSSTREAM_HEADER);
    pCsStreamHeader->TypeSpecificFlags            = 0;
    pCsStreamHeader->PresentationTime.Time        = 0;
    pCsStreamHeader->PresentationTime.Numerator   = 1;
    pCsStreamHeader->PresentationTime.Denominator = 1;
    pCsStreamHeader->Duration                     = 0;
    pCsStreamHeader->FrameExtent                  = m_ulFrameSize;
    pCsStreamHeader->DataUsed                     = m_ulFrameSize;
    pCsStreamHeader->OptionsFlags                 = CSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY;

    pCsFrameInfo->ExtendedHeaderSize = sizeof(CS_FRAME_INFO);
    pCsFrameInfo->dwFrameFlags       = CS_VIDEO_FLAG_FRAME;
    pCsFrameInfo->PictureNumber      = 0; 
    pCsFrameInfo->DropCount          = 0;

    // Note: RemoteLocalAlloc can't really trigger an exception, the __try/__except block is here
    // to highlight the fact that this call has to be protected in the case of a hardware access.
    __try
    {
        pCsStreamHeader->Data = m_pCamAdapter->PDDAllocatePinBuffer( m_ulPinId );
    }
    __except( EXCEPTION_EXECUTE_HANDLER )
    {
        return ERROR_INTERNAL_ERROR;
    }
    
    if( NULL == pCsStreamHeader->Data )
    {
        return ERROR_OUTOFMEMORY;
    }

    // And setup the handle
    pCsStreamHeader->Handle = CreateHandle( dwIndex, pCsStreamHeader->Data );

    return ERROR_SUCCESS;
}


DWORD 
CPinDevice::CreateHandle( 
    DWORD  dwIndex, 
    LPVOID pBuffer 
)
{
    DWORD  dwHandle;
    DWORD dwProcessId = GetCallerVMProcessId();

    dwHandle = dwProcessId ^ (( dwIndex << 16 ) + ( (DWORD)pBuffer & 0xFFFF ));

    return dwHandle;
}


LONG
CPinDevice::GetIndexFromHandle( 
    DWORD  dwHandle, 
    LPVOID pBuffer      // Warning: This is an unsafe buffer, use with caution
)
{
    LONG   lIndex = -1;    
    DWORD dwProcessId = GetCallerVMProcessId();

    // let's retrieve the index from the handle table and make sure we have a match    
    lIndex = ( dwHandle ^ dwProcessId ) >> 16;
    if( lIndex >= (LONG)m_ulMaxNumOfBuffers || lIndex < 0 )
    {
        // Invalid index, bail out
        return -1;
    }

    if(   ( m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data   != pBuffer )
        ||( m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Handle != dwHandle ))
    {
        // Something's wrong, bail out
        return -1;
    }

    return lIndex;
}


DWORD
CPinDevice::EnqueueDescriptor( PCS_STREAM_DESCRIPTOR pUnMarshalCsDescriptor )
{
    LPVOID  lpBuffer, lpMappedBuffer;
    DWORD   dwHandle;
    LONG   lIndex;
    DWORD   dwSize;
    DWORD   dwError = ERROR_INVALID_PARAMETER;
    PCS_VIDEOINFOHEADER   pCsVideoInfoHdr;
    PCS_STREAM_DESCRIPTOR pCsDescriptor = NULL;
    MarshalledBuffer_t  *pMarshalledStreamDesc = NULL;
    
    DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): EnqueueDescriptor\r\n"), this ) );
    if( m_CsState == CSSTATE_STOP )
    {
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    {
        MarshalledBuffer_t MarshalledStreamDesc(pUnMarshalCsDescriptor, sizeof(CS_STREAM_DESCRIPTOR), ARG_O_PTR, FALSE, TRUE);
        pCsDescriptor = reinterpret_cast<PCS_STREAM_DESCRIPTOR>( MarshalledStreamDesc.ptr() );

        if( NULL == pCsDescriptor )
        {
            return dwError;
        }

        // First, let's use the handle and the buffer to retrieve the shadow copy
        // If an exception happens during the following 2 lines, it will be trapped by the upper level
        lpBuffer = pCsDescriptor->CsStreamHeader.Data;
        dwHandle = pCsDescriptor->CsStreamHeader.Handle;
    }

    EnterCriticalSection( &m_csStreamBuffer );

    // Get the entry for this buffer in the internal list
    lIndex = GetIndexFromHandle( dwHandle, lpBuffer );
    if( lIndex == -1 )
    {
        goto Cleanup;
    }

    // Is the row in use?
    if( m_pStreamDescriptorList[ lIndex ].m_fBusy == FALSE )
    {
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): The buffer has not be prepared. Call CS_ALLOCATE first.\r\n"), this ) );
        goto Cleanup;
    }

    if( m_pStreamDescriptorList[ lIndex ].pCsStreamDescriptorExternal != NULL )
    {
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): This buffer has already be enqueued.\r\n"), this ) );
        goto Cleanup;
    }

    // Now, let's probe the incoming buffer
    pCsVideoInfoHdr = reinterpret_cast<PCS_VIDEOINFOHEADER>( &m_CsDataRangeVideo.VideoInfoHeader );
    //dwSize = m_CsDataRangeVideo.VideoInfoHeader.bmiHeader.biSizeImage;
    dwSize = m_CsDataRangeVideo.DataRange.SampleSize;
    
    if( m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer != NULL &&
        NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->ptr() )
    {
        m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->Unmarshal();
    }
    if( m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc != NULL &&
        NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->ptr() )
    {
        m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->Unmarshal();
    }

    if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc )
    {
        m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc = new MarshalledBuffer_t();
        if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc )
        {
            dwError = ERROR_OUTOFMEMORY;
            goto Cleanup;
        }
    }

    m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->Marshal(pUnMarshalCsDescriptor, sizeof(CS_STREAM_DESCRIPTOR), ARG_O_PTR|MARSHAL_FORCE_ALIAS, FALSE, TRUE);
    pCsDescriptor = reinterpret_cast<PCS_STREAM_DESCRIPTOR>( m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->ptr() );

    if( NULL == pCsDescriptor )
    {
        goto Cleanup;
    }

    //Marshal the data buffer
    if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer )
    {
        m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer = new MarshalledBuffer_t();
        if( NULL == m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer )
        {
            dwError = ERROR_OUTOFMEMORY;
            goto Cleanup;
        }
    }

    if(FAILED(m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->Marshal(lpBuffer, //Unmarshalled Src
                                                                                  dwSize, //Size of buffer
                                                                                  ARG_O_PTR|MARSHAL_FORCE_ALIAS, //Pointer is output
                                                                                  FALSE, //Don't force Duplicate
                                                                                  TRUE) //Enable asynch access
      )) 
    {
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Unable to marshal data buffer for asynch access.\r\n"), this ) );
        dwError = ERROR_OUTOFMEMORY;
        goto Cleanup;
    }

    lpMappedBuffer = m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->ptr();

    m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data = lpMappedBuffer;
    m_pStreamDescriptorList[ lIndex ].pCsStreamDescriptorExternal = pCsDescriptor;

    m_pStreamDescriptorList[ lIndex ].m_pUnMarshalledStreamDesc = (PCS_STREAM_DESCRIPTOR)pUnMarshalCsDescriptor;

    if ( false == m_fClientInitialized && CSSTATE_PAUSE == m_CsState )
    {
        m_fClientInitialized = true;
    }

    dwError = ERROR_SUCCESS;
    
Cleanup:

    if( ERROR_SUCCESS != dwError && lIndex >= 0 )
    {
        if( NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer &&
            NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->ptr() )
        {
            m_pStreamDescriptorList[ lIndex ].m_pMarshalledDataBuffer->Unmarshal();
        }
        if( NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc &&
            NULL != m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->ptr() )
        {
            m_pStreamDescriptorList[ lIndex ].m_pMarshalledStreamDesc->Unmarshal();
        }
    }

    LeaveCriticalSection( &m_csStreamBuffer );
    return dwError;
}


bool
CPinDevice::RemoveBufferFromList(
    PCS_STREAM_DESCRIPTOR * ppCsStreamDesc,
    PVOID                 * ppMappedData,
    PVOID                 * ppUnmappedData
    )
{
    DWORD dwCounter = 0;
    bool  RetVal = true;

    // Let's look in the list of buffers for the first buffer that has a non null external stream descriptor
    DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): RemoveBufferFromList\r\n"), this ) );

    if(( ppCsStreamDesc == NULL ) || ( ppMappedData == NULL ) || ( ppUnmappedData == NULL ))
    {
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): RemoveBufferFromList - Null pointer has been passed in.\r\n"), this ) );
        return RetVal;
    }

    //Initialize arguments
    *ppCsStreamDesc = NULL;
    *ppMappedData = NULL;
    *ppUnmappedData = NULL;

    EnterCriticalSection( &m_csStreamBuffer );
    //while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))
    while(( dwCounter < m_ulMaxNumOfBuffers ) && ( *ppCsStreamDesc == NULL )) //For "camera and DShow integration test" sub-case 603
    {
        if( m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal != NULL )
        {
            //REVIEW: All buffers accessed here should have been marshalled, check if try/except is needed
            __try
            {
            // We found one registered buffer. Let's return it.
            *ppCsStreamDesc = m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal;            
            *ppMappedData   = m_pStreamDescriptorList[ dwCounter ].csStreamDescriptorShadow.CsStreamHeader.Data;
            *ppUnmappedData = m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal->CsStreamHeader.Data;
            m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal = NULL;
            m_pStreamDescriptorList[ dwCounter ].csStreamDescriptorShadow.CsStreamHeader.Data = *ppUnmappedData;
            break;
            }
            __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
            {
                DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl: RemoveBufferFromList - Access Violation.\r\n"))) ;                
                RetVal = false;
            }         
        }

        dwCounter++;
    }
    LeaveCriticalSection( &m_csStreamBuffer );
    if(NULL == *ppMappedData)
    {
        RetVal = false;
    }
    
    return RetVal;
}


bool
CPinDevice::ResetBufferList()
{
    EnterCriticalSection( &m_csStreamBuffer );
    if( m_pStreamDescriptorList )
    {
        for( DWORD i = 0; i < m_ulMaxNumOfBuffers; i++ )
        {
            if(m_pStreamDescriptorList[ i ].m_pMarshalledDataBuffer != NULL)
            {
                delete m_pStreamDescriptorList[ i ].m_pMarshalledDataBuffer;
                m_pStreamDescriptorList[ i ].m_pMarshalledDataBuffer = NULL;
            }

            if(m_pStreamDescriptorList[ i ].m_pMarshalledStreamDesc != NULL)
            {
                delete m_pStreamDescriptorList[ i ].m_pMarshalledStreamDesc;
                m_pStreamDescriptorList[ i ].m_pMarshalledStreamDesc = NULL;
            }

            m_pStreamDescriptorList[ i ].pCsStreamDescriptorExternal = NULL;
            m_pStreamDescriptorList[ i ].m_fBusy = FALSE;
        }
    }
    
    LeaveCriticalSection( &m_csStreamBuffer );

    return true;
}



ULONG CPinDevice :: PictureNumber( ) const
{
    return m_ulPictureNumber;
}

ULONG CPinDevice :: FramesDropped( ) const
{
    return m_ulFramesDropped;
}

ULONG CPinDevice :: FrameSize( ) const
{
    return m_ulFrameSize;
}


⌨️ 快捷键说明

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