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

📄 ppclass.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        m_hPpIntrThread = NULL;
    }

    if (m_hPpBufThread != NULL) {
        TerminateThread(m_hPpBufThread, 0);
        CloseHandle(m_hPpBufThread);
        m_hPpBufThread = NULL;
    }

    PP_FUNCTION_EXIT();
}

//-----------------------------------------------------------------------------
//
// Function: PpEnable
//
// This function enables post-processor.
//
// Parameters:
//      None.
//
// Returns:
//      TRUE if successful; FALSE if failed.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpEnable(void)
{
    PP_FUNCTION_ENTRY();

    // Enable eMMA clock
    if (!BSPPpSetClockGatingMode(TRUE)) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Enable PP failed. It probably is being used by someone. \r\n"), 
            __WFUNCTION__));
        return FALSE;
    }
    
    // Software reset post-processor
    INSREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST, PP_CNTL_SWRST_RESET);
    // Suppose it will clear itself after software reset
    while (EXTREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST)) {
        Sleep(0); // Relinquish current time slot for other thread
    }

    // Enable interrupts for frame completing and error occuring
    // Disable the MB completing interrupt, since we don't support it
    OUTREG32(&m_pPpReg->PP_INTRCNTL, 
        CSP_BITFVAL(PP_INTRCNTL_FRAME_COMP_INTR_EN, 
            PP_INTRCNTL_FRAME_COMP_INTR_EN_ENABLE) |
        CSP_BITFVAL(PP_INTRCNTL_ERR_INTR_EN, 
            PP_INTRCNTL_ERR_INTR_EN_ENABLE));

    // Empty buffer queue
    PpClearBuffers();
    
    PP_FUNCTION_EXIT();
    
    return TRUE;
}

//-----------------------------------------------------------------------------
//
// Function: PpDisable
//
// This function disables post-processor.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
void PpClass::PpDisable(void)
{
    PP_FUNCTION_ENTRY();
    
    // Disable post-processor first
    OUTREG32(&m_pPpReg->PP_CNTL, 0);

    // In case there is still one last pending interrupt
    // Clear interrupt status (w1c)
    OUTREG32(&m_pPpReg->PP_INTRSTATUS, 
        CSP_BITFVAL(PP_INTRSTATUS_ERR_INTR, 1) | 
        CSP_BITFVAL(PP_INTRSTATUS_FRAME_COMP_INTR, 1));

    // Disable interrupt
    OUTREG32(&m_pPpReg->PP_INTRCNTL, 0);

    // Disable eMMA clock
    BSPPpSetClockGatingMode(FALSE);

    // Revert flag
    m_bConfigured = FALSE;

    PP_FUNCTION_EXIT();
}

//------------------------------------------------------------------------------
//
// Function: PpConfigure
//
// This function is used to configure post-processor registers.
//
// Parameters:      
//      pConfigData
//          [in] Pointer to configuaration data structure.
//
// Returns:     
//      TRUE if success; FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL PpClass::PpConfigure(pPpConfigData pConfigData)
{
    PP_FUNCTION_ENTRY();

    if (pConfigData == NULL) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Invalid configuration data!\r\n"), __WFUNCTION__));
        return FALSE;
    }
    
    // Enable required operations
    if (pConfigData->bDeblock)
        INSREG32BF(&m_pPpReg->PP_CNTL, 
            PP_CNTL_DEBLOCKEN, PP_CNTL_DEBLOCKEN_ENABLE);
    else
        INSREG32BF(&m_pPpReg->PP_CNTL, 
            PP_CNTL_DEBLOCKEN, PP_CNTL_DEBLOCKEN_DISABLE);
    
    if (pConfigData->bDering)
        INSREG32BF(&m_pPpReg->PP_CNTL, 
            PP_CNTL_DERINGEN, PP_CNTL_DERINGEN_ENABLE);
    else
        INSREG32BF(&m_pPpReg->PP_CNTL, 
            PP_CNTL_DERINGEN, PP_CNTL_DERINGEN_DISABLE);

    // Indicates if we need quantizer parameter from user
    m_bNeedQP = (pConfigData->bDeblock || pConfigData->bDering);

    if (!PpConfigureInput(pConfigData))
        goto _error;

    if (!PpConfigureOutput(pConfigData))
        goto _error;

    if (!PpConfigureCSC(pConfigData))
        goto _error;

    if (!PpConfigureResize(pConfigData))
        goto _error;

    // Indicates the configuration is done
    m_bConfigured = TRUE;

    PP_FUNCTION_EXIT();

    return TRUE;

_error:
    // Make a software reset
    INSREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST, PP_CNTL_SWRST_RESET);
    // Suppose it will clear itself after software reset
    while (EXTREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST)) {
        Sleep(0); // Relinquish current time slot for other thread
    }
    
    DEBUGMSG(ZONE_ERROR, 
        (TEXT("%s: Post-processor configuration failed\r\n"), 
        __WFUNCTION__));

    return FALSE;
}

//-----------------------------------------------------------------------------
//
// Function: PpConfigureInput
//
// This function configures the Post-processor input source.
//
// Parameters:
//      pConfigData
//          [in] Pointer to configuration data structure
//
// Returns:
//      TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpConfigureInput(pPpConfigData pConfigData)
{   
    UINT16 iQFWidth;
    UINT16 iInputStride;

    PP_FUNCTION_ENTRY();

    // Alignment check
    if ((pConfigData->inputSize.width & 0x07) || 
        (pConfigData->inputSize.height & 0x07) ||
        (pConfigData->inputStride & 0x07)) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Input image size is not aligned\r\n"), __WFUNCTION__));  
        return FALSE;
    }

    // Boundary check
    if ((pConfigData->inputSize.width < PP_IMAGE_MIN_WIDTH) || 
        (pConfigData->inputSize.height < PP_IMAGE_MIN_HEIGHT) || 
        (pConfigData->inputSize.width > PP_IMAGE_MAX_WIDTH) || 
        (pConfigData->inputSize.height > PP_IMAGE_MAX_HEIGHT)) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Input image size is invalid\r\n"), __WFUNCTION__)); 
        return FALSE;
    }

    // Set input frame parameter register
    INSREG32BF(&m_pPpReg->PP_PROCESS_FRAME_PARA, 
        PP_PROCESS_FRAME_PARA_PROCESS_FRAME_HEIGHT, 
        pConfigData->inputSize.height);
    INSREG32BF(&m_pPpReg->PP_PROCESS_FRAME_PARA, 
        PP_PROCESS_FRAME_PARA_PROCESS_FRAME_WIDTH, 
        pConfigData->inputSize.width);   

    // Set quantizer frame width if need
    if (m_bNeedQP) {
        // Must be multiple of 4 bytes
        iQFWidth = pConfigData->inputSize.width / PP_MB_SIZE;
        iQFWidth = ((iQFWidth + 3) >> 2) << 2;
        INSREG32BF(&m_pPpReg->PP_SOURCE_FRAME_WIDTH, 
            PP_SOURCE_FRAME_WIDTH_QUANTIZER_FRAME_WIDTH, iQFWidth);
    }       

    // Set input line stride
    if (pConfigData->inputStride == 0) {
        // The case it's zero
        iInputStride = pConfigData->inputSize.width;
    } else {
        if (pConfigData->inputStride < pConfigData->inputSize.width) {
            DEBUGMSG(ZONE_ERROR, 
                (TEXT("%s: Input stride (%d) is less than the least valid value (%d)\r\n"), 
                __WFUNCTION__, 
                pConfigData->inputStride, pConfigData->inputSize.width));
            return FALSE;
        } else {
            iInputStride = pConfigData->inputStride;
        }
    }
    
    INSREG32BF(&m_pPpReg->PP_SOURCE_FRAME_WIDTH, 
        PP_SOURCE_FRAME_WIDTH_Y_INPUT_LINE_STRIDE, iInputStride);

    m_iInBufSize = iInputStride * pConfigData->inputSize.height;

    PP_FUNCTION_EXIT();

    return TRUE;
}

//-----------------------------------------------------------------------------
//
// Function: PpConfigureOutput
//
// This function configures the Post-processor output.
//
// Parameters:
//      pConfigData
//          [in] Pointer to configuration data structure
//
// Returns:
//      TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpConfigureOutput(pPpConfigData pConfigData)
{
    UINT8 iBpp;
    UINT16 iOutputStride;

    PP_FUNCTION_ENTRY();

    // Alignment check
    if ((pConfigData->outputSize.width & 0x01) ||
        (pConfigData->outputSize.height & 0x01) ||
        (pConfigData->outputStride & 0x03)) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Output image size is not aligned\r\n"), __WFUNCTION__));
        return FALSE;
    }

    // Boundary check
    if ((pConfigData->outputSize.width < PP_IMAGE_MIN_WIDTH) || 
        (pConfigData->outputSize.height < PP_IMAGE_MIN_HEIGHT) || 
        (pConfigData->outputSize.width > PP_IMAGE_MAX_WIDTH) || 
        (pConfigData->outputSize.height > PP_IMAGE_MAX_HEIGHT)) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Output image size is invalid\r\n"), __WFUNCTION__)); 
        return FALSE;
    }

    // Set output image parameter register
    INSREG32BF(&m_pPpReg->PP_DEST_IMAGE_SIZE, 
        PP_DEST_IMAGE_SIZE_OUT_IMAGE_HEIGHT, pConfigData->outputSize.height);
    INSREG32BF(&m_pPpReg->PP_DEST_IMAGE_SIZE, 
        PP_DEST_IMAGE_SIZE_OUT_IMAGE_WIDTH, pConfigData->outputSize.width);

    // Parameters validity check
    switch (pConfigData->outputFormat) {
        case ppCSCOutputFormat_RGB16:
        case ppCSCOutputFormat_YUV422:
            iBpp = 2;
            break;

        case ppCSCOutputFormat_RGB32:
            iBpp = 4;
            break;
    }
    if ((pConfigData->outputStride != 0) && 
        (pConfigData->outputStride < (pConfigData->outputSize.width * iBpp))) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Output stride %d is less than least valid value %d!\r\n"), 
            __WFUNCTION__, 
            pConfigData->outputStride, pConfigData->outputSize.width * iBpp));
        return FALSE;
    }

    // Set output line stride
    iOutputStride = pConfigData->outputStride;
    if (iOutputStride == 0) {
        // The case it's zero
        iOutputStride = pConfigData->outputSize.width * iBpp;
        // Output stride should always be rounded up as a multiple of 4 bytes
        iOutputStride = ((iOutputStride + 3) >> 2) << 2;
    }

    INSREG32BF(&m_pPpReg->PP_DEST_DISPLAY_WIDTH, 
        PP_DEST_DISPLAY_WIDTH_OUPUT_LINE_STRIDE, iOutputStride);

    // Setup DEST_FRAME_FORMAT_CNTL regsiter for RGB/YUV422
    OUTREG32(&m_pPpReg->PP_DEST_FRAME_FORMAT_CNTL, 
        CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_BLUE_WIDTH, 
            pConfigData->outputPixelFormat.component2_width) |
        CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_GREEN_WIDTH, 
            pConfigData->outputPixelFormat.component1_width) |
        CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_RED_WIDTH, 
            pConfigData->outputPixelFormat.component0_width) |
        CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_BLUE_OFFSET, 
            pConfigData->outputPixelFormat.component2_offset) |
        CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_GREEN_OFFSET, 
            pConfigData->outputPixelFormat.component1_offset) |
        CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_RED_OFFSET, 
            pConfigData->outputPixelFormat.component0_offset));

    m_iOutBufSize = iOutputStride * pConfigData->outputSize.height;

    PP_FUNCTION_EXIT();

    return TRUE;
}

//-----------------------------------------------------------------------------
//
// Function: PpConfigureCSC
//
// This function configures the Post-processor CSC.
//
// Parameters:
//      pConfigData
//          [in] Pointer to configuration data structure
//
// Returns:
//      TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpConfigureCSC(pPpConfigData pConfigData)
{
    PP_FUNCTION_ENTRY();

    if (pConfigData->outputFormat == ppCSCOutputFormat_YUV422) {
        // The output format is YUV422
        DEBUGMSG(ZONE_INFO, 
            (TEXT("%s: Output format is YUV422\r\n"), __WFUNCTION__));
        INSREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_CSCEN, PP_CNTL_CSCEN_YUV);        
    } else {
        // The output format is RGB
        switch (pConfigData->outputFormat) {
            case ppCSCOutputFormat_RGB16:
                DEBUGMSG(ZONE_INFO, 
                    (TEXT("%s: Output format is RGB16\r\n"), __WFUNCTION__));
                break;
                
            case ppCSCOutputFormat_RGB32:
                DEBUGMSG(ZONE_INFO, 
                    (TEXT("%s: Output format is RGB32\r\n"), __WFUNCTION__));
                break;

            default:
                DEBUGMSG(ZONE_ERROR, 
                    (TEXT("%s: Invalid CSC output format (%d)\r\n"), 
                    __WFUNCTION__, pConfigData->outputFormat));                
                return FALSE;
        }

        // Set CSC equation
        if ((pConfigData->CSCEquation != ppCSCEquationA_1) &&
            (pConfigData->CSCEquation != ppCSCEquationA_0) &&
            (pConfigData->CSCEquation != ppCSCEquationB_1) &&
            (pConfigData->CSCEquation != ppCSCEquationB_0)) {
            DEBUGMSG(ZONE_ERROR, 
                (TEXT("%s: Invalid CSC equation (%d)\r\n"), 
                __WFUNCTION__, pConfigData->CSCEquation));
            return FALSE;
        } else {
            OUTREG32(&m_pPpReg->PP_CSC_COEF_0123,
                CSP_BITFVAL(PP_CSC_COEF_0123_C0, 
                    yuv2rgb_tbl[pConfigData->CSCEquation][0]) |
                CSP_BITFVAL(PP_CSC_COEF_0123_C1, 
                    yuv2rgb_tbl[pConfigData->CSCEquation][1]) |
                CSP_BITFVAL(PP_CSC_COEF_0123_C2, 
                    yuv2rgb_tbl[pConfigData->CSCEquation][2]) |
                CSP_BITFVAL(PP_CSC_COEF_0123_C3, 
                    yuv2rgb_tbl[pConfigData->CSCEquation][3]));
            
            OUTREG32(&m_pPpReg->PP_CSC_COEF_4,
                CSP_BITFVAL(PP_CSC_COEF_4_C4, 
                    yuv2rgb_tbl[pConfigData->CSCEquation][4]) |
                CSP_BITFVAL(PP_CSC_COEF_4_X0, 
                    yuv2rgb_tbl[pConfigData->CSCEquation][5]));

⌨️ 快捷键说明

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