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

📄 swdec_videopacket.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
字号:
/*------------------------------------------------------------------------------
--                                                                            --
--       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 : Video packet decoding functionality 
--
-------------------------------------------------------------------------------*/



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

    Table of contents
   
     1. Include headers
     2. External identifiers
     3. Module defines
     4. Module identifiers
     5. Fuctions
        5.1     SwDec_DecodeVideoPacketHeader
        5.2     SwDec_DecodeVideoPacket
        5.3     SwDec_CheckNextVpMbNumber

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


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

#include "SwDec_VideoPacket.h"
#include "SwDec_Utils.h"
#include "SwDec_MotionTexture.h"

/*------------------------------------------------------------------------------
    2. External identifiers 
------------------------------------------------------------------------------*/

#ifndef MP4DEC_H263_ONLY

/*------------------------------------------------------------------------------
    3. Module defines 
------------------------------------------------------------------------------*/


/*------------------------------------------------------------------------------
    4. Module indentifiers 
------------------------------------------------------------------------------*/

static const u32 stuffingTable[8] = {0x0,0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F};

STATIC u32 SwDec_DecodeVideoPacketHeader(decContainer_t *pDecContainer);

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

   5.1  Function name: SwDec_DecodeVideoPacketHeader

        Purpose: Decode video packet header
                 
        Input: 
            Pointer to decContainer_t structure

        Output:
            HANTRO_OK/HANTRO_NOK/END_OF_STREAM

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

u32 SwDec_DecodeVideoPacketHeader(decContainer_t *pDecContainer)
{

    u32 i,tmp;
    i32 itmp;

    pDecContainer->StrmStorage.vpNumMbs = 0;

    /* length of macro_block_number determined by size of the VOP in mbs */
    tmp = SwDec_NumBits(pDecContainer->VopDesc.totalMbInVop-1);
    tmp = SwDec_GetBits(pDecContainer, tmp);
    CHECK_END_OF_STREAM(tmp);

    /* erroneous macro block number */
    if (tmp != pDecContainer->StrmStorage.vpMbNumber)
    {
        return(HANTRO_NOK);
    }

    /* QP */
    tmp = SwDec_GetBits(pDecContainer, 5);
    CHECK_END_OF_STREAM(tmp);
    if (tmp == 0)
    {
        return(HANTRO_NOK);
    }

    pDecContainer->StrmStorage.QP = tmp;
    pDecContainer->StrmStorage.prevQP = tmp;
    pDecContainer->StrmStorage.vpQP = tmp;

    /* HEC */
    tmp = SwDec_GetOneBit(pDecContainer);
    CHECK_END_OF_STREAM(tmp);

    /* decode header extension. Values are used only if vop header was
     * lost for any reason. Otherwise values are just compared to ones
     * received in vop header and errors are reported if they do not match */
    if (tmp)
    {
        /* modulo time base */
        i = 0;
        while ((tmp = SwDec_GetOneBit(pDecContainer)) == 1) 
            i++;

        CHECK_END_OF_STREAM(tmp);

        /* update time codes if vop header not valid */
        if (!pDecContainer->StrmStorage.validVopHeader)
        {
            pDecContainer->VopDesc.timeCodeSeconds += i;
            /* to support modulo_time_base values higher than 60 -> while */
            while (pDecContainer->VopDesc.timeCodeSeconds >= 60)
            {
                 pDecContainer->VopDesc.timeCodeSeconds -= 60;
                 pDecContainer->VopDesc.timeCodeMinutes++;
                 if (pDecContainer->VopDesc.timeCodeMinutes >= 60)
                 {
                     pDecContainer->VopDesc.timeCodeMinutes -= 60;
                     pDecContainer->VopDesc.timeCodeHours++;
                 }
            }
            pDecContainer->VopDesc.moduloTimeBase = i;
        }
        else if (i != pDecContainer->VopDesc.moduloTimeBase)
        {
            return(HANTRO_NOK);
        }

        /* marker */
        tmp = SwDec_GetOneBit(pDecContainer);
        CHECK_END_OF_STREAM(tmp);
        if (tmp == 0)
        {
            return(HANTRO_NOK);
        }

        /* number of bits needed to represent
         * [0,vop_time_increment_resolution) */
        i = SwDec_NumBits(pDecContainer->Hdrs.vopTimeIncrementResolution
            - 1);
        tmp = SwDec_GetBits(pDecContainer, i);
        CHECK_END_OF_STREAM(tmp);

        if (!pDecContainer->StrmStorage.validVopHeader)
        {
            if (tmp >= pDecContainer->Hdrs.vopTimeIncrementResolution)
            {
                return(HANTRO_NOK);
            }
            /* compute tics since previous picture */
            itmp = (i32)tmp - (i32)(pDecContainer->VopDesc.vopTimeIncrement +
                pDecContainer->VopDesc.moduloTimeBase*
                pDecContainer->Hdrs.vopTimeIncrementResolution);

            pDecContainer->VopDesc.ticsFromPrev = (itmp >= 0) ? (u32)itmp:
                (u32)(itmp + (i32)pDecContainer->Hdrs.vopTimeIncrementResolution);
            pDecContainer->VopDesc.vopTimeIncrement = tmp;
        }
        else if (tmp != pDecContainer->VopDesc.vopTimeIncrement)
        {
            return(HANTRO_NOK);
        }

        /* marker */
        tmp = SwDec_GetOneBit(pDecContainer);
        CHECK_END_OF_STREAM(tmp);
        if (tmp == 0)
        {
            return(HANTRO_NOK);
        }

        tmp = SwDec_GetBits(pDecContainer,2); /* vop_coding_type */
        CHECK_END_OF_STREAM(tmp);
        if (pDecContainer->StrmStorage.validVopHeader)
        {
            if (tmp != pDecContainer->VopDesc.vopCodingType)
            {
                return(HANTRO_NOK);
            }
        }
        else
        {
            if ((tmp != IVOP) && (tmp != PVOP))
            {
                return(HANTRO_NOK);
            }
            else
            {
                pDecContainer->VopDesc.vopCodingType = tmp;
            }
        }

        tmp = SwDec_GetBits(pDecContainer,3); /* intra_dc_vlc_thr */
        CHECK_END_OF_STREAM(tmp);

        if (pDecContainer->StrmStorage.validVopHeader)
        {
            if (tmp != pDecContainer->VopDesc.intraDcVlcThr)
            {
                return(HANTRO_NOK);
            }
        }
        else
        {
            pDecContainer->VopDesc.intraDcVlcThr = tmp;
        }

        if (pDecContainer->VopDesc.vopCodingType == PVOP)
        {
            tmp = SwDec_GetBits(pDecContainer,3); /* vop_fcode_fwd */
            CHECK_END_OF_STREAM(tmp);
            if (pDecContainer->StrmStorage.validVopHeader)
            {
                if (tmp != pDecContainer->VopDesc.fcodeFwd)
                {
                    return(HANTRO_NOK);
                }
            }
            else
            {
                if (tmp == 0)
                {
                    return(HANTRO_NOK);
                }
                pDecContainer->VopDesc.fcodeFwd = tmp;
                pDecContainer->VopDesc.vopRoundingType = 0;
            }
        }
        else
        {
            /* set vop_fcode_fwd of intra VOP to 1 for resync marker length
             * computation */
            pDecContainer->VopDesc.fcodeFwd = 1;
        }

        pDecContainer->StrmStorage.resyncMarkerLength = 
            pDecContainer->VopDesc.fcodeFwd + 16;

        if (!pDecContainer->StrmStorage.validVopHeader)
        {
            pDecContainer->StrmStorage.validVopHeader = 1;
        }
    }

    if (pDecContainer->StrmStorage.validVopHeader)
    {
        return(HANTRO_OK);
    }
    else
    {
        return(HANTRO_NOK);
    }
}
	
/*------------------------------------------------------------------------------

   5.2  Function name: SwDec_DecodeVideoPacket

        Purpose: Decode video packet
                 
        Input: 
            Pointer to decContainer_t structure

        Output:
            HANTRO_OK/HANTRO_NOK/END_OF_STREAM

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

u32 SwDec_DecodeVideoPacket(decContainer_t *pDecContainer)
{

    u32 tmp;
    u32 isEndOfVop;
    u32 stuffingLength;
    u32 isResyncMarker = 0;
    u32 status = HANTRO_OK;

    ASSERT(pDecContainer);
    ASSERT(!pDecContainer->StrmStorage.shortVideo);

    status = SwDec_DecodeVideoPacketHeader(pDecContainer);
    if (status != HANTRO_OK) return(status);

    status = SwDec_DecodeMotionTexture(pDecContainer);
    if (status != HANTRO_OK) return(status);
    
    isEndOfVop = (pDecContainer->StrmStorage.vpMbNumber +
                  pDecContainer->StrmStorage.vpNumMbs) ==
                 pDecContainer->VopDesc.totalMbInVop;

    status = SwDec_GetStuffing(pDecContainer);
    if ( (status != HANTRO_OK) && isEndOfVop ) 
    {
        /* read stuffing until stream ends or resync marker or
         * startcode found */
        while( !IS_END_OF_STREAM(pDecContainer) )
        {
            tmp = SwDec_ShowBits(pDecContainer,32);
            isResyncMarker = 
                (tmp>>(32-pDecContainer->StrmStorage.resyncMarkerLength));
            
            /* break if there is resync marker or startcode */
            if ( (isResyncMarker == 0x1) || ((tmp>>8) == 0x1) )
                break;
            /* read stuffing byte */
            stuffingLength = 8-pDecContainer->StrmDesc.bitPosInWord;
            tmp = SwDec_GetBits(pDecContainer,stuffingLength);

            /* check that stuffing is valid H.263 or MPEG-4 stuffing */
            if ( (tmp != 0) && (tmp != stuffingTable[stuffingLength - 1]))
                return (HANTRO_NOK);
        }
    }
    else if ( status != HANTRO_OK )
        return (HANTRO_NOK);

    /* there might be extra stuffing byte if next start code is video
     * object sequence start or end code */
    tmp = SwDec_ShowBitsAligned(pDecContainer,32,1);
    if ((tmp == SC_VOS_START) || (tmp == SC_VOS_END))
    {
        tmp = SwDec_GetStuffing(pDecContainer);
        if (tmp != HANTRO_OK) return(tmp);
    }

    /* stuffing ok -> check that there is proper start code or marker or
     * stream ends */
    tmp = SwDec_ShowBits(pDecContainer,32);
    if (/* END_OF_STREAM */
        IS_END_OF_STREAM(pDecContainer) ||
        /* RESYNC_MARKER */
        (((tmp>>(32-pDecContainer->StrmStorage.resyncMarkerLength)) == 0x01) &&
         !isEndOfVop) ||
        /* end of VOP and START_CODE or SC_ERROR (i.e. at least 23 zeros) */
        (isEndOfVop && !(tmp>>9)))
    {
        /* whole video packet decoded and stuffing ok -> set vpMbNumber in
         * StrmStorage so that this video packet won't be touched/concealed
         * anymore. Also set VpQP to QP so that concealment will use qp of last
         * decoded macro block */
        pDecContainer->StrmStorage.vpMbNumber +=
            pDecContainer->StrmStorage.vpNumMbs;
        pDecContainer->StrmStorage.vpQP = pDecContainer->StrmStorage.QP;

        pDecContainer->StrmStorage.vpNumMbs = 0;

        return(HANTRO_OK);

    }
    else
    {
        return(HANTRO_NOK);
    }

}

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

   5.3  Function name: SwDec_CheckNextVpMbNumber

        Purpose: 
                 
        Input: 
            Pointer to decContainer_t structure

        Output:
            macro block number
            0 if non-valid number found in stream

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

u32 SwDec_CheckNextVpMbNumber(decContainer_t *pDecContainer)
{

    u32 tmp;
    u32 mbNumber;

    tmp = SwDec_NumBits(pDecContainer->VopDesc.totalMbInVop-1);

    /* if not enough bits left -> return 0 */
    if ((i32)tmp <= ( (i32)pDecContainer->StrmDesc.strmBuffSize*8 -
                 (i32)pDecContainer->StrmDesc.strmBuffReadBits ))
    {
        mbNumber = SwDec_ShowBits(pDecContainer, tmp);
        /* use zero value to indicate non valid macro block number */
        if (mbNumber >= pDecContainer->VopDesc.totalMbInVop)
        {
            mbNumber = 0;
        }
    }
    else
    {
        mbNumber = 0;
    }

    return(mbNumber);

}
#endif

⌨️ 快捷键说明

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