📄 swdec_utils.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 utilities
--
-------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
5.1 SwDec_GetBits
5.2 SwDec_ShowBits
5.3 SwDec_ShowBitsAligned
5.4 SwDec_FlushBits
5.5 SwDec_GetStuffing
5.6 SwDec_FindSync
5.7 SwDec_GetStartCode
5.8 SwDec_NumBits
5.9 SwDec_UnFlushBits
5.10 SwDec_CheckStuffing
5.11 SwDec_ShowBits32
5.12 SwDec_GetOneBit
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "SwDec_Utils.h"
/*------------------------------------------------------------------------------
2. External identifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
enum {
SV_MARKER_MASK = 0x1FFFF,
SV_END_MASK = 0x3FFFFF,
SECOND_BYTE_ZERO_MASK = 0x00FF0000
};
#ifndef MP4DEC_H263_ONLY
/* to check first 23 bits */
#define START_CODE_MASK 0xFFFFFE00
/* to check first 16 bits */
#define RESYNC_MASK 0xFFFF0000
/*------------------------------------------------------------------------------
4. Module indentifiers
------------------------------------------------------------------------------*/
static const u32 stuffingTable[8] = {0x0,0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F};
/* table containing start code id for each possible start code suffix. Start
* code suffixes that are either reserved or non-applicable have been marked
* with 0 */
static const u32 startCodeTable[256] =
{
SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,
SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,
SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,
SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,
SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,SC_VO_START,
SC_VO_START,SC_VO_START,
SC_VOL_START,SC_VOL_START,SC_VOL_START,SC_VOL_START,SC_VOL_START,
SC_VOL_START,SC_VOL_START,SC_VOL_START,SC_VOL_START,SC_VOL_START,
SC_VOL_START,SC_VOL_START,SC_VOL_START,SC_VOL_START,SC_VOL_START,
SC_VOL_START,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
SC_VOS_START,SC_VOS_END,0,SC_GVOP_START,0,SC_VISO_START, SC_VOP_START,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0
};
#endif
/*------------------------------------------------------------------------------
5.1 Function name: SwDec_GetBits
Purpose: read and remove bits from mpeg-4 input stream
Input:
Pointer to decContainer_t structure
Number of bits to read [0,31]
Output:
u32 containing bits read from stream. Value END_OF_STREAM
reserved to indicate failure.
------------------------------------------------------------------------------*/
u32 SwDec_GetBits(decContainer_t *pDecContainer, u32 numBits)
{
u32 out;
ASSERT(pDecContainer);
ASSERT(numBits < 32);
out = SwDec_ShowBits(pDecContainer, numBits);
if (SwDec_FlushBits(pDecContainer, numBits) == HANTRO_OK)
{
return(out);
}
else
{
return(END_OF_STREAM);
}
}
/*------------------------------------------------------------------------------
5.2 Function name: SwDec_ShowBits
Purpose: read bits from mpeg-4 input stream. Bits are located right
aligned in the 32-bit output word. In case stream ends,
function fills the word with zeros. For example, numBits = 18 and
there are 7 bits left in the stream buffer -> return
00000000000000xxxxxxx00000000000,
where 'x's represent actual bits read from buffer.
Input:
Pointer to decContainer_t structure
Number of bits to read [0,32]
Output:
u32 containing bits read from stream
------------------------------------------------------------------------------*/
u32 SwDec_ShowBits(decContainer_t *pDecContainer, u32 numBits)
{
u32 i;
i32 bits, shift;
u32 out;
u8 *pStrm;
ASSERT(pDecContainer);
ASSERT(pDecContainer->StrmDesc.pStrmCurrPos);
ASSERT(pDecContainer->StrmDesc.bitPosInWord < 8);
ASSERT(pDecContainer->StrmDesc.bitPosInWord ==
(pDecContainer->StrmDesc.strmBuffReadBits & 0x7));
ASSERT(pDecContainer->StrmDesc.strmBuffSize);
ASSERT(numBits <= 32);
pStrm = pDecContainer->StrmDesc.pStrmCurrPos;
/* bits left in the buffer */
bits = (i32)pDecContainer->StrmDesc.strmBuffSize*8 -
(i32)pDecContainer->StrmDesc.strmBuffReadBits;
if (!numBits || !bits)
{
return(0);
}
/* at least 32-bits in the buffer -> get 32 bits and drop extra bits out */
if (bits >= 32)
{
out = ((u32)pStrm[0] << 24) | ((u32)pStrm[1] << 16) |
((u32)pStrm[2] << 8) | ((u32)pStrm[3]);
if (pDecContainer->StrmDesc.bitPosInWord)
{
out <<= pDecContainer->StrmDesc.bitPosInWord;
out |=
(u32)pStrm[4]>>(8-pDecContainer->StrmDesc.bitPosInWord);
}
out >>= (32 - numBits);
}
else
{
shift = 24 + (i32)pDecContainer->StrmDesc.bitPosInWord;
out = (u32)pStrm[0] << shift;
bits -= 8 - (i32)pDecContainer->StrmDesc.bitPosInWord;
i = 1;
while (bits > 0)
{
shift -= 8;
out |= (u32)pStrm[i] << shift;
bits -= 8;
i++;
}
out >>= (32 - numBits);
}
return(out);
}
/*------------------------------------------------------------------------------
5.3 Function name: SwDec_ShowBitsAligned
Purpose: read bits from mpeg-4 input stream at byte aligned position
given as parameter (offset from current stream position).
Input:
Pointer to decContainer_t structure
Number of bits to read [1,32]
Byte offset from current stream position
Output:
u32 containing bits read from stream
------------------------------------------------------------------------------*/
u32 SwDec_ShowBitsAligned(decContainer_t *pDecContainer, u32 numBits,
u32 byteOffset)
{
u32 i;
u32 out;
u32 bytes,shift;
u8 *pStrm;
ASSERT(pDecContainer);
ASSERT(pDecContainer->StrmDesc.pStrmCurrPos);
ASSERT(pDecContainer->StrmDesc.strmBuffSize);
ASSERT(numBits);
ASSERT(numBits <= 32);
out = 0;
pStrm = pDecContainer->StrmDesc.pStrmCurrPos + byteOffset;
/* at least four bytes available starting byteOffset bytes ahead */
if ( (pDecContainer->StrmDesc.strmBuffSize >= (4+byteOffset)) &&
((pDecContainer->StrmDesc.strmBuffReadBits>>3) <=
(pDecContainer->StrmDesc.strmBuffSize - byteOffset - 4)) )
{
out = ((u32)pStrm[0] << 24) | ((u32)pStrm[1] << 16) |
((u32)pStrm[2] << 8) | ((u32)pStrm[3]);
out >>= (32 - numBits);
}
else
{
bytes = pDecContainer->StrmDesc.strmBuffSize -
(pDecContainer->StrmDesc.strmBuffReadBits >> 3);
if (bytes > byteOffset)
{
bytes -= byteOffset;
}
else
{
bytes = 0;
}
shift = 24;
i = 0;
while (bytes)
{
out |= (u32)pStrm[i] << shift;
i++;
shift -= 8;
bytes--;
}
out >>= (32 - numBits);
}
return(out);
}
/*------------------------------------------------------------------------------
5.4 Function name: SwDec_FlushBits
Purpose: removes bits from mpeg-4 input stream
Input:
Pointer to decContainer_t structure
Number of bits to remove [0,2^32)
Output:
HANTRO_OK if operation was successful
END_OF_STREAM if stream buffer run empty
------------------------------------------------------------------------------*/
u32 SwDec_FlushBits(decContainer_t *pDecContainer, u32 numBits)
{
u32 tmp;
ASSERT(pDecContainer);
ASSERT(pDecContainer->StrmDesc.pStrmBuffStart);
ASSERT(pDecContainer->StrmDesc.pStrmCurrPos);
ASSERT(pDecContainer->StrmDesc.bitPosInWord < 8);
ASSERT(pDecContainer->StrmDesc.bitPosInWord ==
(pDecContainer->StrmDesc.strmBuffReadBits & 0x7));
if ( (pDecContainer->StrmDesc.strmBuffReadBits + numBits) >
(8*pDecContainer->StrmDesc.strmBuffSize) )
{
pDecContainer->StrmDesc.strmBuffReadBits =
8 * pDecContainer->StrmDesc.strmBuffSize;
pDecContainer->StrmDesc.bitPosInWord = 0;
pDecContainer->StrmDesc.pStrmCurrPos =
pDecContainer->StrmDesc.pStrmBuffStart +
pDecContainer->StrmDesc.strmBuffSize;
return(END_OF_STREAM);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -