📄 swdec.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 : 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 + -