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

📄 swdec_motiontextureutils.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            break;

    /*lint --e(744) */
    }

    mv->hor += hor;
    mv->ver += ver;

}

/*------------------------------------------------------------------------------

   5.7  Function name: SwDec_MedianFilter

        Purpose: median filtering of three input values

        Input:
            a,b,c   input values to be median filtered

        Output:
            median of three input values

------------------------------------------------------------------------------*/

i32 SwDec_MedianFilter(i32 a, i32 b, i32 c)
{
    i32 max,min,med;
    max = min = med = a;
    if (b > max)
    {
        max = b;
    }
    else if (b < min)
    {
        min = b;
    }
    if (c > max)
    {
        med = max;
    }
    else if (c < min)
    {
        med = min;
    }
    else
    {
        med = c;
    }

    return(med);
}
            
/*------------------------------------------------------------------------------

   5.8  Function name: SwDec_GetLeftMvCandidate

        Purpose: get left motion vector candidate for differential decoding

        Input:
            pMbDesc      pointer to decMbDesc_t array
            mbNum
            mbNum       [0,3]
            column
            vpBoundaryMb

        Output:
            motion vector of block on the left if valid, otherwise NON_VALID_MV

------------------------------------------------------------------------------*/

mv_t SwDec_GetLeftMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum, u32 mvNum,
    u32 column, u32 vpBoundaryMb)
{
    mv_t mv = {NON_VALID_MV,NON_VALID_MV};

    ASSERT(pMbDesc);
    ASSERT(mbNum >= vpBoundaryMb);
    ASSERT(mvNum < 4);

    if (mvNum & 0x1)
    {
        mv.hor = pMbDesc[mbNum].data[2*(mvNum-1)];
        mv.ver = pMbDesc[mbNum].data[2*(mvNum-1)+1];
    }
    else if (column && (mbNum > vpBoundaryMb))
    {
        if (pMbDesc[--mbNum].flags & INTER_MB_MASK)
        {
            mv.hor = pMbDesc[mbNum].data[2+2*mvNum];
            mv.ver = pMbDesc[mbNum].data[3+2*mvNum];
        }
        else
        {
            mv.hor = mv.ver = 0;
        }
    }
    return(mv);

}

/*------------------------------------------------------------------------------

   5.9  Function name: SwDec_GetAboveMvCandidate

        Purpose: get above motion vector candidate for differential decoding

        Input:
            pMbDesc      pointer to decMbDesc_t array
            mbNum
            mbNum       [0,3]
            width       width of vop in macro blocks
            vpBoundaryMb

        Output:
            motion vector of block above if valid, otherwise NON_VALID_MV

------------------------------------------------------------------------------*/

mv_t SwDec_GetAboveMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum, u32 mvNum,
    u32 width, u32 vpBoundaryMb)
{
    u32 tmp;
    mv_t mv = {NON_VALID_MV,NON_VALID_MV};

    ASSERT(pMbDesc);
    ASSERT(width);
    ASSERT(mbNum >= vpBoundaryMb);
    ASSERT(mvNum < 4);

    if (mvNum >= 2)
    {
        mv.hor = pMbDesc[mbNum].data[0];
        mv.ver = pMbDesc[mbNum].data[1];
    }
    else if ((mbNum >= width) && ((tmp = mbNum-width) >= vpBoundaryMb))
    {
        if (pMbDesc[tmp].flags & INTER_MB_MASK)
        {
            mv.hor = pMbDesc[tmp].data[4+2*mvNum];
            mv.ver = pMbDesc[tmp].data[5+2*mvNum];
        }
        else
        {
            mv.hor = mv.ver = 0;
        }
    }
    return(mv);

}

/*------------------------------------------------------------------------------

   5.10  Function name: SwDec_GetRightMvCandidate

        Purpose: get right motion vector candidate for differential decoding

        Input:
            pMbDesc      pointer to decMbDesc_t array
            mbNum
            mbNum       [0,3]
            width       widht of vop in macro blocks
            column
            vpBoundaryMb

        Output:
            motion vector of block on the right if valid, otherwise NON_VALID_MV

------------------------------------------------------------------------------*/

mv_t SwDec_GetRightMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum, u32 mvNum,
    u32 width, u32 column, u32 vpBoundaryMb)
{
    u32 tmp;
    mv_t mv = {NON_VALID_MV,NON_VALID_MV};

    ASSERT(pMbDesc);
    ASSERT(width);
    ASSERT(mbNum >= vpBoundaryMb);
    ASSERT((mbNum%width) == column);
    ASSERT(mvNum < 4);

    if (mvNum >= 2)
    {
        mv.hor = pMbDesc[mbNum].data[2];
        mv.ver = pMbDesc[mbNum].data[3];
    }
    else if ( (column != (width-1)) && (mbNum >= width) &&
             ((tmp = mbNum-width+1) >= vpBoundaryMb) )
    {
        if (pMbDesc[tmp].flags & INTER_MB_MASK)
        {
           mv.hor = pMbDesc[tmp].data[4];
           mv.ver = pMbDesc[tmp].data[5];
        }
        else
        {
            mv.hor = mv.ver = 0;
        }
    }
    return(mv);

}

/*------------------------------------------------------------------------------

   5.11  Function name: SwDec_UseIntraDcVlc

        Purpose: determine whether to use intra DC vlc or not
                 
        Input: 
            Pointer to decContainer_t structure
            u32 MbNumber

        Output:
            0 don't use intra dc vlc
            1 use intra dc vlc

------------------------------------------------------------------------------*/
#ifndef MP4DEC_H263_ONLY
u32 SwDec_UseIntraDcVlc(decContainer_t *pDecContainer, u32 mbNumber)
{

    u32 QP;

    ASSERT(pDecContainer);
    ASSERT(mbNumber >= pDecContainer->StrmStorage.vpFirstCodedMb);
    ASSERT(mbNumber < pDecContainer->VopDesc.totalMbInVop);
    ASSERT(pDecContainer->StrmStorage.QP < 32);
    ASSERT(pDecContainer->StrmStorage.prevQP < 32);

    if (pDecContainer->StrmStorage.shortVideo)
    {
        pDecContainer->MbDesc[mbNumber].flags |= USE_INTRA_DC_VLC_MASK;
        return(1);
    }

    if (mbNumber == pDecContainer->StrmStorage.vpFirstCodedMb)
    {
        QP = pDecContainer->StrmStorage.QP;
    }
    else
    {
        QP = pDecContainer->StrmStorage.prevQP;
    }

    if (QP < IntraDcQp[pDecContainer->VopDesc.intraDcVlcThr])
    {
        pDecContainer->MbDesc[mbNumber].flags |= USE_INTRA_DC_VLC_MASK;
        return(1);
    }
    else
    {
        return(0);
    }

}

/*------------------------------------------------------------------------------

   5.12  Function name: SwDec_ScanDir

        Purpose: determine scanning direction and store dc predictor
                 
        Input: 
            Pointer to decContainer_t structure
            u32 MbNum
            u32 BlockNum

        Output:
            SCAN_ZIGZAG, SCAN_HOR, SCAN_VER

------------------------------------------------------------------------------*/

u32 SwDec_ScanDir(decContainer_t *pDecContainer, u32 mbNum, u32 blockNum)
{

    dcPred_t left, above;
    i32 corner;
    u32 col;
    u32 width;

    ASSERT(pDecContainer);
    ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
    ASSERT(mbNum >= pDecContainer->StrmStorage.vpMbNumber);
    ASSERT(blockNum < 6);
    ASSERT(pDecContainer->VopDesc.vopWidth);

    /* zigzan scan for inter macro blocks or all macro blocks (short video) */
    if (MB_IS_INTER(mbNum) || pDecContainer->StrmStorage.shortVideo)
    {
        return(SCAN_ZIGZAG);
    }

    col = pDecContainer->StrmStorage.col[mbNum];
    width = pDecContainer->VopDesc.vopWidth;

    left = SwDec_GetLeftCoeff(pDecContainer->MbDesc, mbNum, blockNum,
        col, pDecContainer->StrmStorage.vpMbNumber);
    above = SwDec_GetAboveCoeff(pDecContainer->MbDesc, mbNum, blockNum,
        width, pDecContainer->StrmStorage.vpMbNumber);
    corner = SwDec_GetCornerCoeff(pDecContainer->MbDesc, mbNum, blockNum,
        width, col, pDecContainer->StrmStorage.vpMbNumber);

    if (ABS(left.coeff-corner) < ABS(above.coeff-corner))
    {
        pDecContainer->StrmStorage.predictor = above.coeff;
        pDecContainer->StrmStorage.isDefaultPredictor =
            above.isDefault;
        pDecContainer->StrmStorage.predictorQP = above.QP;
        if (pDecContainer->MbDesc[mbNum].flags & AC_PRED_FLAG_MASK)
            return(SCAN_HOR);
        else
            return(SCAN_ZIGZAG);
    }
    else
    {
        pDecContainer->StrmStorage.predictor = left.coeff;
        pDecContainer->StrmStorage.isDefaultPredictor =
            left.isDefault;
        pDecContainer->StrmStorage.predictorQP = left.QP;
        if (pDecContainer->MbDesc[mbNum].flags & AC_PRED_FLAG_MASK)
            return(SCAN_VER);
        else
            return(SCAN_ZIGZAG);
    }
}

/*------------------------------------------------------------------------------

   5.13  Function name: SwDec_GetLeftCoeff

        Purpose: get dc coefficient of block on the left
                 
        Input: 
            pMbDesc      pointer to decMbDesc_t array
            mbNum
            blockNum
            column
            vpBoundaryMb

        Output:
            dcPred_t structure containing dc coeff and qp of block on the left
            if valid, otherwise set to default values

------------------------------------------------------------------------------*/

dcPred_t SwDec_GetLeftCoeff(decMbDesc_t *pMbDesc, u32 mbNum, u32 blockNum,
    u32 column, u32 vpBoundaryMb)
{

    u32 refMbNum;
    dcPred_t pred;

    ASSERT(pMbDesc);
    ASSERT(mbNum >= vpBoundaryMb);
    ASSERT(blockNum < 6);

    pred.isDefault = 0;
    if ( (blockNum != 1) && (blockNum != 3) )
    {
        refMbNum = mbNum - 1;
        if ( !column ||
             (refMbNum < vpBoundaryMb) ||
             (pMbDesc[refMbNum].flags & INTER_MB_MASK))
        {
            pred.coeff = DEFAULT_PREDICTOR;
            pred.QP = 0;
            pred.isDefault = 1;
        }
        else
        {
            if (blockNum < 4)
                blockNum++;
            pred.coeff = pMbDesc[refMbNum].data[blockNum];
            pred.QP = pMbDesc[refMbNum].QP;
        }
    }
    else
    {
        pred.coeff = pMbDesc[mbNum].data[blockNum-1];
        pred.QP = pMbDesc[mbNum].QP;
    }

    return pred;
}

/*------------------------------------------------------------------------------

   5.14  Function name: SwDec_GetAboveCoeff

        Purpose: get dc coefficient of block above
                 
        Input: 
            pMbDesc      pointer to decMbDesc_t array
            mbNum
            blockNum
            width       width of vop in macro blocks
            vpBoundaryMb

        Output:
            dcPred_t structure containing dc coeff and qp of block above
            if valid, otherwise set to default values

------------------------------------------------------------------------------*/

dcPred_t SwDec_GetAboveCoeff(decMbDesc_t *pMbDesc, u32 mbNum, u32 blockNum,
    u32 width, u32 vpBoundaryMb)
{
    u32 refMbNum;
    dcPred_t pred;

    ASSERT(pMbDesc);
    ASSERT(mbNum >= vpBoundaryMb);
    ASSERT(blockNum < 6);
    ASSERT(width);

    pred.isDefault = 0;
    if ( (blockNum != 2) && (blockNum != 3) )
    {
        refMbNum = mbNum - width;
        if ( (mbNum < width) ||
             (refMbNum < vpBoundaryMb) ||
             (pMbDesc[refMbNum].flags & INTER_MB_MASK))
        {
            pred.coeff = DEFAULT_PREDICTOR;
            pred.QP = 0;
            pred.isDefault = 1;
        }
        else
        {
            if (blockNum < 4)
                blockNum += 2;
            pred.coeff = pMbDesc[refMbNum].data[blockNum];
            pred.QP = pMbDesc[refMbNum].QP;
        }
    }
    else
    {
        pred.coeff = pMbDesc[mbNum].data[blockNum-2];
        pred.QP = pMbDesc[mbNum].QP;
    }

    return(pred);

}

/*------------------------------------------------------------------------------

   5.15  Function name: SwDec_GetCornerCoeff

        Purpose: get dc coefficient of block on the left above
                 
        Input: 
            pMbDesc      pointer to decMbDesc_t array
            mbNum
            blockNum
            width       width of vop in macro blocks
            column
            vpBoundaryMb

        Output:
            dc coeff of block above left if valid, otherwise set to default
            value

------------------------------------------------------------------------------*/

i32 SwDec_GetCornerCoeff(decMbDesc_t *pMbDesc, u32 mbNum, u32 blockNum,
    u32 width, u32 column, u32 vpBoundaryMb)
{

    i32 refMbNum;
    i32 coeff = 0;
    static const u32 refBlockNum[6] = {3,2,1,0,4,5};

    ASSERT(pMbDesc);
    ASSERT(mbNum >= vpBoundaryMb);
    ASSERT(blockNum < 6);
    ASSERT(width);
    ASSERT((mbNum%width) == column);

    refMbNum = (i32)mbNum;
    switch (blockNum)
    {
        case 1:
            refMbNum -= (i32)width;
            break;

        case 2:
            if (!column)
                refMbNum = -1;
            else
                refMbNum--;
            break;

        case 0:
        case 4:
        case 5:
            if (!column)
                refMbNum = -1;
            else
                refMbNum -= (i32)width + 1;
            break;

    /*lint --e(744) */
    }

    if ( (refMbNum < (i32)vpBoundaryMb) ||
         (pMbDesc[refMbNum].flags & INTER_MB_MASK))
    {
        coeff = DEFAULT_PREDICTOR;
    }
    else
    {
        coeff = pMbDesc[refMbNum].data[refBlockNum[blockNum]];
    }

    return(coeff);
}
#endif

/*lint +e701 +e702 */

⌨️ 快捷键说明

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