📄 swdec_utils.c
字号:
}
else
{
pDecContainer->StrmDesc.strmBuffReadBits += numBits;
tmp = pDecContainer->StrmDesc.bitPosInWord + numBits;
pDecContainer->StrmDesc.pStrmCurrPos += tmp >> 3;
pDecContainer->StrmDesc.bitPosInWord = tmp & 0x7;
return(HANTRO_OK);
}
}
/*------------------------------------------------------------------------------
5.5 Function name: SwDec_GetStuffing
Purpose: removes mpeg-4 stuffing from input stream
Input:
Pointer to decContainer_t structure
Output:
HANTRO_OK if operation was successful
HANTRO_NOK if error in stuffing (i.e. not 0111...)
END_OF_STREAM
------------------------------------------------------------------------------*/
#ifndef MP4DEC_H263_ONLY
u32 SwDec_GetStuffing(decContainer_t *pDecContainer)
{
u32 stuffing;
u32 stuffingLength;
ASSERT(pDecContainer);
ASSERT(pDecContainer->StrmDesc.bitPosInWord < 8);
stuffingLength = 8 - pDecContainer->StrmDesc.bitPosInWord;
stuffing = SwDec_GetBits(pDecContainer, stuffingLength);
CHECK_END_OF_STREAM(stuffing);
if (stuffing != stuffingTable[stuffingLength - 1])
return(HANTRO_NOK);
else
return(HANTRO_OK);
}
#endif
/*------------------------------------------------------------------------------
5.6 Function name: SwDec_FindSync
Purpose: searches next syncronization point in mpeg-4 stream. Takes
into account StrmDecStorage.status as follows:
state not ready -> only accept SC_VOS_START, SC_VO_START,
SC_VISO_START and SC_VOL_START codes (to get initial headers
for decoding). Also accept SC_SV_START as short video vops
provide all information needed in decoding.
In addition to above mentioned condition short video markers are
accepted only in case shortVideo in DecStrmStrorage is TRUE.
Function starts searching sync four bytes back from current stream
position. However, if this would result starting before last found sync,
search is started one byte ahead fo last found sync. Search is always
started at byte aligned position.
Input:
Pointer to decContainer_t structure
Output:
Start code value in case one was found, END_OF_STREAM if stream
end was encountered before sync was found. SC_ERROR if start code
prefix correct but suffix does not match or more than 23
successive zeros found.
------------------------------------------------------------------------------*/
u32 SwDec_FindSync(decContainer_t *pDecContainer)
{
u32 i,tmp;
u32 code;
u32 status;
u32 codeLength;
#ifndef MP4DEC_H263_ONLY
u32 mask;
u32 markerLength;
#endif
ASSERT(pDecContainer);
ASSERT(pDecContainer->StrmDesc.pStrmCurrPos);
ASSERT(pDecContainer->StrmStorage.pLastSync);
ASSERT(pDecContainer->StrmStorage.pLastSync <=
pDecContainer->StrmDesc.pStrmCurrPos);
ASSERT(pDecContainer->StrmDesc.bitPosInWord < 8);
#ifndef MP4DEC_H263_ONLY
if (pDecContainer->StrmStorage.validVopHeader)
{
markerLength = pDecContainer->StrmStorage.resyncMarkerLength;
}
else
{
markerLength = 0;
}
#endif
/* go back 4 bytes and to beginning of byte (or to beginning of stream)
* before starting search */
if (pDecContainer->StrmDesc.strmBuffReadBits > 39)
{
pDecContainer->StrmDesc.strmBuffReadBits -= 32;
/* drop 3 lsbs (i.e. make read bits next lowest multiple of byte) */
pDecContainer->StrmDesc.strmBuffReadBits &= 0xFFFFFFF8;
pDecContainer->StrmDesc.bitPosInWord = 0;
pDecContainer->StrmDesc.pStrmCurrPos -= 4;
}
else
{
pDecContainer->StrmDesc.strmBuffReadBits = 0;
pDecContainer->StrmDesc.bitPosInWord = 0;
pDecContainer->StrmDesc.pStrmCurrPos =
pDecContainer->StrmDesc.pStrmBuffStart;
}
/* beyond last sync point -> go to last sync point */
if (pDecContainer->StrmDesc.pStrmCurrPos <
pDecContainer->StrmStorage.pLastSync)
{
pDecContainer->StrmDesc.pStrmCurrPos =
pDecContainer->StrmStorage.pLastSync;
pDecContainer->StrmDesc.strmBuffReadBits = 8 *
(u32)(pDecContainer->StrmDesc.pStrmCurrPos -
pDecContainer->StrmDesc.pStrmBuffStart);
}
code = 0;
codeLength = 0;
#ifdef MP4DEC_H263_ONLY
while (!code)
{
tmp = SwDec_ShowBits(pDecContainer, 32);
if ( tmp && !(tmp & SECOND_BYTE_ZERO_MASK) )
{
if (!pDecContainer->StrmStorage.strmDecReady)
{
if ((tmp >> 10) == SC_SV_START)
{
code = SC_SV_START;
codeLength = 22;
}
}
else
{
if ((tmp>>10) == SC_SV_START)
{
code = SC_SV_START;
codeLength = 22;
}
/* check short video resync and end code at each possible bit
* position [0,7] */
else
{
for (i = 15; i >= 8; i--)
{
if ( ((tmp>>i) & SV_MARKER_MASK) == SC_RESYNC )
{
/* Not short video end marker */
if ( ((tmp>>(i-5)) & SV_END_MASK) != SC_SV_END )
{
code = SC_RESYNC;
codeLength = 32-i;
break;
}
}
}
}
}
}
#else
while (!code)
{
tmp = SwDec_ShowBits(pDecContainer, 32);
/* search if two first bytes equal to zero (all start codes have at
* least 16 zeros in the beginning) or short video case (not
* necessarily byte aligned start codes) */
if ( tmp && (!(tmp & RESYNC_MASK) ||
pDecContainer->StrmStorage.shortVideo) )
{
if (!pDecContainer->StrmStorage.strmDecReady)
{
if ( ((tmp&0xFFFFFFE0) == SC_VO_START) ||
((tmp&0xFFFFFFF0) == SC_VOL_START) ||
(tmp == SC_VISO_START) ||
(tmp == SC_VOS_START) )
{
code = startCodeTable[tmp&0xFF];
codeLength = 32;
}
else if ((tmp >> 10) == SC_SV_START)
{
code = SC_SV_START;
codeLength = 22;
}
}
else if (!pDecContainer->StrmStorage.shortVideo)
{
if ( ((tmp>>8) == 0x01) && startCodeTable[tmp&0xFF] )
{
code = startCodeTable[tmp&0xFF];
codeLength = 32;
}
/* either start code prefix or 24 zeros -> start code error */
else if ( (tmp & 0xFFFFFE00) == 0 )
{
/* consider VOP start code lost */
codeLength = 32;
pDecContainer->StrmStorage.startCodeLoss = 1;
}
else
{
/* resync marker length known? */
if (markerLength)
{
if ((tmp>>(32-markerLength)) == 0x01)
{
code = SC_RESYNC;
codeLength = markerLength;
}
}
/* try all possible lengths [17,23] if third byte contains
* at least one '1' */
else
{
markerLength = 17;
mask = 0x8000;
while ( !(tmp & mask) )
{
mask >>= 1;
markerLength++;
}
code = SC_RESYNC;
codeLength = markerLength;
pDecContainer->StrmStorage.resyncMarkerLength =
markerLength;
}
}
}
else /* short video */
{
if ( ((tmp&0xFFFFFFE0) == SC_VO_START) ||
(tmp == SC_VOS_START) ||
(tmp == SC_VOS_END) ||
(tmp == SC_VISO_START) )
{
code = startCodeTable[tmp&0xFF];
codeLength = 32;
}
else if ((tmp>>10) == SC_SV_START)
{
code = SC_SV_START;
codeLength = 22;
}
/* check short video resync and end code at each possible bit
* position [0,7] if second byte of tmp is 0 */
else if ( !(tmp & SECOND_BYTE_ZERO_MASK) )
{
for (i = 15; i >= 8; i--)
{
if ( ((tmp>>i) & SV_MARKER_MASK) == SC_RESYNC )
{
/* Not short video end marker */
if ( ((tmp>>(i-5)) & SV_END_MASK) != SC_SV_END )
{
code = SC_RESYNC;
codeLength = 32-i;
break;
}
}
}
}
}
}
#endif
if (codeLength)
{
status = SwDec_FlushBits(pDecContainer, codeLength);
pDecContainer->StrmStorage.pLastSync =
pDecContainer->StrmDesc.pStrmCurrPos;
codeLength = 0;
}
else
{
status = SwDec_FlushBits(pDecContainer, 8);
}
if (status == END_OF_STREAM) return(END_OF_STREAM);
}
return(code);
}
/*------------------------------------------------------------------------------
5.7 Function name: SwDec_GetStartCode
Purpose: tries to read next start code from input stream. Start code
is not searched but it is assumed that if there is start code it is at
current stream position.
Input:
Pointer to decContainer_t structure
Output:
Start code value if found, SC_NOT_FOUND if no start code detected
and SC_ERROR if start code prefix correct but suffix does not match
or more than 23 successive zeros found. END_OF_STREAM if stream
ended.
------------------------------------------------------------------------------*/
u32 SwDec_GetStartCode(decContainer_t *pDecContainer)
{
u32 tmp;
u32 codeLength = 0;
u32 startCode = SC_NOT_FOUND;
#ifndef MP4DEC_H263_ONLY
u32 markerLength;
#endif
ASSERT(pDecContainer);
ASSERT(pDecContainer->StrmDesc.pStrmCurrPos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -