/H264Dec/source/h264bsd_vlc.c
http://github.com/mbebenita/Broadway · C · 391 lines · 147 code · 49 blank · 195 comment · 40 complexity · 825bbc6bd0eeb2967503610a1a1d7408 MD5 · raw file
- /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * 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);
- }