h264bsd_vlc.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*------------------------------------------------------------------------------
18
19    Table of contents
20
21     1. Include headers
22     2. External compiler flags
23     3. Module defines
24     4. Local function prototypes
25     5. Functions
26          h264bsdDecodeExpGolombUnsigned
27          h264bsdDecodeExpGolombSigned
28          h264bsdDecodeExpGolombMapped
29          h264bsdDecodeExpGolombTruncated
30
31------------------------------------------------------------------------------*/
32
33/*------------------------------------------------------------------------------
34    1. Include headers
35------------------------------------------------------------------------------*/
36
37#include "h264bsd_vlc.h"
38#include "basetype.h"
39#include "h264bsd_stream.h"
40#include "h264bsd_util.h"
41
42/*------------------------------------------------------------------------------
43    2. External compiler flags
44--------------------------------------------------------------------------------
45
46--------------------------------------------------------------------------------
47    3. Module defines
48------------------------------------------------------------------------------*/
49
50/* definition of special code num, this along with the return value is used
51 * to handle code num in the range [0, 2^32] in the DecodeExpGolombUnsigned
52 * function */
53#define BIG_CODE_NUM 0xFFFFFFFFU
54
55/* Mapping tables for coded_block_pattern, used for decoding of mapped
56 * Exp-Golomb codes */
57static const u8 codedBlockPatternIntra4x4[48] = {
58    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,
59    37,42,44,1,2,4,8,17,18,20,24,6,9,22,25,32,33,34,36,40,38,41};
60
61static const u8 codedBlockPatternInter[48] = {
62    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,
63    39,43,45,46,17,18,20,24,19,21,26,28,23,27,29,30,22,25,38,41};
64
65/*------------------------------------------------------------------------------
66    4. Local function prototypes
67------------------------------------------------------------------------------*/
68
69/*------------------------------------------------------------------------------
70
71   5.1  Function: h264bsdDecodeExpGolombUnsigned
72
73        Functional description:
74            Decode unsigned Exp-Golomb code. This is the same as codeNum used
75            in other Exp-Golomb code mappings. Code num (i.e. the decoded
76            symbol) is determined as
77
78                codeNum = 2^leadingZeros - 1 + GetBits(leadingZeros)
79
80            Normal decoded symbols are in the range [0, 2^32 - 2]. Symbol
81            2^32-1 is indicated by BIG_CODE_NUM with return value HANTRO_OK
82            while symbol 2^32  is indicated by BIG_CODE_NUM with return value
83            HANTRO_NOK.  These two symbols are special cases with code length
84            of 65, i.e.  32 '0' bits, a '1' bit, and either 0 or 1 represented
85            by 32 bits.
86
87            Symbol 2^32 is out of unsigned 32-bit range but is needed for
88            DecodeExpGolombSigned to express value -2^31.
89
90        Inputs:
91            pStrmData       pointer to stream data structure
92
93        Outputs:
94            codeNum         decoded code word is stored here
95
96        Returns:
97            HANTRO_OK       success
98            HANTRO_NOK      failure, no valid code word found, note exception
99                            with BIG_CODE_NUM
100
101------------------------------------------------------------------------------*/
102
103u32 h264bsdDecodeExpGolombUnsigned(strmData_t *pStrmData, u32 *codeNum)
104{
105
106/* Variables */
107
108    u32 bits, numZeros;
109
110/* Code */
111
112    ASSERT(pStrmData);
113    ASSERT(codeNum);
114
115    bits = h264bsdShowBits32(pStrmData);
116
117    /* first bit is 1 -> code length 1 */
118    if (bits >= 0x80000000)
119    {
120        h264bsdFlushBits(pStrmData, 1);
121        *codeNum = 0;
122        return(HANTRO_OK);
123    }
124    /* second bit is 1 -> code length 3 */
125    else if (bits >= 0x40000000)
126    {
127        if (h264bsdFlushBits(pStrmData, 3) == END_OF_STREAM)
128            return(HANTRO_NOK);
129        *codeNum = 1 + ((bits >> 29) & 0x1);
130        return(HANTRO_OK);
131    }
132    /* third bit is 1 -> code length 5 */
133    else if (bits >= 0x20000000)
134    {
135        if (h264bsdFlushBits(pStrmData, 5) == END_OF_STREAM)
136            return(HANTRO_NOK);
137        *codeNum = 3 + ((bits >> 27) & 0x3);
138        return(HANTRO_OK);
139    }
140    /* fourth bit is 1 -> code length 7 */
141    else if (bits >= 0x10000000)
142    {
143        if (h264bsdFlushBits(pStrmData, 7) == END_OF_STREAM)
144            return(HANTRO_NOK);
145        *codeNum = 7 + ((bits >> 25) & 0x7);
146        return(HANTRO_OK);
147    }
148    /* other code lengths */
149    else
150    {
151#ifndef H264DEC_NEON
152        numZeros = 4 + h264bsdCountLeadingZeros(bits, 28);
153#else
154        numZeros = h264bsdCountLeadingZeros(bits);
155#endif
156        /* all 32 bits are zero */
157        if (numZeros == 32)
158        {
159            *codeNum = 0;
160            h264bsdFlushBits(pStrmData,32);
161            bits = h264bsdGetBits(pStrmData, 1);
162            /* check 33rd bit, must be 1 */
163            if (bits == 1)
164            {
165                /* cannot use h264bsdGetBits, limited to 31 bits */
166                bits = h264bsdShowBits32(pStrmData);
167                if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
168                    return(HANTRO_NOK);
169                /* code num 2^32 - 1, needed for unsigned mapping */
170                if (bits == 0)
171                {
172                    *codeNum = BIG_CODE_NUM;
173                    return(HANTRO_OK);
174                }
175                /* code num 2^32, needed for unsigned mapping
176                 * (results in -2^31) */
177                else if (bits == 1)
178                {
179                    *codeNum = BIG_CODE_NUM;
180                    return(HANTRO_NOK);
181                }
182            }
183            /* if more zeros than 32, it is an error */
184            return(HANTRO_NOK);
185        }
186        else
187            h264bsdFlushBits(pStrmData,numZeros+1);
188
189        bits = h264bsdGetBits(pStrmData, numZeros);
190        if (bits == END_OF_STREAM)
191            return(HANTRO_NOK);
192
193        *codeNum = (1 << numZeros) - 1 + bits;
194
195    }
196
197    return(HANTRO_OK);
198
199}
200
201/*------------------------------------------------------------------------------
202
203   5.2  Function: h264bsdDecodeExpGolombSigned
204
205        Functional description:
206            Decode signed Exp-Golomb code. Code num is determined by
207            h264bsdDecodeExpGolombUnsigned and then mapped to signed
208            representation as
209
210                symbol = (-1)^(codeNum+1) * (codeNum+1)/2
211
212            Signed symbols shall be in the range [-2^31, 2^31 - 1]. Symbol
213            -2^31 is obtained when codeNum is 2^32, which cannot be expressed
214            by unsigned 32-bit value. This is signaled as a special case from
215            the h264bsdDecodeExpGolombUnsigned by setting codeNum to
216            BIG_CODE_NUM and returning HANTRO_NOK status.
217
218        Inputs:
219            pStrmData       pointer to stream data structure
220
221        Outputs:
222            value           decoded code word is stored here
223
224        Returns:
225            HANTRO_OK       success
226            HANTRO_NOK      failure, no valid code word found
227
228------------------------------------------------------------------------------*/
229
230u32 h264bsdDecodeExpGolombSigned(strmData_t *pStrmData, i32 *value)
231{
232
233/* Variables */
234
235    u32 status, codeNum = 0;
236
237/* Code */
238
239    ASSERT(pStrmData);
240    ASSERT(value);
241
242    status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
243
244    if (codeNum == BIG_CODE_NUM)
245    {
246        /* BIG_CODE_NUM and HANTRO_OK status means codeNum 2^32-1 which would
247         * result in signed integer valued 2^31 (i.e. out of 32-bit signed
248         * integer range) */
249        if (status == HANTRO_OK)
250            return(HANTRO_NOK);
251        /* BIG_CODE_NUM and HANTRO_NOK status means codeNum 2^32 which results
252         * in signed integer valued -2^31 */
253        else
254        {
255            *value = (i32)(2147483648U);
256            return (HANTRO_OK);
257        }
258    }
259    else if (status == HANTRO_OK)
260    {
261        /* (-1)^(codeNum+1) results in positive sign if codeNum is odd,
262         * negative when it is even. (codeNum+1)/2 is obtained as
263         * (codeNum+1)>>1 when value is positive and as (-codeNum)>>1 for
264         * negative value */
265        /*lint -e702 */
266        *value = (codeNum & 0x1) ? (i32)((codeNum + 1) >> 1) :
267                                  -(i32)((codeNum + 1) >> 1);
268        /*lint +e702 */
269        return(HANTRO_OK);
270    }
271
272    return(HANTRO_NOK);
273
274}
275
276/*------------------------------------------------------------------------------
277
278   5.3  Function: h264bsdDecodeExpGolombMapped
279
280        Functional description:
281            Decode mapped Exp-Golomb code. Code num is determined by
282            h264bsdDecodeExpGolombUnsigned and then mapped to codedBlockPattern
283            either for intra or inter macroblock. The mapping is implemented by
284            look-up tables defined in the beginning of the file.
285
286        Inputs:
287            pStrmData       pointer to stream data structure
288            isIntra         flag to indicate if intra or inter mapping is to
289                            be used
290
291        Outputs:
292            value           decoded code word is stored here
293
294        Returns:
295            HANTRO_OK       success
296            HANTRO_NOK      failure, no valid code word found
297
298------------------------------------------------------------------------------*/
299
300u32 h264bsdDecodeExpGolombMapped(strmData_t *pStrmData, u32 *value,
301    u32 isIntra)
302{
303
304/* Variables */
305
306    u32 status, codeNum;
307
308/* Code */
309
310    ASSERT(pStrmData);
311    ASSERT(value);
312
313    status = h264bsdDecodeExpGolombUnsigned(pStrmData, &codeNum);
314
315    if (status != HANTRO_OK)
316        return (HANTRO_NOK);
317    else
318    {
319        /* range of valid codeNums [0,47] */
320        if (codeNum > 47)
321            return (HANTRO_NOK);
322        if (isIntra)
323            *value = codedBlockPatternIntra4x4[codeNum];
324        else
325            *value = codedBlockPatternInter[codeNum];
326        return(HANTRO_OK);
327    }
328
329}
330
331/*------------------------------------------------------------------------------
332
333   5.4  Function: h264bsdDecodeExpGolombTruncated
334
335        Functional description:
336            Decode truncated Exp-Golomb code. greaterThanOne flag indicates
337            the range of the symbol to be decoded as follows:
338                FALSE   ->  [0,1]
339                TRUE    ->  [0,2^32-1]
340
341            If flag is false the decoding is performed by reading one bit
342            from the stream with h264bsdGetBits and mapping this to decoded
343            symbol as
344                symbol = bit ? 0 : 1
345
346            Otherwise, i.e. when flag is TRUE, code num is determined by
347            h264bsdDecodeExpGolombUnsigned and this is used as the decoded
348            symbol.
349
350        Inputs:
351            pStrmData       pointer to stream data structure
352            greaterThanOne  flag to indicate if range is wider than [0,1]
353
354        Outputs:
355            value           decoded code word is stored here
356
357        Returns:
358            HANTRO_OK       success
359            HANTRO_NOK      failure, no valid code word found
360
361------------------------------------------------------------------------------*/
362
363u32 h264bsdDecodeExpGolombTruncated(
364  strmData_t *pStrmData,
365  u32 *value,
366  u32 greaterThanOne)
367{
368
369/* Variables */
370
371/* Code */
372
373    ASSERT(pStrmData);
374    ASSERT(value);
375
376    if (greaterThanOne)
377    {
378        return(h264bsdDecodeExpGolombUnsigned(pStrmData, value));
379    }
380    else
381    {
382        *value = h264bsdGetBits(pStrmData,1);
383        if (*value == END_OF_STREAM)
384            return (HANTRO_NOK);
385        *value ^= 0x1;
386    }
387
388    return (HANTRO_OK);
389
390}
391
392