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

📄 pindevice.cpp.svn-base

📁 PXA270 平台 Windows Mobile 5 摄像头驱动
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
        m_pStreamDescriptorList[ m_dwBufferCount ].pCsStreamDescriptorExternal = NULL;
        m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy = TRUE;
        m_dwBufferCount++;
    }
    else if( GetCurrentMemoryModel() == CSPROPERTY_BUFFER_CLIENT_LIMITED )
    {
        // The software is allocated by the software, let's copy the descriptor and generate a handle
        ASSERT( m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy == FALSE );

        if( !CeSafeCopyMemory( &( m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow ), pOutBuf, sizeof( CS_STREAM_DESCRIPTOR )))
        {
            dwError = ERROR_INVALID_PARAMETER;
            goto Cleanup;
        }

        // Let's populate the handle and the buffer field.
        dwError = SwSetupStreamDescriptor( m_dwBufferCount, &( m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow ), pOutBuf );
        if( dwError != ERROR_SUCCESS )
        {
            goto Cleanup;
        }

        m_pStreamDescriptorList[ m_dwBufferCount ].pCsStreamDescriptorExternal = NULL;
        m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy = TRUE;
        m_dwBufferCount++;
    }
    else if( GetCurrentMemoryModel() == CSPROPERTY_BUFFER_CLIENT_UNLIMITED )
    {
        // let's find a slot available
        DWORD dwAvailableRow = -1;
        for( DWORD i = 0; ( i < m_ulMaxNumOfBuffers ) && ( dwAvailableRow == -1 ); i++ )
        {
            if( m_pStreamDescriptorList[ i ].m_fBusy == FALSE )
            {
                dwAvailableRow = i;
            }
        }
        if( dwAvailableRow == -1 )
        {
            goto Cleanup;
        }

        if( !CeSafeCopyMemory( &( m_pStreamDescriptorList[ dwAvailableRow ].csStreamDescriptorShadow ), pOutBuf, sizeof( CS_STREAM_DESCRIPTOR )))
        {
            dwError = ERROR_INVALID_PARAMETER;
            goto Cleanup;
        }

        dwError = SwSetupStreamDescriptor( dwAvailableRow, &( m_pStreamDescriptorList[ dwAvailableRow ].csStreamDescriptorShadow ), pOutBuf );
        if( dwError != ERROR_SUCCESS )
        {
            goto Cleanup;
        }

        m_pStreamDescriptorList[ dwAvailableRow ].pCsStreamDescriptorExternal = NULL;
        m_pStreamDescriptorList[ dwAvailableRow ].m_fBusy = TRUE;
        m_dwBufferCount++;
    }

Cleanup:
    LeaveCriticalSection( &m_csStreamBuffer );
    return dwError;
}


DWORD
CPinDevice::DeallocateBuffer( LPVOID pOutBuf )
{
    LPVOID  lpBuffer;
    DWORD   dwHandle;
    DWORD   dwIndex;
    DWORD   dwError = ERROR_SUCCESS;
    PCS_STREAM_DESCRIPTOR pCsDescriptor;

    pCsDescriptor = (PCS_STREAM_DESCRIPTOR) pOutBuf;
    lpBuffer = pCsDescriptor->CsStreamHeader.Data;
    dwHandle = pCsDescriptor->CsStreamHeader.Handle;

    // Get the entry for this buffer in the internal list
    EnterCriticalSection( &m_csStreamBuffer );

    dwIndex = GetIndexFromHandle( dwHandle, lpBuffer );
    if( dwIndex == -1 )
    {
        dwError = ERROR_INVALID_PARAMETER;
        goto Cleanup;
    }

    // If the row is not in use, let's make it available
    if( m_pStreamDescriptorList[ dwIndex ].pCsStreamDescriptorExternal != NULL )
    {
        dwError = ERROR_INVALID_PARAMETER;
        goto Cleanup;
    }

    ASSERT( m_pStreamDescriptorList[ dwIndex ].m_fBusy == TRUE );
    m_pStreamDescriptorList[ dwIndex ].m_fBusy = FALSE;
    m_dwBufferCount--;

    DEBUGMSG(ZONE_INIT, (_T("DeallocateBuffer (%s): Index = %d\r\n"), STILL == m_ulPinId ? L"Still" : L"Preview/Capture", dwIndex));

    if( GetCurrentMemoryModel() == CSPROPERTY_BUFFER_DRIVER )
    {
        // We release the buffer.
        RemoteLocalFree( m_pStreamDescriptorList[ dwIndex ].csStreamDescriptorShadow.CsStreamHeader.Data );
        m_pStreamDescriptorList[ dwIndex ].csStreamDescriptorShadow.CsStreamHeader.Data = NULL;
        pCsDescriptor->CsStreamHeader.Data = NULL;
    }

Cleanup:
    LeaveCriticalSection( &m_csStreamBuffer );
    return dwError;
}


DWORD
CPinDevice::SwSetupStreamDescriptor( 
    DWORD                   dwIndex,
    PCS_STREAM_DESCRIPTOR   pCsStreamDesc, 
    LPVOID                  pBuffer             // Warning: This is an unsafe buffer, use with caution
)
{
    DWORD dwHandle;
    PCS_STREAM_DESCRIPTOR pCsStreamDescExt = ( PCS_STREAM_DESCRIPTOR ) pBuffer;

    if(( pCsStreamDesc == NULL ) || ( pBuffer == NULL ))
    {
        return ERROR_INVALID_PARAMETER;
    }

    dwHandle = CreateHandle( dwIndex, pBuffer );

    __try
    {
        pCsStreamDescExt->CsStreamHeader.Handle = dwHandle; 
    }
    __except( EXCEPTION_EXECUTE_HANDLER )
    {
        return ERROR_INVALID_PARAMETER;
    }

    pCsStreamDesc->CsStreamHeader.Handle = dwHandle; 
        
    return ERROR_SUCCESS;
}


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 = RemoteLocalAlloc( LPTR, m_ulFrameSize );
    }
    __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;
    HANDLE hProcess = GetCallerProcess();

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

    return dwHandle;
}


DWORD
CPinDevice::GetIndexFromHandle( 
    DWORD  dwHandle, 
    LPVOID pBuffer      // Warning: This is an unsafe buffer, use with caution
)
{
    DWORD   dwIndex = -1;
    HANDLE  hProcess = GetCallerProcess();

    // TODO: let's retrieve the index from the handle table and make sure we have a match
    dwIndex = ( dwHandle ^ (DWORD)hProcess ) >> 16;
    if( dwIndex >= m_ulMaxNumOfBuffers )
    {
        // Invalid index, bail out
        return -1;
    }

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

    return dwIndex;
}


DWORD
CPinDevice::EnqueueDescriptor( LPVOID pOutBuf )
{
    LPVOID  lpBuffer, lpMappedBuffer;
    DWORD   dwHandle;
    DWORD   dwIndex;
    DWORD   dwSize;
    DWORD   dwError = ERROR_INVALID_PARAMETER;
    PCS_VIDEOINFOHEADER   pCsVideoInfoHdr;
    PCS_STREAM_DESCRIPTOR pCsDescriptor;
    
    DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): EnqueueDescriptor\r\n"), this ) );

    if( m_CsState == CSSTATE_STOP )
    {
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    pCsDescriptor = (PCS_STREAM_DESCRIPTOR) pOutBuf;

    // 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
    dwIndex = GetIndexFromHandle( dwHandle, lpBuffer );
    if( dwIndex == -1 )
    {
        goto Cleanup;
    }

    // Is the row in use?
    if( m_pStreamDescriptorList[ dwIndex ].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[ dwIndex ].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 = abs( pCsVideoInfoHdr->bmiHeader.biHeight ) * CS_DIBWIDTHBYTES( pCsVideoInfoHdr->bmiHeader );
    lpMappedBuffer = (LPVOID) MapCallerPtr( lpBuffer, dwSize );

    if( lpMappedBuffer == NULL )
    {
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): MapCallerPtr failed for incoming pointer \r\n"), this ) );
        goto Cleanup;
    }

    // Finally, set the internal table
    m_pStreamDescriptorList[ dwIndex ].csStreamDescriptorShadow.CsStreamHeader.Data = lpMappedBuffer;
    m_pStreamDescriptorList[ dwIndex ].pCsStreamDescriptorExternal = pCsDescriptor;           

    dwError = ERROR_SUCCESS;
    
Cleanup:
    LeaveCriticalSection( &m_csStreamBuffer );
    return dwError;
}


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

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

    *ppCsStreamDesc = NULL;

    EnterCriticalSection( &m_csStreamBuffer );
    while(( dwCounter < m_dwBufferCount ) && ( *ppCsStreamDesc == NULL ))
    {
        if( m_pStreamDescriptorList[ dwCounter ].pCsStreamDescriptorExternal != NULL )
        {
            // 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;
        }

        dwCounter++;
    }
    LeaveCriticalSection( &m_csStreamBuffer );

    return true;
}


bool
CPinDevice::ResetBufferList()
{
    EnterCriticalSection( &m_csStreamBuffer );
    for( DWORD i = 0; i < m_dwBufferCount; i++ )
    {
        m_pStreamDescriptorList[ i ].pCsStreamDescriptorExternal = NULL;
        m_pStreamDescriptorList[ i ].m_fBusy = FALSE;
    }
    
    LeaveCriticalSection( &m_csStreamBuffer );

    return true;
}


bool
CPinDevice::ReadMemoryModelFromRegistry()
{
    HKEY  hKey = 0;
    DWORD dwType  = 0;
    DWORD dwSize  = sizeof ( DWORD );
    DWORD dwValue = -1;


    if( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"Drivers\\Capture\\NullCam", 0, 0, &hKey ))
    {
        false;
    }

    if( ERROR_SUCCESS == RegQueryValueEx( hKey, L"MemoryModel", 0, &dwType, (BYTE *)&dwValue, &dwSize ) )
    {
        if(   ( REG_DWORD == dwType ) 
           && ( sizeof( DWORD ) == dwSize ) 
           && (( dwValue == CSPROPERTY_BUFFER_DRIVER ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_LIMITED ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_UNLIMITED )))
        {
            m_dwMemoryModel = (CSPROPERTY_BUFFER_MODE) dwValue;
        }
    }

    RegCloseKey( hKey );
    return true;
}

CSPROPERTY_BUFFER_MODE CPinDevice::GetCurrentMemoryModel()
{
    return CSPROPERTY_BUFFER_CLIENT_LIMITED;
   
    return m_dwMemoryModel;
}

DWORD CPinDevice::GetMaxBufferCount()
{
    return MAX_BUFFER_COUNT;
}

⌨️ 快捷键说明

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