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

📄 swdec.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------
--                                                                            --
--       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 : Stream decoding top level functions (interface functions)
--
-------------------------------------------------------------------------------*/



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

    Table of contents
   
     1. Include headers
     2. External identifiers
     3. Module defines
     4. Module identifiers
     5. Fuctions
        5.1     SwDec_Init
        5.2     SwDec_Decode
        5.3     SwDec_PrepareConcealment
        5.4     SwDec_MemAlloc
        5.5     SwDec_MemFree

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

/*------------------------------------------------------------------------------
    1. Include headers
------------------------------------------------------------------------------*/
#include "MP4SwDecApi.h"
#include "SwDec_Utils.h"
#include "SwDec.h"
#include "SwDec_ShortVideo.h"
#include "SwDec_ErrorConcealment.h"

#ifndef MP4DEC_H263_ONLY
#include "SwDec_Headers.h"
#include "SwDec_Vop.h"
#include "SwDec_VideoPacket.h"
#endif

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

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

enum {
    CONTINUE = 0
};

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

STATIC u32 SwDec_PrepareConcealment(decContainer_t *pDecContainer,
    u32 startCode);

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

   5.1  Function name: SwDec_Init

        Purpose: initialize stream decoding related parts of decContainer_t
                 
        Input: 
            Pointer to decContainer_t structure

        Output:

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

void SwDec_Init(decContainer_t *pDecContainer)
{

    MP4SwDecMemset(&(pDecContainer->StrmStorage), 0, sizeof(decStrmStorage_t));
    pDecContainer->StrmStorage.status             = STATE_OK;
    /* initialize video packet qp to 1 -> reasonable qp value if first vop
     * has to be concealed */
    pDecContainer->StrmStorage.vpQP               = 1;

}

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

   5.2  Function name: SwDec_Decode

        Purpose: Decode MPEG4 stream. Continues decoding until END_OF_STREAM
        encountered or whole VOP decoded. Returns after decoding of VOL header.
        Also returns after checking source format in case short video header
        stream is decoded.
                 
        Input: 
            Pointer to decContainer_t structure

        Output:
            DEC_RDY if everything was ok but no VOP finished
            DEC_HDR_RDY if headers decoded
            DEC_HDR_RDY_BUF_NOT_EMPTY if headers decoded but buffer not empty
            DEC_VOP_RDY if whole VOP decoded
            DEC_VOP_RDY_BUF_NOT_EMPTY if whole VOP decoded but buffer not empty
            DEC_END_OF_STREAM if eos encountered while decoding
            DEC_ERROR if such an error encountered that recovery needs initial
            headers (in short video case only vop_with_sv_header needed)

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

#ifndef _MP4API_UTEST
u32 SwDec_Decode(decContainer_t *pDecContainer)
{

    u32 tmp;
    u32 status;
    u32 startCode;

    status = HANTRO_OK;

    /* reset last sync pointer if in the beginning of stream */
    if ( pDecContainer->StrmDesc.pStrmCurrPos ==
         pDecContainer->StrmDesc.pStrmBuffStart )
    {
        pDecContainer->StrmStorage.pLastSync =
            pDecContainer->StrmDesc.pStrmBuffStart;
    }

    if (pDecContainer->StrmStorage.vpMbNumber == 0)
    {
        /* reset error counter in the beginning of VOP */
        pDecContainer->ErrInfo.numErrMb = 0;

        if (!pDecContainer->StrmStorage.extPicBufAlloc)
        {
            /* swap output and reference picture pointers */
            tmp = (u32)pDecContainer->pRef;
            pDecContainer->pRef = pDecContainer->pOut;
            pDecContainer->pOut = (u8*)tmp;
        }
    }

    /* keep decoding till something ready or something wrong */
    do {

        if (pDecContainer->StrmStorage.status == STATE_OK)
        {
            startCode = SwDec_GetStartCode(pDecContainer);
            if (startCode == END_OF_STREAM)
            {
                if (pDecContainer->StrmStorage.strmDecReady)
                {
                    return(DEC_END_OF_STREAM);
                }
                else
                {
                    return(DEC_ERROR);
                }
            }
        }
        /* sync lost -> find sync and conceal */
#ifdef MP4DEC_H263_ONLY
        else
        {
            DEBUG(("SYNC LOST\n"));

            startCode = SwDec_FindSync(pDecContainer);
            /* return DEC_ERROR if decoder not ready, otherwise
             * return DEC_END_OF_STREAM if resync markers are enabled
             * or vop has not been started yet (header not decoded 
             * successfully), otherwise VOP is concealed */
            if (startCode == END_OF_STREAM)
            {
                if (pDecContainer->StrmStorage.strmDecReady)
                {
                    return(DEC_END_OF_STREAM);
                }
                else
                {
                    return(DEC_ERROR);
                }
            }

            /* decoder ready -> conceal */
            if (pDecContainer->StrmStorage.strmDecReady)
            {
                status = SwDec_PrepareConcealment(pDecContainer, startCode);

                /* decoding of VOP finished -> return */
                if (status == DEC_VOP_RDY)
                {
                    pDecContainer->StrmStorage.vpMbNumber = 0;
                    pDecContainer->StrmStorage.vpNumMbs = 0;
                    pDecContainer->StrmStorage.validVopHeader = 0;
                    pDecContainer->VopDesc.vopNumber++;
                    return(DEC_VOP_RDY_BUF_NOT_EMPTY);
                }
            }
            /* decoder not ready -> do not conceal but continue trying */
            else
            {
                pDecContainer->StrmStorage.status = STATE_OK;
            }
        }

        switch (startCode)
        {
            case SC_RESYNC:
                pDecContainer->StrmStorage.gobResyncFlag = 1;
                status = SwDec_DecodeGobLayer(pDecContainer);
                break;

            case SC_SV_START:
                if (!pDecContainer->StrmStorage.strmDecReady)
                {
                    status = SwDec_InitShortVideo(pDecContainer);
                    if (status == HANTRO_OK)
                    {
                        pDecContainer->StrmStorage.strmDecReady = 1;
                        return(DEC_HDRS_RDY_BUF_NOT_EMPTY);
                    }
                    else
                    {
                        pDecContainer->StrmStorage.status = STATE_SYNC_LOST;
                        return(DEC_ERROR_BUF_NOT_EMPTY);
                    }
                }
                else
                {
                    status = SwDec_DecodeShortVideo(pDecContainer);
                }
                break;

            case SC_SV_END:
                /* remove stuffing */
                status = HANTRO_OK;
                DEBUG(("SHORT_VIDEO_END\n"));
                if (pDecContainer->StrmDesc.bitPosInWord)
                {
                    tmp = SwDec_GetBits(pDecContainer,
                        8-pDecContainer->StrmDesc.bitPosInWord);
                }
                break;

            case SC_NOT_FOUND:
                if (!pDecContainer->StrmStorage.strmDecReady)
                {
                    pDecContainer->StrmStorage.status = STATE_SYNC_LOST;
                    if (IS_END_OF_STREAM(pDecContainer))
                        return(DEC_ERROR);
                    else
                        return(DEC_ERROR_BUF_NOT_EMPTY);
                }
                else
                {
                    pDecContainer->StrmStorage.gobResyncFlag = 0;
                    status = SwDec_DecodeGobLayer(pDecContainer);
                }
                break;
            
            default:
                status = HANTRO_NOK;
        }
#else
        else
        {
  //          DEBUG(("SYNC LOST\n"));

            startCode = SwDec_FindSync(pDecContainer);
            /* return DEC_ERROR if decoder not ready, otherwise
             * return DEC_END_OF_STREAM if resync markers are enabled
             * or vop has not been started yet (header not decoded 
             * successfully), otherwise VOP is concealed */
            if (startCode == END_OF_STREAM)
            {
                if (!pDecContainer->StrmStorage.strmDecReady)
                {
                    return(DEC_ERROR);
                }
                else
                {
                    return(DEC_END_OF_STREAM);
                }
            }

            /* decoder ready -> conceal */
            if (pDecContainer->StrmStorage.strmDecReady)
            {
                status = SwDec_PrepareConcealment(pDecContainer, startCode);

                pDecContainer->StrmStorage.startCodeLoss = 0;

                /* decoding of VOP finished -> return */
                if (status == DEC_VOP_RDY)
                {
                    pDecContainer->StrmStorage.vpMbNumber = 0;
                    pDecContainer->StrmStorage.vpNumMbs = 0;
                    pDecContainer->StrmStorage.validVopHeader = 0;
                    pDecContainer->VopDesc.vopNumber++;
                    if (startCode == END_OF_STREAM)
                    {
                        return(DEC_VOP_RDY);
                    }
                    else
                    {
                        return(DEC_VOP_RDY_BUF_NOT_EMPTY);
                    }
                }
            }
            /* decoder not ready -> do not conceal but continue trying */
            else
            {
                pDecContainer->StrmStorage.status = STATE_OK;
                pDecContainer->StrmStorage.startCodeLoss = 0;
            }
        }
        
        switch (startCode)
        {
            case SC_VOS_START:
            case SC_VISO_START:
            case SC_VO_START:
            case SC_VOL_START:

    //            DEBUG(("DECODING HEADERS\n"));
                if ( !pDecContainer->Hdrs.lock &&
                     pDecContainer->StrmStorage.strmDecReady )
                {
    //                DEBUG(("RE-INITIALIZATION!!!!\n"));
                    SwDec_MemFree(pDecContainer);
                    SwDec_Init(pDecContainer);
                    pDecContainer->StrmStorage.pLastSync =
                        pDecContainer->StrmDesc.pStrmCurrPos;
                    /* initialize default values for headers */
                    SwDec_ClearHeaders(&(pDecContainer->Hdrs));
                }
                status = SwDec_DecodeHeaders(pDecContainer,startCode);
                if (!pDecContainer->StrmStorage.strmDecReady)
                {
                    /* error in header decoding and decoder not ready (i.e. this
                     * is not repetition of header info) -> return control to
                     * caller */
                    if (status != HANTRO_OK)
                    {
                        pDecContainer->StrmStorage.status = STATE_SYNC_LOST;
                        if (status != END_OF_STREAM)
                        {
                            pDecContainer->ErrInfo.errorType = status;
                            return(DEC_ERROR_BUF_NOT_EMPTY);
                        }
                        else
                        {
                            pDecContainer->ErrInfo.errorType = NO_TYPE;
                            return(DEC_ERROR);
                        }
                    }
                    /* VOL decoded -> set vop size parameters and set
                     * strmDecReady. Return control to caller with
                     * indication whether buffer is empty or not */
                    else if (pDecContainer->Hdrs.lastHeaderType ==
                             SC_VOL_START)
                    {
                        pDecContainer->VopDesc.vopWidth =
                          (pDecContainer->Hdrs.videoObjectLayerWidth+15)>>4;
                        pDecContainer->VopDesc.vopHeight =
                          (pDecContainer->Hdrs.videoObjectLayerHeight+15)>>4;
                        pDecContainer->VopDesc.totalMbInVop =
                            pDecContainer->VopDesc.vopWidth *
                            pDecContainer->VopDesc.vopHeight;

                        pDecContainer->StrmStorage.strmDecReady = 1; 
                        if (IS_END_OF_STREAM(pDecContainer))
                        {
                            return(DEC_HDRS_RDY);
                        }
                        else
                        {
                            return(DEC_HDRS_RDY_BUF_NOT_EMPTY);
                        }
                    }
                    /* check if short video header -> continue decoding.
                     * Otherwise return ontrol */
                    else if (SwDec_ShowBits(pDecContainer,22) != SC_SV_START)
                    {
                        return(DEC_RDY);
                    }
                }
                break;

            case SC_GVOP_START:
                status = SwDec_DecodeGovHeader(pDecContainer);
                break;

            case SC_VOP_START:
                status = SwDec_DecodeVop(pDecContainer);
                break;

            case SC_RESYNC:
                if (pDecContainer->StrmStorage.shortVideo)
                {
                    pDecContainer->StrmStorage.gobResyncFlag = 1;

⌨️ 快捷键说明

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