ref: bdf6173d6dfff6ac1627fd61bd3e0aff6a6193ec
dir: /src/h264bsd_vlc.c/
/* * 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); }