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

📄 swdec_processblock.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        row += verMv;

#ifdef MP4DEC_H263_ONLY
        SwDec_GetBlock(pRef, pOut, col, row,
            pDecContainer->VopDesc.vopWidth * 8,
            pDecContainer->VopDesc.vopWidth * 8,
            pDecContainer->VopDesc.vopHeight * 8, 1);
#else
        SwDec_GetBlock(pRef, pOut, col, row,
            pDecContainer->VopDesc.vopWidth * 8,
            pDecContainer->VopDesc.vopWidth * 8,
            pDecContainer->VopDesc.vopHeight * 8,
            (u32)(pDecContainer->VopDesc.vopRoundingType != 1));
#endif
    }

}

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

   5.4  Function name:  SwDec_ChrMv

        Purpose: Compute chrominance motion vector based on luminance motion
        vectors
                 
        Input: 
        motionVectors   pointer to 4 luminance motion vectors (4 pairs,
                        hor,ver,hor,ver,hor,ver,hor,ver)
        chrHorMv        pointer to horizontal chr motion vector
        chrVerMv        pointer to vertical chr motion vector

        Output:

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

void SwDec_ChrMv(i16 *motionVectors, i32 *chrHorMv, i32 *chrVerMv)
{

    i32 tmp;
    static const i32 roundingTable[16] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};

    ASSERT(motionVectors);
    ASSERT(chrHorMv);
    ASSERT(chrVerMv);

    /* Sum of four motion vector */
    *chrHorMv  = motionVectors[0] + motionVectors[2] +
                     motionVectors[4] + motionVectors[6];

    tmp = (*chrHorMv < 0) ? -(*chrHorMv) : (*chrHorMv);
    tmp = ((tmp>>4)<<1) + roundingTable[tmp & 0xF];
    if (*chrHorMv < 0)
        *chrHorMv = -tmp;
    else
        *chrHorMv = tmp;

    /* Sum of four motion vector */
    *chrVerMv  = motionVectors[1] + motionVectors[3] +
                     motionVectors[5] + motionVectors[7];

    tmp = (*chrVerMv < 0) ? -(*chrVerMv) : (*chrVerMv);
    tmp = ((tmp>>4)<<1) + roundingTable[tmp & 0xF];
    if (*chrVerMv < 0)
        *chrVerMv = -tmp;
    else
        *chrVerMv = tmp;

}

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

   5.5  Function name:  SwDec_GetBlock

        Purpose: Get reference block for motion compensation
                 
        Input: 
        u8 *pRef        pointer to reference image
        u8 *pOut        pointer to output block
        i32 hosPos      horizontal position in reference picture
        i32 verPos      vertical position in reference picture
        u32 refWidth    width of reference picture (whole macro blocks)
        u32 width       width of the actual picture (half pixel precision)
        u32 height      height of the actual picture (half pixel precision)
        u32 round       rounding control (should be 1-vop_rounding_type)

        Output:

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

void SwDec_GetBlock(u8 *pRef,u8 *pOut, i32 horPos, i32 verPos, u32 refWidth,
    u32 width, u32 height, u32 round)
{
    i32 tmpx, tmpy;
    u32 interpolationCase;
    i32 row, lastRow;
    /* to ensure that fill is at word boundary */
    u32 fill[27];
    u8 *pFill = (u8*)fill;

    /* Limit horizontal position */
    SATURATE(-16, horPos, (i32)(2*width-2));

    /* Limit vertical position */
    SATURATE(-16, verPos, (i32)(2*height-2));

    /* determine full pixel position */
    tmpx = horPos>>1;
    tmpy = verPos>>1;

    interpolationCase = ((verPos&0x1)<<1) + (horPos&0x1);

    /* No overfill needed -> just interpolate if necessary */
    if ( (width >= 8) && ((u32)(horPos) < (2*width - 15)) &&
         (height >= 8) && ((u32)(verPos) < (2*height - 15)) )
    {
        pRef += (u32)tmpx + (u32)tmpy*width;

        if(interpolationCase == 0)
            SwDec_InterpolateNone(pRef, pOut, refWidth);
        else if(interpolationCase == 1)
            SwDec_InterpolateHorizontal(pRef, pOut, refWidth, round);
        else if(interpolationCase == 2)
            SwDec_InterpolateVertical(pRef, pOut, refWidth, round);
        else
            SwDec_InterpolateBoth(pRef, pOut, refWidth, round);
    }
    /* overfill and interpolation */
    else
    {
        row = tmpy;
        lastRow = tmpy + 9;

        /* Fill buffer "fill" so that it contains 9x9 elements to make interpolation
        * possible */
        /* overfill top */
        for (;row < 0; row++)
        {
            SwDec_FillRow(pRef, pFill, tmpx, width);
            pFill += 12;
        }
        pRef += row * (i32)refWidth;

        for (; row < lastRow; row++)
        {
            SwDec_FillRow(pRef, pFill, tmpx, width);
            pFill += 12;
            /* skip increment for overfill bottom */
            if (row < (i32)(height-1))
            {
                pRef += refWidth;
            }
        }
        pFill = (u8*)fill;

        if(interpolationCase == 0)
            SwDec_InterpolateNone(pFill, pOut, 12);
        else if(interpolationCase == 1)
            SwDec_InterpolateHorizontal(pFill, pOut, 12, round);
        else if(interpolationCase == 2)
            SwDec_InterpolateVertical(pFill, pOut, 12, round);
        else
            SwDec_InterpolateBoth(pFill, pOut, 12, round);

    }
}

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

   5.6  Function name:  SwDec_FillRow

        Purpose: Perform overfilling for one row if necessary
                 
        Input: 
        u8 *pRef        pointer to reference picture (where data is taken from)
        u8 *fill        pointer to (partial, 9 pixels) overfilled row
        i32 horPos      horizontal position in reference picture
        u32 width       width of the reference picture (in pixels)

        Output:

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

void SwDec_FillRow(u8 *pRef, u8 *fill, i32 horPos, u32 width)
{
    i32 last;

    ASSERT(pRef);
    ASSERT(fill);
    ASSERT(width);
    ASSERT(horPos < (i32)width);

    last = horPos + 9;

    for (; horPos < 0; horPos++) {
        *fill++  = *pRef;
    }
    
    pRef += horPos;

    for (; horPos < last; horPos++) {
        *fill++  = *pRef;
        if (horPos < (i32)(width-1))
             pRef++;
    }

} 

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

   5.7  Function name:  SwDec_InterpolateNone

        Purpose: Interpolate data in reference picture if necessary
                 
        Input: 
            pRef        pointer to reference picture
            pOut        pointer to interpolated block
            width       width of reference picture in pixels (whole macro
                        blocks)
            round       rounding control (should be 1-vop_rounding_type)

        Output:

------------------------------------------------------------------------------*/
void SwDec_InterpolateNone(u8 *pRef, u8 *pOut, u32 width)
{
    u32 i;
    u32 *pRef32;
    u32 *pOut32;
#ifndef MP4DEC_UNALIGNED
    u32 tmp1,tmp2,tmp3,tmp4;
#else
    u32 tmp1,tmp2,tmp;
#endif
    ASSERT(pRef);
    ASSERT(pOut);
    ASSERT(width >= 8);

#ifndef MP4DEC_UNALIGNED
    pOut32 = (u32*)pOut;
    
    /* at word boundary you can copy as u32 */
    if (((u32)pRef & 0x3) == 0)
    {
        pRef32 = (u32*)pRef;
        tmp3 = (width>>2)-1;
        for(i = 8; i; i--)
        {
            tmp1 = *pRef32++;
            tmp2 = *pRef32;
            *pOut32++ = tmp1;
            *pOut32++ = tmp2;
            pRef32 += tmp3;
        }
    }
    /* read as u8 and write as u8 */
    else
    {
        for(i = 8; i; i--)
        {
            tmp1 = *pRef++;
            tmp2 = *pRef++;
            tmp3 = *pRef++;
            tmp4 = *pRef++;

            *pOut++ = (u8)tmp1;
            *pOut++ = (u8)tmp2;
            *pOut++ = (u8)tmp3;
            *pOut++ = (u8)tmp4;
        
            tmp1 = *pRef++;
            tmp2 = *pRef++;
            tmp3 = *pRef++;
            tmp4 = *pRef;
        
            *pOut++ = (u8)tmp1;
            *pOut++ = (u8)tmp2;
            *pOut++ = (u8)tmp3;
            *pOut++ = (u8)tmp4;
        
            pRef += (width-7);
        }
    }
#else
    /* use unaligned support to read 
     * and write on word at a time */
    pOut32 = (u32*)pOut;
    pRef32 = (u32*)pRef;
    tmp = (width>>2)-1;
    for(i = 4; i; i--)
    {
        tmp1 = *pRef32++;
        *pOut32++ = tmp1;
        tmp2 = *pRef32;
        *pOut32++ = tmp2;
        pRef32 += tmp;
        
        tmp1 = *pRef32++;
        *pOut32++ = tmp1;
        tmp2 = *pRef32;
        *pOut32++ = tmp2;
        pRef32 += tmp;
    }
#endif
}

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

   5.8  Function name:  SwDec_InterpolateVertical

        Purpose: Interpolate data in reference picture if necessary
                 
        Input: 
            pRef        pointer to reference picture
            pOut        pointer to interpolated block
            width       width of reference picture in pixels (whole macro
                        blocks)
            round       rounding control (should be 1-vop_rounding_type)

        Output:


        Interpolation of MB in vertical direction:
        
        | xxxx++++ |
        | oooo++++ |
        | ++++++++ |    
        | ++++++++ |
        | ++++++++ |
        | ++++++++ |
        | ++++++++ |
        | ++++++++ |
        | @@@@@@@@ |
        
        Interpolation is done by bytewise x-o for four pixels at time if pRef is
        at word boundary in memory. Calculation is done as u32 instead of u8. At
        the beginning pRef points to the first x in picture above and ptmp points
        to the first o in picture above. Then pRef is incremented so that it 
        points to beginning of the row three. o's stays in temprorary variable 
        and then we interpolate bytewise o-x four pixels at time.
        
        Used algorithm:

        if ( rounding_control = 1)
            A/2 + B/2 + [(A & B) & 1]
        
        else (rounding_control = 0)
            A/2 + B/2 + [(A | B ) & 1]
        
------------------------------------------------------------------------------*/
void SwDec_InterpolateVertical(u8 *pRef, u8 *pOut, u32 width, u32 round)
{
    u32 i;
    u32 tmp1,tmp3;
    u32 tmp2=0, tmp4=0;
#if !defined(MP4DEC_ARM11) || !defined(MP4DEC_UNALIGNED)
    u32 *pRef32;
    u32 *ptmp32;
    u8 *ptmp;
    u32 *pOut32;
#else
    u32 tmpx,tmpy,c1;
#endif

    ASSERT(pRef);
    ASSERT(pOut);
    ASSERT(width >= 8);
    ASSERT(round <= 1);
    
#if !defined(MP4DEC_ARM11) || !defined(MP4DEC_UNALIGNED)
    ptmp = pRef + width;
    pOut32 = (u32*)pOut;
    
    /* check if the pRef is at word boundary */
    if (((u32)pRef & 0x3) == 0)
    {
        pRef32 = (u32*)pRef;
        ptmp32 = (u32*)ptmp;

        /* read one row */
        tmp1 = (*pRef32++);
        tmp3 = (*pRef32++);
        
        /* skip one row */
        pRef32 += ((width>>1)-2);

        if (round == 0)
        {
            for ( i = 8; i; i--)
            {
                if (i & 0x1)
                {
                    /* read one row */
                    tmp1 = (*pRef32++);
                    tmp3 = (*pRef32++);
        
                    /* skip one row */
                    pRef32 += ((width>>1)-2);
                }
                else
                {
                    /* read one row */
                    tmp2 = (*ptmp32++);
                    tmp4 = (*ptmp32++);

                    /* skip one row */
                    ptmp32 += ((width>>1)-2);
                }
                /* interpolate */
                *pOut32++ = (((tmp1>>1) & 0x7F7F7F7F) + ((tmp2>>1) & 0x7F7F7F7F)
                        + (( tmp1 & tmp2) & 0x01010101));
                
                *pOut32++ = (((tmp3>>1) & 0x7F7F7F7F) + ((tmp4>>1) & 0x7F7F7F7F)
                        + (( tmp3 & tmp4) & 0x01010101));
            }
        }
        else
        {
            for ( i = 8; i; i--)
            {
                if (i & 0x1)
                {
                    /* read one row */
                    tmp1 = (*pRef32++);
                    tmp3 = (*pRef32++);

                    /* skip one row */
                    pRef32 += ((width>>1)-2);
                }
                else
                {
                    /* read one row */
                    tmp2 = (*ptmp32++);
                    tmp4 = (*ptmp32++);
                    
                    /* skip one row */
                    ptmp32 += ((width>>1)-2);
                }
                /* interpolate four pixels at once */
                *pOut32++ = (((tmp1>>1) & 0x7F7F7F7F) + ((tmp2>>1) & 0x7F7F7F7F)
                        + (( tmp1 | tmp2) & 0x01010101));
                
                *pOut32++ = (((tmp3>>1) & 0x7F7F7F7F) + ((tmp4>>1) & 0x7F7F7F7F)
                        + (( tmp3 | tmp4) & 0x01010101));
            }
        }  
    }
    /* if pRef is not at word boundary */
    else
    {
        for( i = 8; i; i--)
        {   
            tmp1 = *pRef++;
            tmp3 = *pRef++;
            tmp2 = *ptmp++;
            tmp4 = *ptmp++;
            *pOut++ = (u8)((round+tmp1+tmp2)>>1);
            tmp1 = *pRef++;
            tmp2 = *ptmp++;
            *pOut++ = (u8)((tmp3+tmp4+round)>>1);
            tmp3 = *pRef++;
            tmp4 = *ptmp++;
            *pOut++ = (u8)((tmp1+tmp2+round)>>1);
            tmp1 = *pRef++;
            tmp2 = *ptmp++;
            *pOut++ = (u8)((tmp3+tmp4+round)>>1);
            tmp3 = *pRef++;
            tmp4 = *ptmp++;

⌨️ 快捷键说明

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