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

📄 swdec_processblock.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*------------------------------------------------------------------------------
--                                                                            --
--       This software is confidential and proprietary and may be used        --
--        only as expressly authorized by a licensing agreement from          --
--                                                                            --
--                            Hantro Products Oy.                             --
--                                                                            --
--      In the event of publication, the following notice is applicable:      --
--                                                                            --
--                   (C) COPYRIGHT 2004 HANTRO PRODUCTS OY                    --
--                            ALL RIGHTS RESERVED                             --
--                                                                            --
--         The entire notice above must be reproduced on all copies.          --
--                                                                            --
--------------------------------------------------------------------------------
--
--  Abstract : Block processing after variable length decoding
--
-------------------------------------------------------------------------------*/



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

    Table of contents
   
    1. Include headers
    2. External identifiers
    3. Module defines
    4. Module identifiers
    5. Functions
        5.1   SwDec_ProcessIntraBlock
        5.2   SwDec_ProcessInterBlock
        5.3   SwDec_GetReference
        5.4   SwDec_ChrMv
        5.5   SwDec_GetBlock
        5.6   SwDec_FillRow
        5.7   SwDec_InterpolateNone
        5.8   SwDec_InterpolateVertical
        5.9   SwDec_InterpolateHorizontal
        5.10  SwDec_InterpolateBoth   
        5.11  SwDec_AcDcPrediction
        5.12  SwDec_WriteIntraOutput
        5.13  SwDec_WriteInterOutput
        5.14  SwDec_CopyOutput

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


/*------------------------------------------------------------------------------
    1. Include headers
------------------------------------------------------------------------------*/

#include "SwDec_ProcessBlock.h"
#include "SwDec_Utils.h"
#include "SwDec_Idct.h"

/*------------------------------------------------------------------------------
    2. External identifiers 
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
    3. Module defines
------------------------------------------------------------------------------*/

/* macro to perform division with rounding, divisor has to be positive. Macro
 * is tested to work for all dc-scaling and quantization purposes, should not
 * be used to anything else unless carefully tested */
#ifndef MP4DEC_H263_ONLY
#define DIV_W_ROUND(a,b) (((a) + ((a)<0 ? -1 : 1)*((i32)(b)>>1))/(i32)(b))
#endif

/*lint -e826 -e702 */

/*------------------------------------------------------------------------------
    4. Module identifiers
------------------------------------------------------------------------------*/
#ifndef MP4DEC_H263_ONLY
/* luminance dc scaler for each QP */
static const u32 dcScalerLum[32] = { 0, 8, 8, 8, 8,10,12,14,16,17,18,
                                    19,20,21,22,23,24,25,26,27,28,29,
                                    30,31,32,34,36,38,40,42,44,46};

/* chrominance dc scaler for each QP */
static const u32 dcScalerChr[32] = { 0, 8, 8, 8, 8, 9, 9,10,10,11,11,
                                    12,12,13,13,14,14,15,15,16,16,17,
                                    17,18,18,19,20,21,22,23,24,25};
#endif

/* clipping table for output pixel values */
#ifndef MP4DEC_ARM11
static const u8 clip[768] =
{
    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, 
    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, 
    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, 
    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, 
    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
    16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
    32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
    48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
    64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
    80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
    96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
    160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
    192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
    208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
    224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
    240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
#endif

/*------------------------------------------------------------------------------
    4. Local function prototypes
------------------------------------------------------------------------------*/

STATIC void SwDec_GetBlock(u8 *, u8 *, i32, i32, u32, u32, u32, u32);
STATIC void SwDec_FillRow(u8 *, u8 *, i32, u32);
STATIC void SwDec_ChrMv(i16 *, i32 *, i32 *);

STATIC void SwDec_InterpolateNone(u8 *pRef, u8 *pOut, u32 width);
STATIC void SwDec_InterpolateVertical(u8 *pRef, u8 *pOut, u32 width, u32 round);
STATIC void SwDec_InterpolateHorizontal(u8 *pRef, u8 *pOut, u32 width, u32 round);
STATIC void SwDec_InterpolateBoth(u8 *pRef, u8 *pOut, u32 width, u32 round);

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

   5.1  Function name: SwDec_ProcessIntraBlock

        Purpose: Intra block processing.
                 
        Input: 
        pDecContainer       pointer to decContainer_t
        pData               pointer to block data after scanning, partially
                            inverse quantized (excluding first row and col)
        mbNum
        blockNum
        scanDir             scanning mode (SCAN_ZIGZAG, SCAN_HOR, SCAN_VER)

        Output:

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

void SwDec_ProcessIntraBlock(decContainer_t *pDecContainer, i32 *pData,
    u32 mbNum, u32 blockNum, u32 scanDir)
{

    ASSERT(pDecContainer);
    ASSERT(pData);
    ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
    ASSERT(blockNum < 6);
    ASSERT(scanDir < 3);
    ASSERT(MB_IS_INTRA(mbNum));

#ifdef MP4DEC_H263_ONLY
    /* copy separately decoded dc coefficient into first data element */
    pData[0] = pDecContainer->MbDesc[mbNum].data[blockNum];
       
    /* use constant dc_scaler for short video */
    pData[0] *= 8;
    /* store inverse quantized dc coefficient */
    pDecContainer->MbDesc[mbNum].data[blockNum] = pData[0];
#else
    /* copy separately decoded dc coefficient into first data element */
    if (pDecContainer->MbDesc[mbNum].flags & USE_INTRA_DC_VLC_MASK)
    {
        pData[0] = pDecContainer->MbDesc[mbNum].data[blockNum];
    }
       
    if (!pDecContainer->StrmStorage.shortVideo)
    {
        SwDec_AcDcPrediction(pDecContainer, pData, mbNum,
            blockNum, scanDir);
    }
    else
    {
        /* use constant dc_scaler for short video */
        pData[0] *= 8;
        /* store inverse quantized dc coefficient */
        pDecContainer->MbDesc[mbNum].data[blockNum] = (i16)pData[0];
    }
#endif
    /* do IDCT for intra block. Coefficients are written directly
     * to output picture in the IDCT routine */
    SwDec_IdctIntra(pDecContainer, pData, mbNum, blockNum);
}

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

   5.2  Function name: SwDec_ProcessInterBlock

        Purpose: Inter block processing
                 
        Input: 
        pDecContainer       pointer to decContainer_t
        pData               pointer to block data after scanning, partially
                            inverse quantized (excluding dc coefficient)
        mbNum
        blockNum

        Output:

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

void SwDec_ProcessInterBlock(decContainer_t *pDecContainer, i32 *pData,
    u32 mbNum, u32 blockNum)
{
    u32 i;
    /* memory for 64 bytes, has to be word aligned */
    u32 ref[16];
    u8 *pIn = (u8*)ref;
    u8 *pOut = (u8*)ref;
    i32 tmp1,tmp2,tmp3,tmp4;
#ifndef MP4DEC_ARM11
    const u8* pClipTable = clip+256;
#else
    u32 tmpx;
    u32 width;
    u32 rowOffset,colOffset;
#endif

    ASSERT(pDecContainer);
    ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
    ASSERT(blockNum < 6);
    ASSERT(MB_IS_INTER(mbNum));

    SwDec_GetReference(pDecContainer, (u8*)ref, mbNum, blockNum);

    if (pDecContainer->MbDesc[mbNum].codedBits & (0x20>>blockNum))
    {
        ASSERT(pData);

        SwDec_IdctInter(pData, pDecContainer->StrmStorage.numIdctRows);
        /* add reference data and clip to [0,255] */
#ifndef MP4DEC_ARM11
        for (i = 4; i  ; i--)
        {
            tmp1 = *pIn++;
            /*lint --e(613) */
            tmp2 = *pData++;
            tmp3 = *pIn++;
            tmp4 = *pData++;
            
            *pOut++ = pClipTable[tmp1 + tmp2];
            tmp1 = *pIn++;
            tmp2 = *pData++;
            *pOut++ = pClipTable[tmp3 + tmp4];
            tmp3 = *pIn++;
            tmp4 = *pData++;
            *pOut++ = pClipTable[tmp1 + tmp2];
            tmp1 = *pIn++;
            tmp2 = *pData++;
            *pOut++ = pClipTable[tmp3 + tmp4];
            tmp3 = *pIn++;
            tmp4 = *pData++;
            *pOut++ = pClipTable[tmp1 + tmp2];
            tmp1 = *pIn++;
            tmp2 = *pData++;
            *pOut++ = pClipTable[tmp3 + tmp4];
            tmp3 = *pIn++;
            tmp4 = *pData++;
            *pOut++ = pClipTable[tmp1 + tmp2];
            *pOut++ = pClipTable[tmp3 + tmp4];

            tmp1 = *pIn++;
            tmp2 = *pData++;
            tmp3 = *pIn++;
            tmp4 = *pData++;
            
            *pOut++ = pClipTable[tmp1 + tmp2];
            tmp1 = *pIn++;
            tmp2 = *pData++;
            *pOut++ = pClipTable[tmp3 + tmp4];
            tmp3 = *pIn++;
            tmp4 = *pData++;
            *pOut++ = pClipTable[tmp1 + tmp2];
            tmp1 = *pIn++;
            tmp2 = *pData++;
            *pOut++ = pClipTable[tmp3 + tmp4];
            tmp3 = *pIn++;
            tmp4 = *pData++;
            *pOut++ = pClipTable[tmp1 + tmp2];
            tmp1 = *pIn++;
            tmp2 = *pData++;
            *pOut++ = pClipTable[tmp3 + tmp4];
            tmp3 = *pIn++;
            tmp4 = *pData++;
            *pOut++ = pClipTable[tmp1 + tmp2];
            *pOut++ = pClipTable[tmp3 + tmp4];
        }
    }
    SwDec_WriteInterOutput(pDecContainer, (u8*)ref, mbNum, blockNum);
#else
        /* calculate output address */
        /* luminance */
        if (blockNum < 4)
        {
            width = pDecContainer->VopDesc.vopWidth*16;
            rowOffset = pDecContainer->StrmStorage.row[mbNum]*16 +
                  (blockNum>>1)*8;
            colOffset = pDecContainer->StrmStorage.col[mbNum]*16 +
                (blockNum&0x1)*8;
            pOut = pDecContainer->pOut + rowOffset*width + colOffset;
        }
        /* chrominance */
        else
        {
            width = pDecContainer->VopDesc.vopWidth*8;
            rowOffset = pDecContainer->StrmStorage.row[mbNum]*8;
            colOffset = pDecContainer->StrmStorage.col[mbNum]*8;
            pOut = pDecContainer->pOut + 
                (256+(blockNum&0x1)*64)*pDecContainer->VopDesc.vopWidth*
                pDecContainer->VopDesc.vopHeight +
                rowOffset*width + colOffset;
        }

        /* add reference data and saturate to [0,255] by
         * using ARM11 SIMD instructions. Writes directly to 
         * output picture */
        __asm
        {
            MOV     i, #8;
        loop:
            LDR     tmpx, [pIn], #4;    /* load four pixel (ref) */
            LDR     tmp1, [pData], #4;  /* load IDCT coefficients */
            LDR     tmp2, [pData], #4;
            LDR     tmp3, [pData], #4;
            LDR     tmp4, [pData], #4;

            PKHBT   tmp1, tmp1, tmp3, LSL #16;  /* pack two coefficients */
            UADD8TO16   tmp1, tmp1, tmpx;   /* add two u8 pels to i16 coeff */
            USAT16  tmp1, #8, tmp1;         /* saturate two pels [0,255] */

            PKHBT   tmp2, tmp2, tmp4, LSL #16;  /* pack next two coeffs. */
            UADD8TO16   tmp2, tmp2, tmpx, ROR #8;   /* add pels to coeffs. */
            USAT16  tmp2, #8, tmp2;         /* saturate two pels [0,255] */
            ORR     tmp1, tmp1, tmp2, LSL #8;   /* pack 4 pels to one word */
            STR     tmp1, [pOut];       /* store 4 pels to output picture */

            LDR     tmpx, [pIn], #4;
            LDR     tmp1, [pData], #4;
            LDR     tmp2, [pData], #4;
            LDR     tmp3, [pData], #4;
            LDR     tmp4, [pData], #4;

            PKHBT   tmp1, tmp1, tmp3, LSL #16;
            UADD8TO16   tmp1, tmp1, tmpx;
            USAT16  tmp1, #8, tmp1;

            PKHBT   tmp2, tmp2, tmp4, LSL #16;
            UADD8TO16   tmp2, tmp2, tmpx, ROR #8;
            USAT16  tmp2, #8, tmp2;
            ORR     tmp1, tmp1, tmp2, LSL #8;
            STR     tmp1, [pOut, #4];
            ADD     pOut,pOut,width;

            SUBS    i, i, #1;
            BNE     loop;
        }
    }
    else
    {
        SwDec_WriteInterOutput(pDecContainer, (u8*)ref, mbNum, blockNum);
    }
#endif
}

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

   5.3  Function name: SwDec_GetReference

        Purpose: Get reference block for inter block motion compensation
                 
        Input: 
        pDecContainer   pointer to decContainer_t
        pOut            pointer to output (where reference block is written)
        mbNum
        blockNum

        Output:

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

void SwDec_GetReference(decContainer_t *pDecContainer, u8 *pOut,
    u32 mbNum, u32 blockNum)
{ 

    i32 row,col;
    i32 horMv, verMv;
    u8 *pRef;

    ASSERT(pDecContainer);
    ASSERT(pOut);
    ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
    ASSERT(blockNum < 6);

    row = (i32)pDecContainer->StrmStorage.row[mbNum];
    col = (i32)pDecContainer->StrmStorage.col[mbNum];

    if (blockNum < 4)
    {
        /* half pixel positions */
        col *= 32;
        row *= 32;
        if (blockNum & 0x1)
            col += 16;
        if (blockNum & 0x2)
            row += 16;

        /* horizontal position */
        col += pDecContainer->MbDesc[mbNum].data[blockNum*2];
        /* vertical position */
        row += pDecContainer->MbDesc[mbNum].data[blockNum*2+1];

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

        pRef = pDecContainer->pRef +
            (256+(blockNum&0x1)*64)*pDecContainer->VopDesc.vopWidth*
            pDecContainer->VopDesc.vopHeight;

        SwDec_ChrMv(pDecContainer->MbDesc[mbNum].data,
            &horMv, &verMv);

        /* horizontal position */
        col += horMv;
        /* vertical position */

⌨️ 快捷键说明

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