swdec_errorconcealment.c

来自「freescale i.mx31 BSP CE5.0全部源码」· C语言 代码 · 共 522 行 · 第 1/2 页

C
522
字号

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

void SwDec_IConcealment(decContainer_t *pDecContainer, u32 mbNum)
{
    u32 i,j,tmp;
    u32 width;
    i32 dc[6];
    i32 data[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    pDecContainer->MbDesc[mbNum].typeOfMb = MB_INTRA;
    pDecContainer->MbDesc[mbNum].flags = 0;

    width = pDecContainer->VopDesc.vopWidth;

    /* use dc coefficients of block above if not first row */
    if (pDecContainer->StrmStorage.row[mbNum])
    {
        tmp = mbNum - width;
        dc[0] = pDecContainer->MbDesc[mbNum].data[0] =
            pDecContainer->MbDesc[tmp].data[2];
        dc[1] = pDecContainer->MbDesc[mbNum].data[1] =
            pDecContainer->MbDesc[tmp].data[3];
        dc[2] = pDecContainer->MbDesc[mbNum].data[2] = (i16)dc[0];
        dc[3] = pDecContainer->MbDesc[mbNum].data[3] = (i16)dc[1];
        dc[4] = pDecContainer->MbDesc[mbNum].data[4] =
            pDecContainer->MbDesc[tmp].data[4];
        dc[5] = pDecContainer->MbDesc[mbNum].data[5] =
            pDecContainer->MbDesc[tmp].data[5];
    }
    /* use dc coefficients of block on the left if not first column */
    else if (pDecContainer->StrmStorage.col[mbNum])
    {
        tmp = mbNum - 1;
        dc[0] = pDecContainer->MbDesc[mbNum].data[0] =
            pDecContainer->MbDesc[tmp].data[1];
        dc[1] = pDecContainer->MbDesc[mbNum].data[1] = (i16)dc[0];
        dc[2] = pDecContainer->MbDesc[mbNum].data[2] =
            pDecContainer->MbDesc[tmp].data[3];
        dc[3] = pDecContainer->MbDesc[mbNum].data[3] = (i16)dc[2];
        dc[4] = pDecContainer->MbDesc[mbNum].data[4] =
            pDecContainer->MbDesc[tmp].data[4];
        dc[5] = pDecContainer->MbDesc[mbNum].data[5] =
            pDecContainer->MbDesc[tmp].data[5];
    }
    /* otherwise use default dc coefficient values */
    else
    {
        dc[0] = pDecContainer->MbDesc[mbNum].data[0] = 1024;
        dc[1] = pDecContainer->MbDesc[mbNum].data[1] = 1024;
        dc[2] = pDecContainer->MbDesc[mbNum].data[2] = 1024;
        dc[3] = pDecContainer->MbDesc[mbNum].data[3] = 1024;
        dc[4] = pDecContainer->MbDesc[mbNum].data[4] = 1024;
        dc[5] = pDecContainer->MbDesc[mbNum].data[5] = 1024;
    }

    for (i = 0; i < 6; i++)
    {
        data[0] = dc[i];
        if (data[0])
        {
            SwDec_IdctInter(data, 0);
        }
        /* if dc coefficient is zero -> set all data to zero */
        else
        {
            for (j = 0; j < 64; j++) data[j] = 0;
        }
        SwDec_WriteIntraOutput(pDecContainer, data, mbNum, i);
    }

}

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

   5.5  Function name: SwDec_ITextureConcealment

        Purpose: Conceal macro block in I-VOP. Dc coefficients are not
        concealed if they were received separately. Otherwise SwDec_IConcealment
        is called.
                 
        Input:
        pDecContainer   pointer to decContainer_t
        mbNum

        Output:

------------------------------------------------------------------------------*/
#ifndef MP4DEC_H263_ONLY
void SwDec_ITextureConcealment(decContainer_t *pDecContainer, u32 mbNum)
{

    u32 i,j;

    if (pDecContainer->MbDesc[mbNum].flags & USE_INTRA_DC_VLC_MASK)
    {
        i32 data[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

        pDecContainer->MbDesc[mbNum].typeOfMb = MB_INTRA;

        for (i = 0; i < 6; i++)
        {
            data[0] = pDecContainer->MbDesc[mbNum].data[i];
            /* reset ac flag */
            if (!(pDecContainer->MbDesc[mbNum].data[7] & (0x20>>i)))
            {
                pDecContainer->MbDesc[mbNum].flags = USE_INTRA_DC_VLC_MASK;
                j = SwDec_ScanDir(pDecContainer, mbNum, i);
                SwDec_AcDcPrediction(pDecContainer, data, mbNum, i, j);
            }
            if (data[0])
            {
                SwDec_IdctInter(data, 0);
            }
            /* if dc coefficient is zero -> set all data to zero */
            else
            {
                for (j = 0; j < 64; j++) data[j] = 0;
            }
            SwDec_WriteIntraOutput(pDecContainer, data, mbNum, i);
        }
    }
    else
    {
        SwDec_IConcealment(pDecContainer, mbNum);
    }

}
#endif
/*------------------------------------------------------------------------------

   5.6  Function name: SwDec_MotionVectorConcealment

        Purpose: Conceal motion vectors of a macro block. Use motion vector
        of block above if valid, otherwise use motion vector of block above
        left if valid, otherwise use motion vector of block above right if
        valid, otherwise use 0 motion vector. Motion vector of a block is
        valid if macro block type is inter and motion vector has not been
        concealed. Additionally, macro block has to be "inside vop".
                 
        Input:
        pDecContainer   pointer to decContainer_t
        mbNum

        Output:

------------------------------------------------------------------------------*/
void SwDec_MotionVectorConcealment(decContainer_t* pDecContainer, u32 mbNum)
{

    u32 tmp;
    u32 location;
    u32 width;
    u32 refMbNumber = 0;

    location = EC_NOCANDO;
    width = pDecContainer->VopDesc.vopWidth;

    if (mbNum >= width)
    {
        /* try above */
        refMbNumber = mbNum - width;
        if ( MB_IS_INTER(refMbNumber) && 
             !(pDecContainer->MbDesc[refMbNumber].errorStatus & 0x80) )
        {
            location = EC_ABOVE;
        }
        else 
        {
            /* determine location of the current macroblock */
            tmp = pDecContainer->StrmStorage.col[mbNum];

            /* try above left if not first column */
            if ( tmp && MB_IS_INTER(refMbNumber-1) &&
                 !(pDecContainer->MbDesc[refMbNumber-1].errorStatus &
                     0x80) )
            {
                refMbNumber--;
                location = EC_ABOVELEFT;
            }
            /* try above right if not last column */
            else if ( (tmp != (width-1)) &&
                MB_IS_INTER(refMbNumber+1) &&
                !(pDecContainer->MbDesc[refMbNumber+1].errorStatus &
                    0x80) )
            {
                refMbNumber++;
                location = EC_ABOVERIGHT;
            }
        }
    }

    switch (location)
    {
        case EC_ABOVE:
            /* use motion vector of block 2 for blocks 0 and 2 */
            pDecContainer->MbDesc[mbNum].data[0] =
            pDecContainer->MbDesc[mbNum].data[4] =
                pDecContainer->MbDesc[refMbNumber].data[4];
            pDecContainer->MbDesc[mbNum].data[1] =
            pDecContainer->MbDesc[mbNum].data[5] =
                pDecContainer->MbDesc[refMbNumber].data[5];
            /* use motion vector of block 3 for blocks 1 and 3 */
            pDecContainer->MbDesc[mbNum].data[2] =
            pDecContainer->MbDesc[mbNum].data[6] =
                pDecContainer->MbDesc[refMbNumber].data[6];
            pDecContainer->MbDesc[mbNum].data[3] =
            pDecContainer->MbDesc[mbNum].data[7] =
                pDecContainer->MbDesc[refMbNumber].data[7];
            break;

        case EC_ABOVELEFT:
            /* use motion vector of block 3 for all blocks */
            pDecContainer->MbDesc[mbNum].data[0] =
            pDecContainer->MbDesc[mbNum].data[2] =
            pDecContainer->MbDesc[mbNum].data[4] =
            pDecContainer->MbDesc[mbNum].data[6] =
                pDecContainer->MbDesc[refMbNumber].data[6];
            pDecContainer->MbDesc[mbNum].data[1] =
            pDecContainer->MbDesc[mbNum].data[3] =
            pDecContainer->MbDesc[mbNum].data[5] =
            pDecContainer->MbDesc[mbNum].data[7] =
                pDecContainer->MbDesc[refMbNumber].data[7];
            break;

        case EC_ABOVERIGHT:
            /* use motion vector of block 2 for all blocks */
            pDecContainer->MbDesc[mbNum].data[0] =
            pDecContainer->MbDesc[mbNum].data[2] =
            pDecContainer->MbDesc[mbNum].data[4] =
            pDecContainer->MbDesc[mbNum].data[6] =
                pDecContainer->MbDesc[refMbNumber].data[4];
            pDecContainer->MbDesc[mbNum].data[1] =
            pDecContainer->MbDesc[mbNum].data[3] =
            pDecContainer->MbDesc[mbNum].data[5] =
            pDecContainer->MbDesc[mbNum].data[7] =
                pDecContainer->MbDesc[refMbNumber].data[5];
            break;

        case EC_NOCANDO:
            pDecContainer->MbDesc[mbNum].data[0] = 0;
            pDecContainer->MbDesc[mbNum].data[1] = 0;
            pDecContainer->MbDesc[mbNum].data[2] = 0;
            pDecContainer->MbDesc[mbNum].data[3] = 0;
            pDecContainer->MbDesc[mbNum].data[4] = 0;
            pDecContainer->MbDesc[mbNum].data[5] = 0;
            pDecContainer->MbDesc[mbNum].data[6] = 0;
            pDecContainer->MbDesc[mbNum].data[7] = 0;
            break;

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

⌨️ 快捷键说明

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