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

📄 mp4swdecapi.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 : The API module C-functions of the MPEG4 Decoder
--
-------------------------------------------------------------------------------*/


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

    Table of contents 

    1. Include headers
    2. External identifiers
    3. Module defines
    4. Module identifiers
    5. Functions
        - MP4SwDecDecode()
        - MP4SwDecInit()
        - MP4SwDecGetInfo()
        - MP4SwDecGetUserData()
        - MP4SwDecRelease()
        - MP4SwDecGetAPIVersion()
        - MP4SwDecGetQPs()
        - MP4SwDecGetDeblockingInfo()
 
------------------------------------------------------------------------------*/

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

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

#ifdef MP4DEC_TRACE
#include <stdio.h>
#endif

/*------------------------------------------------------------------------------
       Version Information
------------------------------------------------------------------------------*/

#define MP4SWDEC_MAJOR_VERSION 3
#define MP4SWDEC_MINOR_VERSION 2

/*------------------------------------------------------------------------------
    2. External compiler flags 
--------------------------------------------------------------------------------
MP4DEC_H263_ONLY        When this flag is defined the decoder supports
                        only H.263 decoding (MPEG-4 is disabled).

MP4DEC_TRACE            Trace MP4 Decoder API function calls.

MP4DEC_EVALUATION       if defined, decoder decodes only limited 
                        number of frames.

MP4DEC_ARM11            Enables ARM11 optimizations.

MP4DEC_UNALIGNED        Uses unaligned memory access support.
--------------------------------------------------------------------------------
    3. Module defines 
------------------------------------------------------------------------------*/

#define MP4DEC_EVALUATION_LIMIT     400

#ifndef NULL
#define NULL 0
#endif

#ifdef MP4DEC_TRACE
#define DEC_API_TRC(str)    MP4SwDecTrace(str)
#else
#define DEC_API_TRC(str)
#endif

/*lint -e826 -e702 -e774 */

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

static void SwDec_ClearDataStructures(decContainer_t *pDecCont);

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

         Function name: MP4SwDecDecode

         Purpose:       Decodes a block of MPEG4 stream
                 
         Input:         pDecInst        decoder instance
                        *pInput         pointer to input structure
                        *pOutput        pointer to output structure

         Output:        MP4SwDecRet (enum) 

------------------------------------------------------------------------------*/
MP4SwDecRet MP4SwDecDecode(MP4SwDecInst     pDecInst, 
                           MP4SwDecInput    *pInput, 
                           MP4SwDecOutput   *pOutput)
{
#define API_STOR pDecCont->ApiStorage
#define DEC_ERRS pDecCont->ErrInfo
    decContainer_t *pDecCont;
    u32 pcf = 0;
    u32 DecResult = 0;
    MP4SwDecRet returnValue = MP4SWDEC_OK;

    if ((pInput == NULL) || (pOutput == NULL))
    {
        DEC_API_TRC("MP4SwDecDecode# ERROR: pInput == NULL or pOutput == NULL");
        return(MP4SWDEC_PARAM_ERR);
    }
   
    /* Initialize function variables */
    pOutput->nbrOfErrMBs = 0;
        
    /* Check if decoder instance is NULL */
    if(pDecInst == NULL)
    {
        DEC_API_TRC("MP4SwDecDecode# ERROR: Decoder instance is NULL");
        return(MP4SWDEC_NOT_INITIALIZED);
    }
    pDecCont = (decContainer_t*)pDecInst;

    /* Check if decoder is in an incorrect mode */
    if(API_STOR.DecStat == UNINIT)
    {
        DEC_API_TRC("MP4SwDecDecode# ERROR: Decoder not initialized");
        return(MP4SWDEC_NOT_INITIALIZED);
    }
    
#ifdef MP4DEC_TRACE
    sprintf(pDecCont->str, "MP4SwDecDecode# pDecInst %p  pInput %p  pOutput %p",
                                    (MP4SwDecInst *)pDecInst, pInput, pOutput);
    DEC_API_TRC(pDecCont->str);
#endif

    /* Check that function input parameters are valid */
    if((pInput->pStream == NULL) || (pInput->dataLen == 0))
    {
        DEC_API_TRC("MP4SwDecDecode# ERROR: Not valid Input parameters");
        return(MP4SWDEC_PARAM_ERR);
    }

    if(API_STOR.DecStat == HEADERSDECODED)
    {
        /* allocate decoder internal memories if not user allocated */
        if (pInput->pExtOutputPic != NULL)
            pDecCont->StrmStorage.extPicBufAlloc = 1;
            
        if (SwDec_MemAlloc(pDecCont))
        {
            API_STOR.BufStat = NEWBUF;
            return (MP4SWDEC_MEMFAIL);
        }
        /* change state */
        API_STOR.DecStat = STREAMDECODING;
    }

    if (API_STOR.BufStat == NEWBUF)
    {
        /* Assign pointers into structures */
        pDecCont->StrmDesc.pStrmBuffStart       = pInput->pStream;
        pDecCont->StrmDesc.pStrmCurrPos         = pInput->pStream;
        pDecCont->StrmDesc.bitPosInWord         = 0;
        pDecCont->StrmDesc.strmBuffSize         = pInput->dataLen;
        pDecCont->StrmDesc.strmBuffReadBits     = 0;
    
        /* Set zeros to user data field.
         * User data fields are valid only for the latest stream buffer */
        pDecCont->StrmDesc.userDataVOSLen = 0;
        pDecCont->StrmDesc.pUserDataVOS = 0;
        pDecCont->StrmDesc.userDataVOSMaxLen = 0;
        pDecCont->StrmDesc.userDataVOLen = 0;
        pDecCont->StrmDesc.pUserDataVO = 0;
        pDecCont->StrmDesc.userDataVOMaxLen = 0;
        pDecCont->StrmDesc.userDataVOLLen = 0;
        pDecCont->StrmDesc.pUserDataVOL = 0;
        pDecCont->StrmDesc.userDataVOLMaxLen = 0;
        pDecCont->StrmDesc.userDataGOVLen = 0;
        pDecCont->StrmDesc.pUserDataGOV = 0;
        pDecCont->StrmDesc.userDataGOVMaxLen = 0;
    }
    
    /* Check that output pointer is valid if external memory allocation */
    if ( (pInput->pExtOutputPic == NULL) && 
         (pDecCont->StrmStorage.extPicBufAlloc) )
    {
        DEC_API_TRC("MP4SwDecDecode# ERROR: Ext output pic pointer not valid");
        return(MP4SWDEC_PARAM_ERR);
    }
#ifndef _MP4API_UTEST
    /*Check that reference picture pointer is valid if external memory alloc */
    if ((pDecCont->pRef == NULL) && 
        (pDecCont->VopDesc.vopNumber > 0) && 
        (pDecCont->StrmStorage.extPicBufAlloc))
    {
        DEC_API_TRC("MP4API_Decode#ERROR: Reference picture pointer not valid");
        return(MP4SWDEC_PARAM_ERR);
    }
#endif

    if (pDecCont->StrmStorage.extPicBufAlloc)
        pDecCont->pOut = (u8*)pInput->pExtOutputPic;

#ifdef MP4DEC_EVALUATION
    if (pDecCont->VopDesc.vopNumber > MP4DEC_EVALUATION_LIMIT)
        return (MP4SWDEC_EVALUATION_LIMIT_EXCEEDED);
#endif
 
    DecResult = SwDec_Decode(pDecCont);

    switch(DecResult)
    {
        case DEC_ERROR: 
            /* Nothing finished, decoder not ready, cannot continue decoding
             * before some headers received */
            returnValue = MP4SWDEC_STRM_ERR;
            API_STOR.BufStat = NEWBUF;
            break;

        case DEC_ERROR_BUF_NOT_EMPTY:
            /* same as above but stream buffer not empty */
            returnValue = MP4SWDEC_STRM_ERR_BUFF_NOT_EMPTY;
            API_STOR.BufStat = OLDBUF;
            break;

        case DEC_END_OF_STREAM:
            /* nothing finished, no data left in stream */
        case DEC_RDY:
            /* everything ok but no VOP finished */
            returnValue = MP4SWDEC_STRM_PROCESSED;
            API_STOR.BufStat = NEWBUF;
            break;

        case DEC_VOP_RDY:
        case DEC_VOP_RDY_BUF_NOT_EMPTY:
            /* vop finished */
            pOutput->pOutputPicture = (u32*)pDecCont->pOut;
            
            if (pDecCont->StrmStorage.extPicBufAlloc)
            {
                /* set reference picture pointer for the next VOP */
                pDecCont->pRef = pDecCont->pOut;
            }
            pOutput->nbrOfErrMBs = DEC_ERRS.numErrMb;
            
#ifdef  MP4DEC_H263_ONLY
            /* picture frequency */
            pcf = ((pDecCont->SvDesc.tics * 
                    pDecCont->SvDesc.clockDivisor * 
                    pDecCont->SvDesc.clockConversionCode) /
                    pDecCont->Hdrs.vopTimeIncrementResolution);

            pOutput->timeCode.hours     = (pcf / 3600);
            pOutput->timeCode.minutes   = (pcf / 60) % 60;
            pOutput->timeCode.seconds   = (pcf) % 60;
            pOutput->timeCode.timeIncr  = 
                (pDecCont->SvDesc.tics * pDecCont->SvDesc.clockDivisor *
                 pDecCont->SvDesc.clockConversionCode) % 
                 pDecCont->Hdrs.vopTimeIncrementResolution;
            pOutput->timeCode.timeRes   = 
                pDecCont->Hdrs.vopTimeIncrementResolution;
#else
            if (pDecCont->StrmStorage.shortVideo)
            {
                /* picture frequency */
                pcf = ((pDecCont->SvDesc.tics * 
                        pDecCont->SvDesc.clockDivisor * 
                        pDecCont->SvDesc.clockConversionCode) /
                        pDecCont->Hdrs.vopTimeIncrementResolution);

                pOutput->timeCode.hours     = (pcf / 3600);
                pOutput->timeCode.minutes   = (pcf / 60) % 60;
                pOutput->timeCode.seconds   = (pcf) % 60;
                pOutput->timeCode.timeIncr  = 
                    (pDecCont->SvDesc.tics * pDecCont->SvDesc.clockDivisor *
                     pDecCont->SvDesc.clockConversionCode) % 
                     pDecCont->Hdrs.vopTimeIncrementResolution;
                pOutput->timeCode.timeRes   = 
                     pDecCont->Hdrs.vopTimeIncrementResolution;
            }
            else 
            {
                pOutput->timeCode.hours = pDecCont->VopDesc.timeCodeHours;
                pOutput->timeCode.minutes = pDecCont->VopDesc.timeCodeMinutes;
                pOutput->timeCode.seconds = pDecCont->VopDesc.timeCodeSeconds;
                pOutput->timeCode.timeIncr = pDecCont->VopDesc.vopTimeIncrement;
                pOutput->timeCode.timeRes = 
                    pDecCont->Hdrs.vopTimeIncrementResolution;
            }
#endif
            if (DecResult == DEC_VOP_RDY)
            {
                API_STOR.BufStat = NEWBUF;
                returnValue = MP4SWDEC_VOP_RDY;
            }
            else
            {
                API_STOR.BufStat = OLDBUF;
                returnValue = MP4SWDEC_VOP_RDY_BUFF_NOT_EMPTY;
            }
            break;

        case DEC_HDRS_RDY:
        case DEC_HDRS_RDY_BUF_NOT_EMPTY:
            /* either vol header decoded or short video source format
             * determined */
            API_STOR.DecStat = HEADERSDECODED;
            
            /* set headers lock */
            pDecCont->Hdrs.lock = 1;
            
            if (DecResult == DEC_HDRS_RDY)
            {
                returnValue = MP4SWDEC_HDRS_RDY;
                API_STOR.BufStat = NEWBUF;
            }
            else
            {
                returnValue = MP4SWDEC_HDRS_RDY_BUFF_NOT_EMPTY;
                API_STOR.BufStat = OLDBUF;
            }
            break;

        case DEC_VOS_END:
            /* vos end code encountered, stopping */
            returnValue = MP4SWDEC_VOS_END;
            API_STOR.BufStat = NEWBUF;
            break;

        default:
            returnValue = MP4SWDEC_STRM_ERR;
            API_STOR.BufStat = NEWBUF;
    }
#ifdef MP4DEC_TRACE
        sprintf(pDecCont->str, "MP4SwDecDecode# OK: DecResult %d",
                returnValue);
        DEC_API_TRC(pDecCont->str);
#endif
         
    return (returnValue);

#undef API_STOR
#undef DEC_ERRS
}

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

        Function name: MP4SwDecInit()

        Purpose:    Initialize decoder
                 
        Input:      MP4SwDecInst *pDecInst 

        Output:     MP4SwDecRet

------------------------------------------------------------------------------*/
MP4SwDecRet MP4SwDecInit(MP4SwDecInst *pDecInst)
{
    decContainer_t *pDecCont;

#ifdef MP4DEC_TRACE
    DEC_API_TRC("MP4SwDecInit#");
#endif

    /* check that right shift on negative numbers is performed signed */
    /*lint --e(572) --e(649) --e(506) */
    if ( ((-1)>>1) != (-1) )
    {
        DEC_API_TRC("MP4SwDecInit# ERROR: Right shift is not signed");
        return(MP4SWDEC_PARAM_ERR);
    }
    
    pDecCont = (decContainer_t *)MP4SwDecMalloc(sizeof(decContainer_t));
    
    if (pDecCont == NULL)
    {
        DEC_API_TRC("MP4SwDecInit# ERROR: pDecCont == NULL");
        return(MP4SWDEC_MEMFAIL);
    }
    SwDec_ClearDataStructures(pDecCont);
 
    SwDec_Init(pDecCont);

    pDecCont->ApiStorage.DecStat      = INITIALIZED;
    pDecCont->ApiStorage.BufStat      = NEWBUF;
    
#ifdef MP4DEC_TRACE
        sprintf(pDecCont->str, "MP4SwDecInit# OK: return %p",(void*)pDecCont);
        DEC_API_TRC(pDecCont->str);
#endif
    /*lint --e(740) */
    *pDecInst = (MP4SwDecInst *)pDecCont;
    
    return (MP4SWDEC_OK);
}

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

        Function name: MP4SwDecGetInfo()

        Purpose:    This function is used to get stream information.
                 
        Input:      MP4SwDecInst pDecInst   (decoder instance)
                    MP4SwDecInfo *pDecInfo  (pointer to config structure)
                    
        Output:     MP4SwDecRet

------------------------------------------------------------------------------*/
MP4SwDecRet MP4SwDecGetInfo(MP4SwDecInst pDecInst, MP4SwDecInfo *pDecInfo)
{
    decContainer_t *pDecCont;

    if ((pDecInst == NULL) || (pDecInfo == NULL))
    {

⌨️ 快捷键说明

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