| /* |
| * 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); |
| |
| } |
| |