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

📄 pindevice.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            {
                DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): State to set = CSSTATE_STOP but we are already Stopped.\r\n"), this ) );
                dwError = ERROR_SUCCESS;
                break;
            }
        
            m_CsState = CSSTATE_STOP;
            m_pCamAdapter->PDDSetPinState( m_ulPinId, m_CsState );

            // The buffer queue needs to be emptied if the driver is not allocating the buffers
            FlushBufferQueue();
            dwError = ERROR_SUCCESS;

            break;

        case CSSTATE_PAUSE:
            
            if ( CSSTATE_PAUSE == m_CsState ) 
            {
                DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): State to set = CSSTATE_PAUSE but we are already Paused.\r\n"), this ) );
                dwError = ERROR_SUCCESS;
                break;
            }

            dwError = PauseStream();
            break;

        case CSSTATE_RUN:
            
            if ( CSSTATE_STOP == m_CsState ) 
            {
                DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): CSSTATE_STOP to CSSTATE_RUN is not a supported transition .\r\n"), this ) );
                dwError = ERROR_INVALID_STATE;
                break;
            }

            // We only allow Still Pin to goto Run state through PROPSETID_VIDCAP_VIDEOCONTROL
            if ( STILL == m_ulPinId )
            {
                dwError = ERROR_SUCCESS;
                break;
            }

            m_CsState = CSSTATE_RUN;          
            m_msStart = 0xFFFFFFFF;
            m_pCamAdapter->PDDSetPinState( m_ulPinId, m_CsState );


            dwError = ERROR_SUCCESS;
            
            break;

        default :
            DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Incorrect State\r\n"), this ) );
            dwError = ERROR_INVALID_PARAMETER;
        }
        LeaveCriticalSection(&m_csStreamIO);
        break;

    default:
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Invalid Request\r\n"), this ) );

        break;
    }

    return dwError;
}


DWORD
CPinDevice::PinHandleCustomRequests(
    PUCHAR pInBuf,              // Warning: This is an unsafe buffer, access with care
    DWORD  InBufLen,
    PUCHAR pOutBuf,             // Warning: This is an unsafe buffer, access with care
    DWORD  OutBufLen,
    PDWORD pdwBytesTransferred  // Warning: This is an unsafe buffer, access with care
    )
{
    return m_pCamAdapter->PDDHandlePinCustomProperties( m_ulPinId, pInBuf, InBufLen, pOutBuf, OutBufLen, pdwBytesTransferred );
}

DWORD
CPinDevice::PinHandleConnDataFormatSubReqs(
    ULONG                          ulReqFlags,
    PCS_DATAFORMAT_VIDEOINFOHEADER pCsDataFormatVidInfoHdr,  // Warning: this buffer is unsafe, use with caution
    PDWORD                         pdwBytesTransferred
    )
{
    DWORD    dwError  = ERROR_INVALID_PARAMETER;
    PCSSTATE pCsState = NULL;

    PCS_DATARANGE_VIDEO pCsDataRangeVideoMatched = NULL;

    // We must have called IOCTL_STREAM_INSTANTIATE before setting format
    if ( -1 == m_ulPinId )
    {
        return dwError;
    }
    
    // The incoming video info header is unsafe. The data might change on a separate thread
    // while it's being accessed. For security purposes, let's make a copy of the data
    // before any attempt to access them is done, and then work off the copy

    switch( ulReqFlags )
    {
    case CSPROPERTY_TYPE_SET:
        if ( true == m_pCamAdapter->AdapterCompareFormat( m_ulPinId, pCsDataFormatVidInfoHdr, &pCsDataRangeVideoMatched, true ) )
        {
            // We found our format
            memcpy( &m_CsDataRangeVideo, pCsDataRangeVideoMatched, sizeof ( CS_DATARANGE_VIDEO ) );
            memcpy( &m_CsDataRangeVideo, &pCsDataFormatVidInfoHdr->DataFormat, sizeof ( CSDATARANGE ) );
            memcpy( &m_CsDataRangeVideo.VideoInfoHeader, &pCsDataFormatVidInfoHdr->VideoInfoHeader, sizeof ( CS_VIDEOINFOHEADER ) );

            m_RtAveTimePerFrame = m_CsDataRangeVideo.VideoInfoHeader.AvgTimePerFrame;
            
            dwError = m_pCamAdapter->PDDSetPinFormat( m_ulPinId, &m_CsDataRangeVideo );
            *pdwBytesTransferred = 0;
        }

        break;

    default:
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Invalid Request\r\n"), this ) );
    }

    return dwError;
}


DWORD 
CPinDevice::AllocateBuffer( PCS_STREAM_DESCRIPTOR pCsDescriptor, LPVOID pOutBuf, DWORD  OutBufLen, DWORD *pdwBytesTransferred )
{
    DWORD                   dwError = ERROR_INVALID_PARAMETER;
    DWORD                   dwResult = -1;
    PCS_STREAM_DESCRIPTOR   pCsDescriptorOut = (PCS_STREAM_DESCRIPTOR) pOutBuf;

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

    if( NULL == pCsDescriptor )
    {
        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 );

    //Check the BufferCount after the critical section is entered.
    //This prevents synch issues with validating the BufferCount
    if( m_dwBufferCount >= m_ulMaxNumOfBuffers )
    {
        dwError = ERROR_INVALID_PARAMETER;
        goto Cleanup;
    }

    if( m_dwMemoryModel == CSPROPERTY_BUFFER_DRIVER )
    {
        if( NULL == pOutBuf || OutBufLen < sizeof(CS_STREAM_DESCRIPTOR) )
        {
            goto Cleanup;
        }
        // pOutBuf has already been validated through MapCallerPtr in the IOCTL function
        if( pCsDescriptorOut == NULL )
        {
            goto Cleanup;
        }

        // 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( pCsDescriptorOut, &(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++;
        if( pdwBytesTransferred )
        {
            *pdwBytesTransferred = sizeof(CS_STREAM_DESCRIPTOR);
        }
    }
    else if( m_dwMemoryModel == 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 );
		//RETAILMSG(1,(TEXT("AllocBuffer:CeSafeCopyMemory\n")));
        if( !CeSafeCopyMemory( &( m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow ), pCsDescriptor, sizeof( CS_STREAM_DESCRIPTOR )))
        {
            dwError = ERROR_INVALID_PARAMETER;
            goto Cleanup;
        }
		//RETAILMSG(1,(TEXT("AllocBuffer:SwSetupStreamDescriptor\n")));
        // Let's populate the handle and the buffer field.
        dwError = SwSetupStreamDescriptor( m_dwBufferCount, &( m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow ), pCsDescriptor );
        if( dwError != ERROR_SUCCESS )
        {
            goto Cleanup;
        }
		//RETAILMSG(1,(TEXT("AllocBuffer:OKay!!!\n")));
        m_pStreamDescriptorList[ m_dwBufferCount ].pCsStreamDescriptorExternal = NULL;
        m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy = TRUE;
        m_dwBufferCount++;
    }
    else if( m_dwMemoryModel == 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 ), pCsDescriptor, sizeof( CS_STREAM_DESCRIPTOR )))
        {
            dwError = ERROR_INVALID_PARAMETER;
            goto Cleanup;
        }

        dwError = SwSetupStreamDescriptor( dwAvailableRow, &( m_pStreamDescriptorList[ dwAvailableRow ].csStreamDescriptorShadow ), pCsDescriptor );
        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( PCS_STREAM_DESCRIPTOR pCsDescriptor )
{
    LPVOID  lpBuffer;
    DWORD   dwHandle;
    LONG    lIndex;
    DWORD   dwError = ERROR_SUCCESS;    

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

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

    lpBuffer = pCsDescriptor->CsStreamHeader.Data;
    dwHandle = pCsDescriptor->CsStreamHeader.Handle;

    // Get the entry for this buffer in the internal list
    EnterCriticalSection( &m_csStreamBuffer );
    
    //Check if there are any buffers to deallocate    
    if(0 == m_dwBufferCount)
    {
        dwError = ERROR_INVALID_PARAMETER;
        goto Cleanup;
    }

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

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

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

    if( m_dwMemoryModel == CSPROPERTY_BUFFER_DRIVER )
    {
        // We release the buffer. 
        dwError = m_pCamAdapter->PDDDeAllocatePinBuffer( m_ulPinId, m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data );
        m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data = NULL;
        pCsDescriptor->CsStreamHeader.Data = NULL;
    }
    else
    {
        dwError = m_pCamAdapter->PDDUnRegisterClientBuffer( m_ulPinId, m_pStreamDescriptorList[ lIndex ].csStreamDescriptorShadow.CsStreamHeader.Data );

        m_pStreamDescriptorList[ lIndex ].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;
    }

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

    pCsStreamDesc->CsStreamHeader.Handle = dwHandle; 
    
    return m_pCamAdapter->PDDRegisterClientBuffer( m_ulPinId, pCsStreamDesc->CsStreamHeader.Data );    
}


⌨️ 快捷键说明

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