You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
393 lines
12 KiB
393 lines
12 KiB
/*
|
|
* Copyright (C) 2009 The Android Open Source Project
|
|
* Modified for use by h264bsd standalone library
|
|
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Table of contents
|
|
|
|
1. Include headers
|
|
2. External compiler flags
|
|
3. Module defines
|
|
4. Local function prototypes
|
|
5. Functions
|
|
h264bsdDecodeExpGolombUnsigned
|
|
h264bsdDecodeExpGolombSigned
|
|
h264bsdDecodeExpGolombMapped
|
|
h264bsdDecodeExpGolombTruncated
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
/*------------------------------------------------------------------------------
|
|
1. Include headers
|
|
------------------------------------------------------------------------------*/
|
|
|
|
#include "h264bsd_vlc.h"
|
|
#include "basetype.h"
|
|
#include "h264bsd_stream.h"
|
|
#include "h264bsd_util.h"
|
|
|
|
/*------------------------------------------------------------------------------
|
|
2. External compiler flags
|
|
--------------------------------------------------------------------------------
|
|
|
|
--------------------------------------------------------------------------------
|
|
3. Module defines
|
|
------------------------------------------------------------------------------*/
|
|
|
|
/* definition of special code num, this along with the return value is used
|
|
* to handle code num in the range [0, 2^32] in the DecodeExpGolombUnsigned
|
|
* function */
|
|
#define BIG_CODE_NUM 0xFFFFFFFFU
|
|
|
|
/* Mapping tables for coded_block_pattern, used for decoding of mapped
|
|
* Exp-Golomb codes */
|
|
static const u8 codedBlockPatternIntra4x4[48] = {
|
|
47,31,15,0,23,27,29,30,7,11,13,14,39,43,45,46,16,3,5,10,12,19,21,26,28,35,
|
|
37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41};
|
|
|
|
static const u8 codedBlockPatternInter[48] = {
|
|
0,16,1,2,4,8,32,3,5,10,12,15,47,7,11,13,14,6,9,31,35,37,42,44,33,34,36,40,
|
|
39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41};
|
|
|
|
/*------------------------------------------------------------------------------
|
|
4. Local function prototypes
|
|
------------------------------------------------------------------------------*/
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
5.1 Function: h264bsdDecodeExpGolombUnsigned
|
|
|
|
Functional description:
|
|
Decode unsigned Exp-Golomb code. This is the same as codeNum used
|
|
in other Exp-Golomb code mappings. Code num (i.e. the decoded
|
|
symbol) is determined as
|
|
|
|
codeNum = 2^leadingZeros - 1 + GetBits(leadingZeros)
|
|
|
|
Normal decoded symbols are in the range [0, 2^32 - 2]. Symbol
|
|
2^32-1 is indicated by BIG_CODE_NUM with return value HANTRO_OK
|
|
while symbol 2^32 is indicated by BIG_CODE_NUM with return value
|
|
HANTRO_NOK. These two symbols are special cases with code length
|
|
of 65, i.e. 32 '0' bits, a '1' bit, and either 0 or 1 represented
|
|
by 32 bits.
|
|
|
|
Symbol 2^32 is out of unsigned 32-bit range but is needed for
|
|
DecodeExpGolombSigned to express value -2^31.
|
|
|
|
Inputs:
|
|
pStrmData pointer to stream data structure
|
|
|
|
Outputs:
|
|
codeNum decoded code word is stored here
|
|
|
|
Returns:
|
|
HANTRO_OK success
|
|
HANTRO_NOK failure, no valid code word found, note exception
|
|
with BIG_CODE_NUM
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
u32 h264bsdDecodeExpGolombUnsigned(strmData_t *pStrmData, u32 *codeNum)
|
|
{
|
|
|
|
/* Variables */
|
|
|
|
u32 bits, numZeros;
|
|
|
|
/* Code */
|
|
|
|
ASSERT(pStrmData);
|
|
ASSERT(codeNum);
|
|
|
|
bits = h264bsdShowBits32(pStrmData);
|
|
|
|
/* first bit is 1 -> code length 1 */
|
|
if (bits >= 0x80000000)
|
|
{
|
|
h264bsdFlushBits(pStrmData, 1);
|
|
*codeNum = 0;
|
|
return(HANTRO_OK);
|
|
}
|
|
/* second bit is 1 -> code length 3 */
|
|
else if (bits >= 0x40000000)
|
|
{
|
|
if (h264bsdFlushBits(pStrmData, 3) == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
*codeNum = 1 + ((bits >> 29) & 0x1);
|
|
return(HANTRO_OK);
|
|
}
|
|
/* third bit is 1 -> code length 5 */
|
|
else if (bits >= 0x20000000)
|
|
{
|
|
if (h264bsdFlushBits(pStrmData, 5) == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
*codeNum = 3 + ((bits >> 27) & 0x3);
|
|
return(HANTRO_OK);
|
|
}
|
|
/* fourth bit is 1 -> code length 7 */
|
|
else if (bits >= 0x10000000)
|
|
{
|
|
if (h264bsdFlushBits(pStrmData, 7) == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
*codeNum = 7 + ((bits >> 25) & 0x7);
|
|
return(HANTRO_OK);
|
|
}
|
|
/* other code lengths */
|
|
else
|
|
{
|
|
#ifndef H264DEC_NEON
|
|
numZeros = 4 + h264bsdCountLeadingZeros(bits, 28);
|
|
#else
|
|
numZeros = h264bsdCountLeadingZeros(bits);
|
|
#endif
|
|
/* all 32 bits are zero */
|
|
if (numZeros == 32)
|
|
{
|
|
*codeNum = 0;
|
|
h264bsdFlushBits(pStrmData,32);
|
|
bits = h264bsdGetBits(pStrmData, 1);
|
|
/* check 33rd bit, must be 1 */
|
|
if (bits == 1)
|
|
{
|
|
/* cannot use h264bsdGetBits, limited to 31 bits */
|
|
bits = h264bsdShowBits32(pStrmData);
|
|
if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
/* code num 2^32 - 1, needed for unsigned mapping */
|
|
if (bits == 0)
|
|
{
|
|
*codeNum = BIG_CODE_NUM;
|
|
return(HANTRO_OK);
|
|
}
|
|
/* code num 2^32, needed for unsigned mapping
|
|
* (results in -2^31) */
|
|
else if (bits == 1)
|
|
{
|
|
*codeNum = BIG_CODE_NUM;
|
|
return(HANTRO_NOK);
|
|
}
|
|
}
|
|
/* if more zeros than 32, it is an error */
|
|
return(HANTRO_NOK);
|
|
}
|
|
else
|
|
h264bsdFlushBits(pStrmData,numZeros+1);
|
|
|
|
bits = h264bsdGetBits(pStrmData, numZeros);
|
|
if (bits == END_OF_STREAM)
|
|
return(HANTRO_NOK);
|
|
|
|
*codeNum = (1 << numZeros) - 1 + bits;
|
|
|
|
}
|
|
|
|
return(HANTRO_OK);
|
|
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
5.2 Function: h264bsdDecodeExpGolombSigned
|
|
|
|
Functional description:
|
|
Decode signed Exp-Golomb code. Code num is determined by
|
|
h264bsdDecodeExpGolombUnsigned and then mapped to signed
|
|
representation as
|
|
|
|
symbol = (-1)^(codeNum+1) * (codeNum+1)/2
|
|
|
|
Signed symbols shall be in the range [-2^31, 2^31 - 1]. Symbol
|
|
-2^31 is obtained when codeNum is 2^32, which cannot be expressed
|
|
by unsigned 32-bit value. This is signaled as a special case from
|
|
the h264bsdDecodeExpGolombUnsigned by setting codeNum to
|
|
BIG_CODE_NUM and returning HANTRO_NOK status.
|
|
|
|
Inputs:
|
|
pStrmData pointer to stream data structure
|
|
|
|
Outputs:
|
|
value decoded code word is stored here
|
|
|
|
Returns:
|
|
HANTRO_OK success
|
|
HANTRO_NOK failure, no valid code word found
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
u32 h264bsdDecodeExpGolombSigned(strmData_t *pStrmData, i32 *value)
|
|
{
|
|
|
|
/* Variables */
|
|
|
|
u32 status, codeNum = 0;
|
|
|
|
/* Code */
|
|
|
|
ASSERT(pStrmData);
|
|
ASSERT(value);
|
|
|
|
status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
|
|
|
|
if (codeNum == BIG_CODE_NUM)
|
|
{
|
|
/* BIG_CODE_NUM and HANTRO_OK status means codeNum 2^32-1 which would
|
|
* result in signed integer valued 2^31 (i.e. out of 32-bit signed
|
|
* integer range) */
|
|
if (status == HANTRO_OK)
|
|
return(HANTRO_NOK);
|
|
/* BIG_CODE_NUM and HANTRO_NOK status means codeNum 2^32 which results
|
|
* in signed integer valued -2^31 */
|
|
else
|
|
{
|
|
*value = (i32)(2147483648U);
|
|
return (HANTRO_OK);
|
|
}
|
|
}
|
|
else if (status == HANTRO_OK)
|
|
{
|
|
/* (-1)^(codeNum+1) results in positive sign if codeNum is odd,
|
|
* negative when it is even. (codeNum+1)/2 is obtained as
|
|
* (codeNum+1)>>1 when value is positive and as (-codeNum)>>1 for
|
|
* negative value */
|
|
/*lint -e702 */
|
|
*value = (codeNum & 0x1) ? (i32)((codeNum + 1) >> 1) :
|
|
-(i32)((codeNum + 1) >> 1);
|
|
/*lint +e702 */
|
|
return(HANTRO_OK);
|
|
}
|
|
|
|
return(HANTRO_NOK);
|
|
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
5.3 Function: h264bsdDecodeExpGolombMapped
|
|
|
|
Functional description:
|
|
Decode mapped Exp-Golomb code. Code num is determined by
|
|
h264bsdDecodeExpGolombUnsigned and then mapped to codedBlockPattern
|
|
either for intra or inter macroblock. The mapping is implemented by
|
|
look-up tables defined in the beginning of the file.
|
|
|
|
Inputs:
|
|
pStrmData pointer to stream data structure
|
|
isIntra flag to indicate if intra or inter mapping is to
|
|
be used
|
|
|
|
Outputs:
|
|
value decoded code word is stored here
|
|
|
|
Returns:
|
|
HANTRO_OK success
|
|
HANTRO_NOK failure, no valid code word found
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
u32 h264bsdDecodeExpGolombMapped(strmData_t *pStrmData, u32 *value,
|
|
u32 isIntra)
|
|
{
|
|
|
|
/* Variables */
|
|
|
|
u32 status, codeNum;
|
|
|
|
/* Code */
|
|
|
|
ASSERT(pStrmData);
|
|
ASSERT(value);
|
|
|
|
status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
|
|
|
|
if (status != HANTRO_OK)
|
|
return (HANTRO_NOK);
|
|
else
|
|
{
|
|
/* range of valid codeNums [0,47] */
|
|
if (codeNum > 47)
|
|
return (HANTRO_NOK);
|
|
if (isIntra)
|
|
*value = codedBlockPatternIntra4x4[codeNum];
|
|
else
|
|
*value = codedBlockPatternInter[codeNum];
|
|
return(HANTRO_OK);
|
|
}
|
|
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
|
|
5.4 Function: h264bsdDecodeExpGolombTruncated
|
|
|
|
Functional description:
|
|
Decode truncated Exp-Golomb code. greaterThanOne flag indicates
|
|
the range of the symbol to be decoded as follows:
|
|
FALSE -> [0,1]
|
|
TRUE -> [0,2^32-1]
|
|
|
|
If flag is false the decoding is performed by reading one bit
|
|
from the stream with h264bsdGetBits and mapping this to decoded
|
|
symbol as
|
|
symbol = bit ? 0 : 1
|
|
|
|
Otherwise, i.e. when flag is TRUE, code num is determined by
|
|
h264bsdDecodeExpGolombUnsigned and this is used as the decoded
|
|
symbol.
|
|
|
|
Inputs:
|
|
pStrmData pointer to stream data structure
|
|
greaterThanOne flag to indicate if range is wider than [0,1]
|
|
|
|
Outputs:
|
|
value decoded code word is stored here
|
|
|
|
Returns:
|
|
HANTRO_OK success
|
|
HANTRO_NOK failure, no valid code word found
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
u32 h264bsdDecodeExpGolombTruncated(
|
|
strmData_t *pStrmData,
|
|
u32 *value,
|
|
u32 greaterThanOne)
|
|
{
|
|
|
|
/* Variables */
|
|
|
|
/* Code */
|
|
|
|
ASSERT(pStrmData);
|
|
ASSERT(value);
|
|
|
|
if (greaterThanOne)
|
|
{
|
|
return(h264bsdDecodeExpGolombUnsigned(pStrmData, value));
|
|
}
|
|
else
|
|
{
|
|
*value = h264bsdGetBits(pStrmData,1);
|
|
if (*value == END_OF_STREAM)
|
|
return (HANTRO_NOK);
|
|
*value ^= 0x1;
|
|
}
|
|
|
|
return (HANTRO_OK);
|
|
|
|
}
|
|
|
|
|