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

📄 swdec_motiontextureutils.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 3 页
字号:
                dctDcSize = 1;
                length = 2;
            }
            else if (buffer >= 128)         /* 10xx xxxx */
            {    
                dctDcSize = 2;
                length = 2;
            }
            else if (buffer >= 96)          /* 011x xxxx */
            {
                dctDcSize = 0;
                length = 3;
            }
            else if (buffer >= 64)          /* 010x xxxx */
            {
                dctDcSize = 3;
                length = 3;
            }
            else if (buffer >= 32)          /* 001x xxxx */
            {
                dctDcSize = 4;
                length = 3;
            }
            else if (buffer >= 16)          /* 0001 xxxx */ 
            {
                dctDcSize = 5;
                length = 4;
            }
            else if (buffer >= 8)           /* 0000 1xxx */ 
            {
                dctDcSize = 6;
                length = 5;
            }
            else if (buffer >= 4)           /* 0000 01xx */ 
            {
                dctDcSize = 7;
                length = 6;
            }
            else if (buffer >= 2)           /* 0000 001x */ 
            {
                dctDcSize = 8;
                length = 7;
            }
            else if (buffer == 1)           /* 0000 0001 */ 
            {
                dctDcSize = 9;
                length = 8;
            }
            else 
            {
                return(HANTRO_NOK);
            }

        }

        /* And this is chrominance */
        else  
        {
            /* max length 9 -> drop 10 bits */
            buffer = tmp>>10;
        
            if (buffer >= 384)              /* 1 1xxx xxxx */
            {           
                dctDcSize = 0;
                length = 2;
            }
            else if (buffer >= 256)         /* 1 0xxx xxxx */
            {    
                dctDcSize = 1;
                length = 2;
            }
            else if (buffer >= 128)         /* 0 1xxx xxxx */
            {
                dctDcSize = 2;
                length = 2;
            }
            else if (buffer >= 64)          /* 0 01xx xxxx */
            {
                dctDcSize = 3;
                length = 3;
            }
            else if (buffer >= 32)          /* 0 001x xxxx */
            {
                dctDcSize = 4;
                length = 4;
            }
            else if (buffer >= 16)          /* 0 0001 xxxx */   
            {
                dctDcSize = 5;
                length = 5;
            }
            else if (buffer >= 8)           /* 0 0000 1xxx */ 
            {
                dctDcSize = 6;
                length = 6;
            }
            else if (buffer >= 4)           /* 0 0000 01xx */   
            {
                dctDcSize = 7;
                length = 7;
            }
            else if (buffer >= 2)           /* 0 0000 001x */ 
            {
                dctDcSize = 8;
                length = 8;
            }
            else if (buffer == 1)           /* 0 0000 0001 */ 
            {
                dctDcSize = 9;
                length = 9;
            }
            else 
            {
                return(HANTRO_NOK);
            }

        }

        if (dctDcSize == 0)
        {
            value = 0;
        }
        else
        {
            /* mask used bits away and drop extra bits out */
            buffer = (tmp>>(18-length-dctDcSize)) &
                ((1<<(dctDcSize+1))-1);

            /* check marker bit if dct_dc_size > 8 */
            if (dctDcSize > 8)
            {
                if ( !(buffer & 0x1) ) return(HANTRO_NOK);
                length += 1;
            }
            /* drop marker */
            buffer >>= 1;
            length += dctDcSize;
            
            /* msb indicates the sign (1 -> positive, 0 -> negative) */
            sign = !(buffer >> (dctDcSize-1));

            /* absolute value */
            tmp = buffer & ((1<<(dctDcSize-1))-1);

            /* negative value */
            if (sign)
            {
                value = -(1<<dctDcSize) + 1 + (i32)tmp;
            }
            /* positive value */
            else
            {
                value = (i32)((1<<(dctDcSize-1)) + tmp);
            }
        }
        status = SwDec_FlushBits(pDecContainer, length);
        CHECK_END_OF_STREAM(status);
    }
    
#endif
    pDecContainer->MbDesc[mbNum].data[blockNum] = (i16)value;

    return(HANTRO_OK);

}

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

   5.4  Function name: SwDec_DecodeMv

        Purpose: decode motion vectors of one macro block. Decodes vlc coded
        motion vectors, residual motion vectors and differential coding of mvs

        Input:
            pointer to decContainer_t
            macro block number

        Output:
            HANTRO_OK/HANTRO_NOK/END_OF_STREAM

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

u32 SwDec_DecodeMv(decContainer_t *pDecContainer, u32 mbNum)
{
    
    u32 i,tmp;
    mv_t mv;
    i32 high,low,range;
    i16 *pi16;
    u32 len = 0;
    u32 numMvs = 0;
#ifndef MP4DEC_H263_ONLY
    u32 rsize;
    tmpBuffer_t buffer;

    ASSERT(pDecContainer->VopDesc.fcodeFwd &&
          (pDecContainer->VopDesc.fcodeFwd < 8));
#endif
    ASSERT(pDecContainer);
    ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
    ASSERT(MB_IS_INTER(mbNum));

    pi16 = pDecContainer->MbDesc[mbNum].data;

#ifdef MP4DEC_H263_ONLY
    high = 31;
    low = -32;
    range = 64;

    tmp = SwDec_ShowBits(pDecContainer, 13);

    /* vlc code for horizontal motion vector */
    len = SwDec_DecodeMvVlc(tmp, &(mv.hor));
    if (!len) return(HANTRO_NOK);

    tmp = SwDec_FlushBits(pDecContainer, len);
    CHECK_END_OF_STREAM(tmp);
    
    tmp = SwDec_ShowBits(pDecContainer, 13);

    /* vlc code for vertical motion vector */
    len = SwDec_DecodeMvVlc(tmp, &(mv.ver));
    if (!len) return(HANTRO_NOK);

    tmp = SwDec_FlushBits(pDecContainer, len);
    CHECK_END_OF_STREAM(tmp);

    SwDec_DecodeMvDifferential(pDecContainer, &mv, mbNum, numMvs);

    if (mv.hor < low)
    {
        mv.hor += range;
    }
    else if (mv.hor > high)
    {
        mv.hor -= range;
    }

    if (mv.ver < low)
    {
        mv.ver += range;
    }
    else if (mv.ver > high)
    {
        mv.ver -= range;
    }
#else
    /* [low,high] and range determined based on vop_fcode_forward */
    rsize = pDecContainer->VopDesc.fcodeFwd - 1;
    high = (32 << rsize) - 1;
    low = -(32 << rsize);
    range = (64 << rsize);

    if (pDecContainer->MbDesc[mbNum].typeOfMb == MB_INTER4V)
    {
        numMvs = 4;
    }
    else
    {
        numMvs = 1;
    }

    BUFFER_INIT(buffer);

    for (i = 0; i < numMvs; i++)
    {
        BUFFER_SHOW(buffer,tmp,13);

        /* vlc code for horizontal motion vector */
        len = SwDec_DecodeMvVlc(tmp, &(mv.hor));
        if (!len) break;

        BUFFER_FLUSH(buffer,len);
        
        /* residual motion vector */
        if ( (rsize != 0) && (mv.hor != 0) )
        {
            BUFFER_GET(buffer,tmp,rsize);

            if (mv.hor > 0)
            {
                mv.hor = ((mv.hor - 1) << rsize) + (i32)tmp + 1;
            }
            else
            {
                mv.hor = -((-mv.hor - 1) << rsize) - (i32)tmp - 1;
            }

        }

        BUFFER_SHOW(buffer, tmp, 13);

        /* vlc code for vertical motion vector */
        len = SwDec_DecodeMvVlc(tmp, &(mv.ver));
        if (!len) break;

        BUFFER_FLUSH(buffer,len);

        /* residual motion vector */
        if ( (rsize != 0) && (mv.ver != 0) )
        {
            BUFFER_GET(buffer,tmp,rsize);

            if (mv.ver > 0)
            {
                mv.ver = ((mv.ver - 1) << rsize) + (i32)tmp + 1;
            }
            else
            {
                mv.ver = -((-mv.ver - 1) << rsize) - (i32)tmp - 1;
            }

        }

        SwDec_DecodeMvDifferential(pDecContainer, &mv, mbNum, i);

        if (mv.hor < low)
        {
            mv.hor += range;
        }
        else if (mv.hor > high)
        {
            mv.hor -= range;
        }

        if (mv.ver < low)
        {
            mv.ver += range;
        }
        else if (mv.ver > high)
        {
            mv.ver -= range;
        }

        *pi16++ = (i16)mv.hor;
        *pi16++ = (i16)mv.ver;
    }

    tmp = SwDec_FlushBits(pDecContainer,32-buffer.bits);
    CHECK_END_OF_STREAM(tmp);

    if (!len) return(HANTRO_NOK);
#endif
    /* just one motion vector -> copy value to other three locations */
    for (i = numMvs; i < 4; i++)
    {
        /*lint --e(771) */
        *pi16++ = (i16)mv.hor;
        *pi16++ = (i16)mv.ver;
    }

    return(HANTRO_OK);

}

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

   5.5  Function name: SwDec_DecodeMvVlc

        Purpose: decode vlc coded motion vector

        Input:
            buffer:         buffer container 13 coded bits
            motionVector:   pointer to motion vector

        Output:
            length of decoded code word, 0 if not found

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

u32 SwDec_DecodeMvVlc(u32 buffer, i32 *motionVector)
{

    mvTable_t tab;

    ASSERT(motionVector);
    ASSERT(buffer < 8192);
    
    if (buffer > 4095)
    {
        tab.val = 0;
        tab.len = 1;
    }
    else if (buffer > 511)
    {           
        tab = MvTable1[(buffer>>8)-2];
    }
    else if (buffer > 255)
    {    
        tab = MvTable2[(buffer>>5)-8];
    }
    else if (buffer > 127)
    {
        tab = MvTable3[(buffer>>2)-32];
    }
    else if (buffer > 31)
    {
        tab = MvTable4[(buffer>>3)-4];
        /* sign */
        if (buffer & 0x4)
            tab.val = -tab.val;
    }
    else if (buffer > 3)
    {
        tab = MvTable5[buffer-4];
    }
    else 
    {
        return(0);
    }

    *motionVector = tab.val;

    return(tab.len);

}

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

   5.6  Function name: SwDec_DecodeMvDifferential

        Purpose: decode motion vector differential coding

        Input:
            pointer to decContainer_t
            pointer to horizontal motion vector to be updated
            pointer to vertical motion vector to be updated
            macro block number
            mvNum indicates which motion vector is decoded, [0,3], max
                4 mvs

        Output:

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

void SwDec_DecodeMvDifferential(decContainer_t *pDecContainer, mv_t *mv,
    u32 mbNum, u32 mvNum)
{
    
    u32 validCount;
    mv_t mvLeft, mvAbove, mvRight;
    u32 vpBoundaryMb;
    u32 width,column;
    i32 hor, ver;

    ASSERT(pDecContainer);
    ASSERT(mv);
    ASSERT(mvNum < 4);
    ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
    ASSERT(mbNum >= pDecContainer->StrmStorage.vpMbNumber);
    ASSERT(pDecContainer->VopDesc.vopWidth);
    ASSERT(pDecContainer->MbDesc);
    
    width = pDecContainer->VopDesc.vopWidth;
    column = pDecContainer->StrmStorage.col[mbNum];

    /* normal mpeg4 stream or short video gob which started with gob header ->
     * respect start of video packet (candidates outside packet invalid) */
#ifdef MP4DEC_H263_ONLY
    if ( pDecContainer->StrmStorage.gobResyncFlag )
    {
        vpBoundaryMb = pDecContainer->StrmStorage.vpMbNumber;
    }
#else
    if ( !pDecContainer->StrmStorage.shortVideo ||
         pDecContainer->StrmStorage.gobResyncFlag )
    {
        vpBoundaryMb = pDecContainer->StrmStorage.vpMbNumber;
    }
#endif
    /* short video and gob without header -> ignore video packet boundaries
     * here */
    else
    {
        vpBoundaryMb = 0;
    }

    mvLeft = SwDec_GetLeftMvCandidate(pDecContainer->MbDesc, mbNum, mvNum,
        column, vpBoundaryMb);
    mvAbove = SwDec_GetAboveMvCandidate(pDecContainer->MbDesc, mbNum, mvNum,
        width, vpBoundaryMb);
    mvRight = SwDec_GetRightMvCandidate(pDecContainer->MbDesc, mbNum, mvNum,
        width, column, vpBoundaryMb);

    /* number of valid candidates */
    /*lint --e(514) */
    validCount = (mvLeft.hor != NON_VALID_MV) +
                     (mvAbove.hor != NON_VALID_MV) +
                     (mvRight.hor != NON_VALID_MV);

    hor = ver = 0;

    switch (validCount)
    {
        /* case 0: all candidates set to zero -> predictor 0 -> do nothing */
            
        case 1:
            /* use the one and only valid value, 2 values equal to NON_VALID_MV
             * -> add all three and subtract 2 non valid ones */
            hor = mvLeft.hor + mvAbove.hor + mvRight.hor - 2*NON_VALID_MV;
            ver = mvLeft.ver + mvAbove.ver + mvRight.ver - 2*NON_VALID_MV;
            break;

        case 2:
            /* determine which one is non valid and set to 0 */
            if (mvLeft.hor == NON_VALID_MV)
            {
                mvLeft.hor = mvLeft.ver = 0;
            }
            else if (mvAbove.hor == NON_VALID_MV)
            {
                mvAbove.hor = mvAbove.ver = 0;
            }
            else
            {
                mvRight.hor = mvRight.ver = 0;
            }
            /* FALLTHRU (or something) */

        case 3:

            hor = SwDec_MedianFilter(mvLeft.hor,mvAbove.hor,mvRight.hor);
            ver = SwDec_MedianFilter(mvLeft.ver,mvAbove.ver,mvRight.ver);

⌨️ 快捷键说明

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