📄 swdec_vop.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 : VOP decoding functionality
--
-------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
5.1 SwDec_DecodeVopHeader
5.2 SwDec_DecodeVop
5.3 SwDec_ReadVopComplexity
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "SwDec_Vop.h"
#include "SwDec_Utils.h"
#include "SwDec_MotionTexture.h"
#include "MP4SwDecApi.h" /* for Memcpy */
/*------------------------------------------------------------------------------
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_DecodeVopHeader(decContainer_t *pDecContainer);
STATIC u32 SwDec_ReadVopComplexity(decContainer_t *pDecContainer);
/*------------------------------------------------------------------------------
5.1 Function name: SwDec_DecodeVopHeader
Purpose: Decode VideoObjectPlane header
Input:
Pointer to decContainer_t structure
Output:
HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeVopHeader(decContainer_t *pDecContainer)
{
u32 i,tmp;
i32 itmp;
u32 moduloTimeBase,vopTimeIncrement;
u32 status = HANTRO_OK;
/* check that previous vop was finished, if it wasnt't return start code
* into the stream and get away */
if (pDecContainer->StrmStorage.vpMbNumber)
{
(void)SwDec_UnFlushBits(pDecContainer,32);
pDecContainer->StrmStorage.pLastSync =
pDecContainer->StrmDesc.pStrmCurrPos;
return(HANTRO_NOK);
}
/* vop header is non valid until successively decoded */
pDecContainer->StrmStorage.validVopHeader = 0;
pDecContainer->StrmStorage.vpMbNumber = 0;
pDecContainer->StrmStorage.vpNumMbs = 0;
pDecContainer->StrmStorage.resyncMarkerLength = 0;
tmp = SwDec_GetBits(pDecContainer,2); /* vop coding type */
CHECK_END_OF_STREAM(tmp);
if ( (tmp != IVOP) && (tmp != PVOP) )
{
return(HANTRO_NOK);
}
pDecContainer->VopDesc.vopCodingType = tmp;
/* Time codes updated at the end of function so that they won't be updated
* twice if header is lost (updated if vop header lost and header extension
* received in video packet header) */
/* modulo time base */
moduloTimeBase = 0;
while ((tmp = SwDec_GetOneBit(pDecContainer)) == 1)
moduloTimeBase++;
CHECK_END_OF_STREAM(tmp);
/* 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);
vopTimeIncrement = SwDec_GetBits(pDecContainer, i);
CHECK_END_OF_STREAM(vopTimeIncrement);
if (vopTimeIncrement >=
pDecContainer->Hdrs.vopTimeIncrementResolution)
{
return(HANTRO_NOK);
}
/* marker */
tmp = SwDec_GetOneBit(pDecContainer);
CHECK_END_OF_STREAM(tmp);
if (tmp == 0)
{
return(HANTRO_NOK);
}
/* vop coded */
tmp = SwDec_GetOneBit(pDecContainer);
CHECK_END_OF_STREAM(tmp);
pDecContainer->VopDesc.vopCoded = tmp;
if (pDecContainer->VopDesc.vopCoded)
{
/* vop rounding type */
if (pDecContainer->VopDesc.vopCodingType == PVOP)
{
tmp = SwDec_GetOneBit(pDecContainer);
CHECK_END_OF_STREAM(tmp);
}
else
{
tmp = 0;
}
pDecContainer->VopDesc.vopRoundingType = tmp;
if (!pDecContainer->Hdrs.complexityEstimationDisable)
{
status = SwDec_ReadVopComplexity(pDecContainer);
if (status != HANTRO_OK) return(status);
}
tmp = SwDec_GetBits(pDecContainer,3);
CHECK_END_OF_STREAM(tmp);
pDecContainer->VopDesc.intraDcVlcThr = tmp;
pDecContainer->VopDesc.QP = SwDec_GetBits(pDecContainer,5);
CHECK_END_OF_STREAM(pDecContainer->VopDesc.QP);
if (pDecContainer->VopDesc.QP == 0)
{
return(HANTRO_NOK);
}
pDecContainer->StrmStorage.QP = pDecContainer->VopDesc.QP;
pDecContainer->StrmStorage.prevQP = pDecContainer->VopDesc.QP;
pDecContainer->StrmStorage.vpQP = pDecContainer->VopDesc.QP;
if (pDecContainer->VopDesc.vopCodingType == PVOP)
{
tmp = SwDec_GetBits(pDecContainer,3);
CHECK_END_OF_STREAM(tmp);
if (tmp == 0)
{
return(HANTRO_NOK);
}
pDecContainer->VopDesc.fcodeFwd = tmp;
}
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;
}
/* update time codes */
pDecContainer->VopDesc.timeCodeSeconds += moduloTimeBase;
/* 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++;
}
}
/* compute tics since previous picture */
itmp = (i32)vopTimeIncrement -
(i32)pDecContainer->VopDesc.vopTimeIncrement +
(i32)moduloTimeBase*
(i32)pDecContainer->Hdrs.vopTimeIncrementResolution;
pDecContainer->VopDesc.ticsFromPrev = (itmp >= 0) ? (u32)itmp:
(u32)(itmp + (i32)pDecContainer->Hdrs.vopTimeIncrementResolution);
pDecContainer->VopDesc.vopTimeIncrement = vopTimeIncrement;
pDecContainer->VopDesc.moduloTimeBase = moduloTimeBase;
/* everything ok this far -> set vop header valid. If vop was not coded
* don't set the flag -> if there were errors in vop header decoding they
* don't limit decoding of header extension in video packets. */
if (pDecContainer->VopDesc.vopCoded)
{
pDecContainer->StrmStorage.validVopHeader = 1;
}
return(HANTRO_OK);
}
/*------------------------------------------------------------------------------
5.2 Function name: SwDec_DecodeVop
Purpose: Decode VideoObjectPlane
Input:
Pointer to decContainer_t structure
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -