📄 swdec_shortvideo.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 : Short video (h263) decoding functionality
--
-------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
5.1 SwDec_DecodeGobLayer
5.2 SwDec_DecodeShortVideo
5.3 SwDec_DecodeShortVideoHeader
5.4 SwDec_CheckNextGobNumber
5.5 SwDec_DecodeGobHeader
5.6 SwDec_InitShortVideo
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "SwDec_ShortVideo.h"
#include "SwDec_Utils.h"
#include "SwDec_MotionTexture.h"
/*------------------------------------------------------------------------------
2. External identifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
4. Module indentifiers
------------------------------------------------------------------------------*/
static const u32 stuffingTable[8] = {0x0,0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F};
STATIC u32 SwDec_DecodeShortVideoHeader(decContainer_t* pDecContainer);
STATIC u32 SwDec_DecodeGobHeader(decContainer_t* pDecContainer);
/*------------------------------------------------------------------------------
5.1 Function name: SwDec_DecodeGobLayer
Purpose: decode Group Of Blocks (GOB) layer
Input:
Pointer to decContainer_t structure
Output:
HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeGobLayer(decContainer_t *pDecContainer)
{
u32 tmp;
u32 mbNumber,mbCounter;
u32 numMbs;
u32 stuffingLength;
u32 status = HANTRO_OK;
ASSERT(pDecContainer);
#ifndef MP4DEC_H263_ONLY
ASSERT(pDecContainer->StrmStorage.shortVideo);
#endif
/* gob header */
if (pDecContainer->StrmStorage.gobResyncFlag)
{
status = SwDec_DecodeGobHeader(pDecContainer);
if (status != HANTRO_OK) return(status);
pDecContainer->StrmStorage.vpFirstCodedMb =
pDecContainer->StrmStorage.vpMbNumber;
}
numMbs = pDecContainer->StrmStorage.numMbsInGob;
mbNumber = pDecContainer->StrmStorage.vpMbNumber;
mbCounter = 0;
/*lint --e(716) */
while(1)
{
status = SwDec_DecodeMb(pDecContainer, mbNumber);
if (status != HANTRO_OK) return(status);
if (!MB_IS_STUFFING(mbNumber))
{
mbNumber++;
mbCounter++;
/* read remaining stuffing macro blocks if end of GOB or
* last MB in vop */
if ( (mbCounter == numMbs) ||
(mbNumber == pDecContainer->VopDesc.totalMbInVop))
{
/*lint --e(514) */
tmp = 9 + (pDecContainer->VopDesc.vopCodingType==PVOP);
while (SwDec_ShowBits(pDecContainer, tmp) == 0x01)
(void)SwDec_FlushBits(pDecContainer, tmp);
break;
}
}
}
/* stuffing */
/* there is stuffing if next byte aligned bits are resync marker or
* stream ends at next byte aligned position */
if ( (SwDec_ShowBitsAligned(pDecContainer,17,1) == SC_RESYNC) ||
( ((pDecContainer->StrmDesc.strmBuffReadBits>>3) + 1) ==
pDecContainer->StrmDesc.strmBuffSize ) )
{
stuffingLength = 8-pDecContainer->StrmDesc.bitPosInWord;
tmp = SwDec_ShowBits(pDecContainer, stuffingLength);
if ( (tmp == 0) || (tmp == stuffingTable[stuffingLength - 1]) )
{
SwDec_FlushBits(pDecContainer, stuffingLength);
}
}
/* last gob of vop -> check if short video end code. Read if yes and
* check that there is stuffing and either end of stream or short video
* start */
if (mbNumber == pDecContainer->VopDesc.totalMbInVop)
{
tmp = SwDec_ShowBits(pDecContainer,22);
if (tmp == SC_SV_END)
{
(void)SwDec_FlushBits(pDecContainer,22);
}
/* read stuffing until stream ends or resync marker or
* startcode found */
while( !IS_END_OF_STREAM(pDecContainer) )
{
/* check if there is resync marker
* or startcode prefix */
tmp = SwDec_ShowBits(pDecContainer, 32);
if ( (tmp>>15) == 0x1 ||
(tmp == SC_VOS_START) ||
(tmp == SC_VOS_END))
break;
stuffingLength = 8-pDecContainer->StrmDesc.bitPosInWord;
tmp = SwDec_GetBits(pDecContainer, stuffingLength);
if (tmp == END_OF_STREAM) return (END_OF_STREAM);
if ( (tmp != 0) && (tmp != stuffingTable[stuffingLength - 1]) )
{
return(HANTRO_NOK);
}
}
#ifndef MP4DEC_H263_ONLY
/* there might be extra stuffing byte if next start code is video
* object sequence start or end code. If this is the case the
* stuffing is normal mpeg4 stuffing. */
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);
}
#endif
/* check that there is either end of stream or short video start
* (only checking that first 17 bits are short video resync marker) or
* at least 23 zeros in the stream */
tmp = SwDec_ShowBits(pDecContainer,23);
if ( !IS_END_OF_STREAM(pDecContainer) &&
((tmp>>6) != SC_RESYNC) && tmp )
{
return(HANTRO_NOK);
}
}
/* whole video packet decoded and stuffing ok (if stuffed) -> set
* vpMbNumber in StrmStorage so that this gob layer 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 = mbNumber;
pDecContainer->StrmStorage.vpQP = pDecContainer->StrmStorage.QP;
pDecContainer->StrmStorage.vpNumMbs = 0;
return (status);
}
/*------------------------------------------------------------------------------
5.2 Function name: SwDec_DecodeShortVideo
Purpose: decode VOP with short video header
Input:
Pointer to decContainer_t structure
Output:
HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeShortVideo(decContainer_t *pDecContainer)
{
u32 status = HANTRO_OK;
ASSERT(pDecContainer);
#ifndef MP4DEC_H263_ONLY
ASSERT(pDecContainer->StrmStorage.shortVideo);
#endif
status = SwDec_DecodeShortVideoHeader(pDecContainer);
if (status != HANTRO_OK) return(status);
status = SwDec_DecodeGobLayer(pDecContainer);
return(status);
}
/*------------------------------------------------------------------------------
5.3 Function name: SwDec_DecodeShortVideoHeader
Purpose: decode short video header
Input:
Pointer to decContainer_t structure
Output:
HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeShortVideoHeader(decContainer_t *pDecContainer)
{
u32 tmp;
u32 ufep = 0;
/* 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,22);
pDecContainer->StrmStorage.pLastSync =
pDecContainer->StrmDesc.pStrmCurrPos;
return(HANTRO_NOK);
}
pDecContainer->StrmStorage.validVopHeader = 0;
/* temporal reference. Note that arithmetics are performed only with
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -