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

📄 pindevice.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    {
		RETAILMSG(RETAIL_ON,(TEXT("AllocateBuffer 1\r\n")));
        return dwError;
    }

    // There are 2 cases here: the buffer comes from the hardware or from the software. 
    // If the buffer comes from the software, we generate a new entry in the table up to the maximum allowed.
    // If the buffer comes from the hardware, we setup the application stream descriptor

    EnterCriticalSection( &m_csStreamBuffer );

    if( GetCurrentMemoryModel() == CSPROPERTY_BUFFER_DRIVER )
    {
        // Get one of the hardware buffers, and setup the descriptor
        ASSERT( m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy == FALSE );

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

        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
	    RETAILMSG(RETAIL_ON,(TEXT("AllocateBuffer 1\r\n")));
        ASSERT( m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy == FALSE );
		RETAILMSG(RETAIL_ON,(TEXT("AllocateBuffer 2\r\n")));
        if( !CeSafeCopyMemory( &( m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow ), pOutBuf, sizeof( CS_STREAM_DESCRIPTOR )))
        {
            dwError = ERROR_INVALID_PARAMETER;
            goto Cleanup;
        }
		RETAILMSG(RETAIL_ON,(TEXT("AllocateBuffer 3\r\n")));

        // 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;
        }
		RETAILMSG(RETAIL_ON,(TEXT("AllocateBuffer 4\r\n")));

        m_pStreamDescriptorList[ m_dwBufferCount ].pCsStreamDescriptorExternal = NULL;
        m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy = TRUE;
        m_dwBufferCount++;
		RETAILMSG(RETAIL_ON,(TEXT("AllocateBuffer 5\r\n")));
    }
    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 );
	RETAILMSG(RETAIL_ON, (TEXT("\nBuffer Count = %d\n"), m_dwBufferCount));
    return dwError;
}


DWORD
CPinDevice::DeallocateBuffer( LPVOID pOutBuf )
{
    LPVOID  lpBuffer;
    DWORD   dwHandle;
    DWORD   dwIndex;
    DWORD   dwError = ERROR_SUCCESS;
    PCS_STREAM_DESCRIPTOR pCsDescriptor;
	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: DeallocateBuffer\r\n")));

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

    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;

	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: SwSetupStreamDescriptor\r\n")));
    if(( pCsStreamDesc == NULL ) || ( pBuffer == NULL ))
    {
        return ERROR_INVALID_PARAMETER;
    }

    // TODO: In the case the driver has its own buffers, we need to go through the list of internal buffers
    // TODO: Change the handle to a real handle
    dwHandle = CreateHandle( dwIndex, pBuffer );

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

    // Note: This is the place to setup DMA for the buffer. 

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


DWORD
CPinDevice::HwSetupStreamDescriptor(
    DWORD   dwIndex
)
{
    PCSSTREAM_HEADER      pCsStreamHeader; 
    PCS_FRAME_INFO        pCsFrameInfo;
	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: HwSetupStreamDescriptor\r\n")));

    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
    // TODO: Change this to use a real handle
    pCsStreamHeader->Handle = CreateHandle( dwIndex, pCsStreamHeader->Data );

    return ERROR_SUCCESS;
}


DWORD 
CPinDevice::CreateHandle( 
    DWORD  dwIndex, 
    LPVOID pBuffer 
)
{
    DWORD  dwHandle;
    HANDLE hProcess = GetCallerProcess();

	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: CreateHandle\r\n")));
    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();
	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: GetIndexFromHandle\r\n")));

    // 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
	    RETAILMSG(1, (TEXT("Invalid index, bail out.....\r\n")));
        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;
    
    RETAILMSG( RETAIL_ON, ( _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 )
    {
        RETAILMSG( RETAIL_ON, ( _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 )
    {
        RETAILMSG( RETAIL_ON, ( _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 )
    {
        RETAILMSG( RETAIL_ON, ( _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;           

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

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


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

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

    if(( ppCsStreamDesc == NULL ) || ( ppMappedData == NULL ) || ( ppUnmappedData == NULL ))
    {
        RETAILMSG( RETAIL_ON, ( _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;
		//NOTE: this is the buffer number that was removed as per allocation sequence
		*pdwBuffNumber = dwCounter;	
        }

        dwCounter++;
    }
    LeaveCriticalSection( &m_csStreamBuffer );

    return true;
}


bool
CPinDevice::ResetBufferList()
{
	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: ResetBufferList\r\n")));
    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;

	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: ReadMemoryModelFromRegistry\r\n")));

	if( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"Drivers\\BuiltIn\\Camera", 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;
}

⌨️ 快捷键说明

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