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

📄 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 页
字号:

        }

        // Set control register for CSC
        INSREG32BF(&m_pPpReg->PP_CNTL, 
            PP_CNTL_CSCEN, PP_CNTL_CSCEN_RGB);
        INSREG32BF(&m_pPpReg->PP_CNTL, 
            PP_CNTL_CSC_OUT, pConfigData->outputFormat);
        INSREG32BF(&m_pPpReg->PP_CNTL, 
            PP_CNTL_CSC_TABLE_SEL, pConfigData->CSCEquation);
    }
    
    PP_FUNCTION_EXIT();
    
    return TRUE;
}

//-----------------------------------------------------------------------------
//
// Function: PpConfigureResize
//
// This function configures the Post-processor resizing.
//
// Parameters:
//      pConfigData
//          [in] Pointer to configuration data structure
//
// Returns:
//      TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpConfigureResize(pPpConfigData pConfigData)
{
    UINT8 iRetry = 0;
    UINT8 iHoriStart, iHoriEnd;
    UINT8 iVertStart, iVertEnd;

    FLOAT fHoriRatio, fVertRatio;
    
    UINT16 iInWidth = pConfigData->inputSize.width;
    UINT16 iInHeight = pConfigData->inputSize.height;
    UINT16 iOutWidth = pConfigData->outputSize.width;
    UINT16 iOutHeight = pConfigData->outputSize.height;
    UINT16 iVarInWidth, iVarOutWidth;
    UINT16 iVarInHeight, iVarOutHeight;

    PP_FUNCTION_ENTRY();
    
    // Only support 2:1 to 1:4 and a fixed 4:1
    if (((4 * iInWidth < iOutWidth) || (iInWidth > 2 * iOutWidth)) && 
        (iInWidth != 4 * iOutWidth)) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Invalid width resizing ratio\r\n"), __WFUNCTION__));
        return FALSE;
    }

    if (((4 * iInHeight < iOutHeight) || (iInHeight > 2 * iOutHeight)) &&
        (iInHeight != 4 * iOutHeight)) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Invalid height resizing ratio\r\n"), __WFUNCTION__));
        return FALSE;
    }

    //
    // Resizing ratio calculation
    //
    m_iHoriLen = 0;
    m_iVertLen = 0;

    // Width
    if (iInWidth != iOutWidth) {
        iVarInWidth = iInWidth;
        iVarOutWidth = iOutWidth;
        while (iRetry < PP_MAX_RESIZE_RETRIES) {
            UINT16 gcd = PpGetGcd(iVarInWidth, iVarOutWidth);
            m_iHoriLen = PpResize(iVarInWidth/gcd, iVarOutWidth/gcd);
            if (m_iHoriLen < 0) {
                iRetry++;
                iVarOutWidth++;
                m_iHoriLen = 0;
            }
            else break;
        }
    } else {
        // Calculate it even for 1:1
        m_iHoriLen = PpResize(1, 1);
        if (m_iHoriLen < 0) {
            DEBUGMSG(ZONE_ERROR, 
                (TEXT("%s: Width 1:1 resize calculation failure\r\n"), 
                __WFUNCTION__));
            return FALSE;
        }
    }
    if (iRetry == PP_MAX_RESIZE_RETRIES) {
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Width resize failure\r\n"), __WFUNCTION__));
        return FALSE;
    }
    iHoriStart = 0;
    iHoriEnd = m_iHoriLen - 1;

    // Height
    iRetry = 0;
    fHoriRatio = (iInWidth > iOutWidth) ?
        ((float)iInWidth / (float)iOutWidth) : 
        ((float)iOutWidth / (float)iInWidth);
    fVertRatio = (iInHeight > iOutHeight) ? 
        ((float)iInHeight / (float)iOutHeight) : 
        ((float)iOutHeight / (float)iInHeight);
    if (fHoriRatio != fVertRatio) {
        if (iInHeight != iOutHeight) {
            // UINT16 inHeight = iInHeight;
            iVarInHeight = iInHeight;
            iVarOutHeight = iOutHeight;
            while (iRetry < PP_MAX_RESIZE_RETRIES) {
                UINT16 gcd = PpGetGcd(iVarInHeight, iVarOutHeight);
                m_iVertLen = PpResize(iVarInHeight/gcd, iVarOutHeight/gcd);
                if (m_iVertLen < 0) {
                    iRetry++;
                    iVarOutHeight++;
                    m_iVertLen = 0;
                } else break;
            }
        } else {
            // Calculate it even for 1:1
            m_iVertLen = PpResize(1, 1);
            if (m_iVertLen < 0) {
                DEBUGMSG(ZONE_ERROR, 
                    (TEXT("%s: Height 1:1 resize calculation failure\r\n"), 
                    __WFUNCTION__));
                return FALSE;
            }
        }
        if (iRetry == PP_MAX_RESIZE_RETRIES) {
            DEBUGMSG(ZONE_ERROR, 
                (TEXT("%s: Width resize failure\r\n"), __WFUNCTION__));
            return FALSE;
        }
        iVertStart = m_iHoriLen;
        iVertEnd = m_iHoriLen + m_iVertLen - 1;
    } else {
        iVertStart = iHoriStart;
        iVertEnd = iHoriEnd;
    }
    
    PpSetupResize(iVertStart, iVertEnd, iHoriStart, iHoriEnd);

    PP_FUNCTION_EXIT();
    
    return TRUE;
}

//------------------------------------------------------------------------------
//
// Function: PpGetGcd
//
// This function is used to calculate the greatest common divider of the 
// two passed in parameters.  This code is reused from Symbian.
//
// Parameters:  
//      x
//          [in] One number.
//
//      y
//          [in] The other one.
//
// Returns:
//      The greatest common divider of x and y.
//
//------------------------------------------------------------------------------
UINT16 PpClass::PpGetGcd(UINT16 x, UINT16 y)
{
    UINT16 temp;
    
    if (x < y) {
        temp = y;
        y = x;
        x = temp;
    }
    
    if ((x % y) == 0) return y;

    while ((temp = (x % y)) != 0) {
        x = y;
        y = temp;
    }
    
    return y; 
}

//------------------------------------------------------------------------------
//
// Function: PpResize
//
// This function is used to build resize table.  Bilinear interpolation is 
// implemented.  There is a special case for 4:1 scaling. 
//
// This code is reused from Symbian team.
//
// Parameters:
//      in
//          [in] Width/height of input frame.
//
//      out
//          [in] Width/height of output frame.
//
// Returns:     
//      Resized width/height if positive otherwise indicates failure.
//
//------------------------------------------------------------------------------
INT8 PpClass::PpResize(UINT16 in, UINT16 out)
{
    UINT8 iResizeLen = 0;
    
    // Up sampling
    if (in <= out) {
        UINT16 pos = 0;
        for (UINT16 i = 0; i < out; i++) {
            UINT16 w1 = out - pos;
            UINT16 w2 = pos;
            UINT16 next = 0;
            pos += in;
            if (pos >= out) {
                pos -= out;
                next++;
            }
            if ((iResizeLen + m_iHoriLen) >= PP_MAX_RESIZE_COEFFS) {
                DEBUGMSG(ZONE_ERROR, 
                    (TEXT("%s: Up sampling exceeds maximum coeffs\r\n"), 
                    __WFUNCTION__));
                return (-1);
            }
            
            PpStoreCoeffs(w1, w2, out, next, iResizeLen);
            iResizeLen++;
            
            if (pos == 0) break;
        }
    } else if (in <= 2 * out) {
        // Handle the cases for 2:1 and lower for down sampling
        UINT16 inPos1 = out;
        UINT16 inPosInc = 2 * out;
        UINT16 inPos2   = inPos1 + inPosInc;
        UINT16 outPos = in;
        UINT16 outPosInc = 2 * in;
        UINT16 init_carry = in - out;
        UINT16 carry = init_carry;
        do {
            int w1 = inPos2 - outPos;
            int w2 = outPos - inPos1;
            int n = 0;
            outPos += outPosInc;
            carry += outPosInc;
            while (inPos2 < outPos) {
                inPos1 = inPos2;
                inPos2 += inPosInc;
                n++;
                carry -= inPosInc;
            }
            
            if ((iResizeLen + m_iHoriLen) >= PP_MAX_RESIZE_COEFFS) {
                DEBUGMSG(ZONE_ERROR, 
                    (TEXT("%s: Down sampling exceeds maximum coeffs\r\n"), 
                    __WFUNCTION__));

                return (-1);
            }
            
            PpStoreCoeffs(w1, w2, 2 * out, n, iResizeLen);
            iResizeLen++;
        } while (carry != init_carry);
    } else if (in == 4 * out) { 
        // Down sampling by 4:1        
        m_iResizeCoeffs[m_iHoriLen] = 
            CSP_BITFVAL(PP_RESIZE_COEF_TBL_W, ((1 << PP_RESIZE_COEFF) / 2)) |
            CSP_BITFVAL(PP_RESIZE_COEF_TBL_N, 1) |
            CSP_BITFVAL(PP_RESIZE_COEF_TBL_OP, PP_RESIZE_COEF_TBL_OP_PIXELS);

        m_iResizeCoeffs[m_iHoriLen + 1] = CSP_BITFVAL(PP_RESIZE_COEF_TBL_N, 1) | 
            CSP_BITFVAL(PP_RESIZE_COEF_TBL_OP, PP_RESIZE_COEF_TBL_OP_NOPIXELS);

        m_iResizeCoeffs[m_iHoriLen + 2] = CSP_BITFVAL(PP_RESIZE_COEF_TBL_N, 1) | 
            CSP_BITFVAL(PP_RESIZE_COEF_TBL_OP, PP_RESIZE_COEF_TBL_OP_NOPIXELS);

        m_iResizeCoeffs[m_iHoriLen + 3] = CSP_BITFVAL(PP_RESIZE_COEF_TBL_N, 1) | 
            CSP_BITFVAL(PP_RESIZE_COEF_TBL_OP, PP_RESIZE_COEF_TBL_OP_NOPIXELS);

        iResizeLen = 4;
    } else {
        // The resize ratio is not supported
        DEBUGMSG(ZONE_ERROR, 
            (TEXT("%s: Unsupported resizing ratio\r\n"), 
            __WFUNCTION__));
        return (-1);
    }
    
    return iResizeLen;
}

//------------------------------------------------------------------------------
//
// Function: PpStoreCoeffs
//
// This function is used to store the resizing instructions in the array
// m_iResizeCoeffs[].  Each entry in the array is in the form (w1, w2, n). 
// An output pixel will be generated with the value (w1*in1 + w2*in2) and 
// the resize engine will then read in a n new input pixels (where n != 0), 
// where in1 and in2 are two adjacent pixels.
//
// This code is reused from Symbian team.
//
// Parameters:
//      ...
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void PpClass::PpStoreCoeffs(UINT16 w1, UINT16 w2, UINT16 base, 
    UINT16 next, UINT16 index)
{
    UINT16 iCoeff;
    
    if (m_iHoriLen != 0)
        index += m_iHoriLen;

    iCoeff = ((w1 << PP_RESIZE_COEFF) + (base >> 1)) / base;
    
    // 31 means 32, so 30 will handle both 30 & 31
    if (iCoeff == (PP_MAX_COEFF - 1))
        iCoeff--;
    else if (iCoeff == 1) 
        iCoeff++;
    else if (iCoeff == PP_MAX_COEFF)
        // 32 should be set to 31, as the HW treats 31 binary as 32 decimal
        iCoeff = PP_MAX_COEFF - 1;

    m_iResizeCoeffs[index] = CSP_BITFVAL(PP_RESIZE_COEF_TBL_W, iCoeff) |
        CSP_BITFVAL(PP_RESIZE_COEF_TBL_N, next) |
        CSP_BITFVAL(PP_RESIZE_COEF_TBL_OP, PP_RESIZE_COEF_TBL_OP_PIXELS);
}

//------------------------------------------------------------------------------
//
// Function: PpSetupResize
//
// This function is used to setup the resize registers.
//
// Parameters:
//      iVertStart
//          [in] Start index of vertial resize table.
//
//      iVertEnd
//          [in] End index of vertial resize table.
//
//      iHoriStart
//          [in] Start index of horizontal resize table.
//
//      iHoriEnd
//          [in] End index of horizontal resize table.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void PpClass::PpSetupResize(UINT8 iVertStart, UINT8 iVertEnd, 
    UINT8 iHoriStart, UINT8 iHoriEnd)
{
    UINT16 len;
    UINT16 i;

    // Setup RESIZE_TBL_INDEX regiser
    OUTREG32(&m_pPpReg->PP_RESIZE_TABLE_INDEX, 
        CSP_BITFVAL(PP_RESIZE_TABLE_INDEX_VERT_TBL_END_INDEX, iVertEnd) |
        CSP_BITFVAL(PP_RESIZE_TABLE_INDEX_VERT_TBL_START_INDEX, iVertStart) |
        CSP_BITFVAL(PP_RESIZE_TABLE_INDEX_HORI_TBL_END_INDEX, iHoriEnd) |
        CSP_BITFVAL(PP_RESIZE_TABLE_INDEX_HORI_TBL_START_INDEX, iHoriStart));

    // Setup RESIZE_TABLE register
    if ((iVertEnd != iHoriEnd) && (iVertStart != iHoriStart)) {
        len = (iVertEnd - iVertStart) + (iHoriEnd - iHoriStart) + 2;
    } else {
        // If the horizontal and vertical resize ratios are the same,
        // then the iHoriStart can be the same as iVertStart and iHoriEnd 
        // can be the same as iVertEnd. 
        len = iVertEnd - iVertStart + 1;
    }
    for (i = 0; i < len; i++)
        OUTREG32(&m_pPpReg->PP_RESIZE_COEF_TBL[i], m_iResizeCoeffs[i]);
}

//-----------------------------------------------------------------------------
//
// Function: PpEnqueueBuffers
//
// This function adds buffers for the PP channel.  Input and output buffers
// are provided and added to the buffer queue.  It is assumed that the caller 
// has allocated physically contiguous buffers.
//
// Parameters:
//      pPpBufs
//          [in] Pointer to structure containing a pointer to an input and 
//          output buffer.
//
// Returns:
//      TRUE if successful; FALSE if failed.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpEnqueueBuffers(pPpBuffers pPpBufs)
{
    PP_FUNCTION_ENTRY();

    //
    // Buffer boundary check
    // QP is needed only when deblock and/or dering enabled
    // Input, output and quantizer buffer should be word aligned
    //
    if (m_bNeedQP) {
        if ((pPpBufs->InQPBuf == NULL) || 
            (((UINT32)(pPpBufs->InQPBuf) & 0x03) != 0)) {
            DEBUGMSG(ZONE_ERROR, 
                (TEXT("%s: Invalid quantizer buffer (0x%08lX).\r\n"), 
                __WFUNCTION__, pPpBufs->InQPBuf));
            return FALSE;
        }

⌨️ 快捷键说明

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