📄 swdec.c
字号:
status = SwDec_DecodeGobLayer(pDecContainer);
}
else
{
status = SwDec_DecodeVideoPacket(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_VOS_END:
// DEBUG(("VIDEO_OBJECT_SEQUENCE_END\n"));
return(DEC_VOS_END);
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);
}
/* start code not found and decoding short video stream ->
* try to decode gob layer */
else if (pDecContainer->StrmStorage.shortVideo)
{
pDecContainer->StrmStorage.gobResyncFlag = 0;
status = SwDec_DecodeGobLayer(pDecContainer);
}
/* normal mpeg4 stream packet should always start either with
* start code or resync marker */
else
{
status = HANTRO_NOK;
}
break;
default:
status = HANTRO_NOK;
}
#endif
if (status != HANTRO_OK)
{
pDecContainer->StrmStorage.status = STATE_SYNC_LOST;
}
/* status OK in all cases below */
/* decoding ok, whole VOP decoded -> return DEC_VOP_RDY */
else if ( pDecContainer->StrmStorage.strmDecReady &&
(pDecContainer->StrmStorage.vpMbNumber ==
pDecContainer->VopDesc.totalMbInVop) )
{
pDecContainer->StrmStorage.vpMbNumber = 0;
pDecContainer->StrmStorage.validVopHeader = 0;
pDecContainer->VopDesc.vopNumber++;
if (IS_END_OF_STREAM(pDecContainer))
{
return(DEC_VOP_RDY);
}
else
{
return(DEC_VOP_RDY_BUF_NOT_EMPTY);
}
}
/* decoding ok but stream ends -> get away */
else if (IS_END_OF_STREAM(pDecContainer))
{
return(DEC_RDY);
}
/*lint --e(506) */
} while (1);
}
#endif
/*------------------------------------------------------------------------------
5.3 Function name: SwDec_PrepareConcealment
Purpose: Set data needed by error concealment and call concealment
Input:
Pointer to decContainer_t structure
startCode
Output:
CONTINUE to indicate that decoding should be continued
DEC_VOP_RDY to indicate that decoding of VOP was finished
------------------------------------------------------------------------------*/
u32 SwDec_PrepareConcealment(decContainer_t *pDecContainer, u32 startCode)
{
u32 i;
u32 first, last;
/* first mb to be concealed */
first = pDecContainer->StrmStorage.vpMbNumber;
if (startCode == SC_RESYNC)
{
#ifdef MP4DEC_H263_ONLY
/* determine macro block number of next video packet */
last = SwDec_CheckNextGobNumber(pDecContainer) *
pDecContainer->StrmStorage.numMbsInGob;
#else
/* determine macro block number of next video packet */
if (!pDecContainer->StrmStorage.shortVideo)
{
last = SwDec_CheckNextVpMbNumber(pDecContainer);
}
else
{
last = SwDec_CheckNextGobNumber(pDecContainer) *
pDecContainer->StrmStorage.numMbsInGob;
}
#endif
/* last equal to zero -> incorrect number found from stream, cannot
* do anything */
if (!last)
{
return(CONTINUE);
}
/* Consider VOP start code (and tail of previous vop) lost if:
* -mb number less than previous by macro_blocks_in_vop/8 or
* -start code loss detected (assumption: if first is zero ->
* previous vop was successfully decoded and we may have lost e.g.
* GVOP start code and header)
* -> Conceal rest of the VOP. Beginning of next VOP will be concealed
* on next invocation -> status left as STATE_SYNC_LOST */
if ( /* case 1 */ ( first > (last +
(pDecContainer->VopDesc.totalMbInVop>>3) ) ) ||
/* case 2 */ ( first &&
pDecContainer->StrmStorage.startCodeLoss ) )
{
/* conceal rest of the vop */
last = pDecContainer->VopDesc.totalMbInVop;
/* return resync marker into stream so that beginning of next
* VOP can be concealed later */
SwDec_UnFlushBits(pDecContainer,
pDecContainer->StrmStorage.resyncMarkerLength);
/* set last sync to beginning of marker -> will be found next
* time (starting search before last sync point prohibited) */
pDecContainer->StrmStorage.pLastSync =
pDecContainer->StrmDesc.pStrmCurrPos;
}
/* cannot conceal -> continue and (possibly) conceal at next sync
* point */
else if (last < first)
{
return(CONTINUE);
}
/* macro block number in the stream matches expected -> continue
* decoding without concealment */
else if (last == first)
{
pDecContainer->StrmStorage.status = HANTRO_OK;
return(CONTINUE);
}
/* set error status for all macro blocks to be concealed */
for (i = first; i < last; i++)
{
#ifdef MP4DEC_H263_ONLY
pDecContainer->MbDesc[i].errorStatus = EVERYTHING_LOST;
#else
/* data partitioned and first partition ok -> texture lost
* (vpNumMbs set by partitioned motion texture decoding
* function right after detection of motion/dc marker) */
if (pDecContainer->Hdrs.dataPartitioned &&
( (pDecContainer->StrmStorage.vpMbNumber +
pDecContainer->StrmStorage.vpNumMbs) == last ))
{
pDecContainer->MbDesc[i].errorStatus = TEXTURE_LOST;
}
/* otherwise everything lost */
else
{
pDecContainer->MbDesc[i].errorStatus = EVERYTHING_LOST;
}
#endif
}
// DEBUG(("CONCEALING [%d,%d]\n",first,last-1));
SwDec_ErrorConcealment(pDecContainer,first, last-1);
if (last == pDecContainer->VopDesc.totalMbInVop)
{
/* leave status as it was (STATE_SYNC_LOST) */
return(DEC_VOP_RDY);
}
else
{
pDecContainer->StrmStorage.vpMbNumber = last;
pDecContainer->StrmStorage.vpNumMbs = 0;
pDecContainer->StrmStorage.status = STATE_OK;
return(CONTINUE);
}
}
/* start code (or END_OF_STREAM) */
else
{
/* conceal rest of the vop and return DEC_VOP_RDY */
last = pDecContainer->VopDesc.totalMbInVop;
#ifdef MP4DEC_H263_ONLY
SwDec_UnFlushBits(pDecContainer,22);
for (i = first; i < last; i++)
{
pDecContainer->MbDesc[i].errorStatus = EVERYTHING_LOST;
}
#else
/* return start code into stream */
if ((startCode == SC_SV_START) || (startCode == SC_SV_END))
{
SwDec_UnFlushBits(pDecContainer,22);
}
/* start code value END_OF_STREAM if nothing was found (resync markers
* disabled -> conceal) */
else if (startCode != END_OF_STREAM)
{
SwDec_UnFlushBits(pDecContainer,32);
}
for (i = first; i < last; i++)
{
if (pDecContainer->Hdrs.dataPartitioned &&
( (pDecContainer->StrmStorage.vpMbNumber +
pDecContainer->StrmStorage.vpNumMbs) == last))
{
pDecContainer->MbDesc[i].errorStatus = TEXTURE_LOST;
}
else
{
pDecContainer->MbDesc[i].errorStatus = EVERYTHING_LOST;
}
}
#endif
// DEBUG(("CONCEALING [%d,%d]\n",first,last-1));
SwDec_ErrorConcealment(pDecContainer,first, last-1);
pDecContainer->StrmStorage.status = STATE_OK;
return(DEC_VOP_RDY);
}
}
/*------------------------------------------------------------------------------
5.4 Function name: SwDec_MemAlloc
Purpose: allocate memories that depend on vop dimensions
Input:
Pointer to decContainer_t structure
Output:
0 if successful, ~0 otherwise
------------------------------------------------------------------------------*/
u32 SwDec_MemAlloc(decContainer_t *pDecContainer)
{
u32 i,j,size;
u32 *pCol, *pRow;
ASSERT(pDecContainer);
ASSERT( (pDecContainer->VopDesc.vopWidth *
pDecContainer->VopDesc.vopHeight) ==
pDecContainer->VopDesc.totalMbInVop );
size = 384 * pDecContainer->VopDesc.totalMbInVop;
pDecContainer->MbDesc = (decMbDesc_t*)MP4SwDecMalloc(
pDecContainer->VopDesc.totalMbInVop * sizeof(decMbDesc_t) );
if (!pDecContainer->StrmStorage.extPicBufAlloc)
{
pDecContainer->pRef = (u8*)MP4SwDecMalloc(size * sizeof(u8));
pDecContainer->pOut = (u8*)MP4SwDecMalloc(size * sizeof(u8));
if ((pDecContainer->pRef == NULL) ||
(pDecContainer->pOut == NULL))
{
SwDec_MemFree(pDecContainer);
return (~0);
}
}
pDecContainer->StrmStorage.col =
(u32*)MP4SwDecMalloc( pDecContainer->VopDesc.totalMbInVop*sizeof(u32) );
pDecContainer->StrmStorage.row =
(u32*)MP4SwDecMalloc( pDecContainer->VopDesc.totalMbInVop*sizeof(u32) );
#ifdef MP4DEC_H263_ONLY
if ( (pDecContainer->MbDesc == NULL) ||
(pDecContainer->StrmStorage.col == NULL) ||
(pDecContainer->StrmStorage.row == NULL) )
{
SwDec_MemFree(pDecContainer);
return(~0);
}
#else
pDecContainer->StrmStorage.horLumAcCoeff = (i32*)MP4SwDecMalloc(
pDecContainer->VopDesc.vopWidth * 14 * sizeof(i32) );
pDecContainer->StrmStorage.horChrAcCoeff = (i32*)MP4SwDecMalloc(
pDecContainer->VopDesc.vopWidth * 14 * sizeof(i32) );
if ( (pDecContainer->MbDesc == NULL) ||
(pDecContainer->StrmStorage.horLumAcCoeff == NULL) ||
(pDecContainer->StrmStorage.horChrAcCoeff == NULL) ||
(pDecContainer->StrmStorage.col == NULL) ||
(pDecContainer->StrmStorage.row == NULL) )
{
SwDec_MemFree(pDecContainer);
return(~0);
}
#endif
/* initialize row and column arrays */
pCol = pDecContainer->StrmStorage.col;
pRow = pDecContainer->StrmStorage.row;
/* initialize column and row tables */
for (i = 0; i < pDecContainer->VopDesc.vopHeight; i++)
{
for (j = 0; j < pDecContainer->VopDesc.vopWidth; j++)
{
*pCol++ = j;
*pRow++ = i;
}
}
return(0);
}
/*------------------------------------------------------------------------------
5.5 Function name: SwDec_MemFree
Purpose: free memories that depend on vop dimensions
Input:
Pointer to decContainer_t structure
Output:
------------------------------------------------------------------------------*/
void SwDec_MemFree(decContainer_t *pDecContainer)
{
MP4SwDecFree(pDecContainer->MbDesc);
if (!pDecContainer->StrmStorage.extPicBufAlloc)
{
MP4SwDecFree(pDecContainer->pRef);
MP4SwDecFree(pDecContainer->pOut);
pDecContainer->pRef = NULL;
pDecContainer->pOut = NULL;
}
MP4SwDecFree(pDecContainer->StrmStorage.col);
MP4SwDecFree(pDecContainer->StrmStorage.row);
#ifndef MP4DEC_H263_ONLY
MP4SwDecFree(pDecContainer->StrmStorage.horLumAcCoeff);
MP4SwDecFree(pDecContainer->StrmStorage.horChrAcCoeff);
pDecContainer->StrmStorage.horLumAcCoeff = NULL;
pDecContainer->StrmStorage.horChrAcCoeff = NULL;
#endif
pDecContainer->MbDesc = NULL;
pDecContainer->StrmStorage.col = NULL;
pDecContainer->StrmStorage.row = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -