h264bsd_pic_param_set.c revision 21e525fdcc234c22d843a8bf1a4ec35c4b376314
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          h264bsdDecodePicParamSet
27
28------------------------------------------------------------------------------*/
29
30/*------------------------------------------------------------------------------
31    1. Include headers
32------------------------------------------------------------------------------*/
33
34#include "h264bsd_pic_param_set.h"
35#include "h264bsd_util.h"
36#include "h264bsd_vlc.h"
37#include "h264bsd_cfg.h"
38
39/*------------------------------------------------------------------------------
40    2. External compiler flags
41--------------------------------------------------------------------------------
42
43--------------------------------------------------------------------------------
44    3. Module defines
45------------------------------------------------------------------------------*/
46
47/* lookup table for ceil(log2(numSliceGroups)), i.e. number of bits needed to
48 * represent range [0, numSliceGroups)
49 *
50 * NOTE: if MAX_NUM_SLICE_GROUPS is higher than 8 this table has to be resized
51 * accordingly */
52static const u32 CeilLog2NumSliceGroups[8] = {1, 1, 2, 2, 3, 3, 3, 3};
53
54/*------------------------------------------------------------------------------
55    4. Local function prototypes
56------------------------------------------------------------------------------*/
57
58/*------------------------------------------------------------------------------
59
60    Function name: h264bsdDecodePicParamSet
61
62        Functional description:
63            Decode picture parameter set information from the stream.
64
65            Function allocates memory for
66                - run lengths if slice group map type is 0
67                - top-left and bottom-right arrays if map type is 2
68                - for slice group ids if map type is 6
69
70            Validity of some of the slice group mapping information depends
71            on the image dimensions which are not known here. Therefore the
72            validity has to be checked afterwards, currently in the parameter
73            set activation phase.
74
75        Inputs:
76            pStrmData       pointer to stream data structure
77
78        Outputs:
79            pPicParamSet    decoded information is stored here
80
81        Returns:
82            HANTRO_OK       success
83            HANTRO_NOK      failure, invalid information or end of stream
84            MEMORY_ALLOCATION_ERROR for memory allocation failure
85
86
87------------------------------------------------------------------------------*/
88
89u32 h264bsdDecodePicParamSet(strmData_t *pStrmData, picParamSet_t *pPicParamSet)
90{
91
92/* Variables */
93
94    u32 tmp, i, value;
95    i32 itmp;
96
97/* Code */
98
99    ASSERT(pStrmData);
100    ASSERT(pPicParamSet);
101
102
103    H264SwDecMemset(pPicParamSet, 0, sizeof(picParamSet_t));
104
105    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
106        &pPicParamSet->picParameterSetId);
107    if (tmp != HANTRO_OK)
108        return(tmp);
109    if (pPicParamSet->picParameterSetId >= MAX_NUM_PIC_PARAM_SETS)
110    {
111        EPRINT("pic_parameter_set_id");
112        return(HANTRO_NOK);
113    }
114
115    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
116        &pPicParamSet->seqParameterSetId);
117    if (tmp != HANTRO_OK)
118        return(tmp);
119    if (pPicParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
120    {
121        EPRINT("seq_param_set_id");
122        return(HANTRO_NOK);
123    }
124
125    /* entropy_coding_mode_flag, shall be 0 for baseline profile */
126    tmp = h264bsdGetBits(pStrmData, 1);
127    if (tmp)
128    {
129        EPRINT("entropy_coding_mode_flag");
130        return(HANTRO_NOK);
131    }
132
133    tmp = h264bsdGetBits(pStrmData, 1);
134    if (tmp == END_OF_STREAM)
135        return(HANTRO_NOK);
136    pPicParamSet->picOrderPresentFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
137
138    /* num_slice_groups_minus1 */
139    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
140    if (tmp != HANTRO_OK)
141        return(tmp);
142    pPicParamSet->numSliceGroups = value + 1;
143    if (pPicParamSet->numSliceGroups > MAX_NUM_SLICE_GROUPS)
144    {
145        EPRINT("num_slice_groups_minus1");
146        return(HANTRO_NOK);
147    }
148
149    /* decode slice group mapping information if more than one slice groups */
150    if (pPicParamSet->numSliceGroups > 1)
151    {
152        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
153            &pPicParamSet->sliceGroupMapType);
154        if (tmp != HANTRO_OK)
155            return(tmp);
156        if (pPicParamSet->sliceGroupMapType > 6)
157        {
158            EPRINT("slice_group_map_type");
159            return(HANTRO_NOK);
160        }
161
162        if (pPicParamSet->sliceGroupMapType == 0)
163        {
164            ALLOCATE(pPicParamSet->runLength,
165                pPicParamSet->numSliceGroups, u32);
166            if (pPicParamSet->runLength == NULL)
167                return(MEMORY_ALLOCATION_ERROR);
168            for (i = 0; i < pPicParamSet->numSliceGroups; i++)
169            {
170                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
171                if (tmp != HANTRO_OK)
172                    return(tmp);
173                pPicParamSet->runLength[i] = value+1;
174                /* param values checked in CheckPps() */
175            }
176        }
177        else if (pPicParamSet->sliceGroupMapType == 2)
178        {
179            ALLOCATE(pPicParamSet->topLeft,
180                pPicParamSet->numSliceGroups - 1, u32);
181            ALLOCATE(pPicParamSet->bottomRight,
182                pPicParamSet->numSliceGroups - 1, u32);
183            if (pPicParamSet->topLeft == NULL ||
184                pPicParamSet->bottomRight == NULL)
185                return(MEMORY_ALLOCATION_ERROR);
186            for (i = 0; i < pPicParamSet->numSliceGroups - 1; i++)
187            {
188                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
189                if (tmp != HANTRO_OK)
190                    return(tmp);
191                pPicParamSet->topLeft[i] = value;
192                tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
193                if (tmp != HANTRO_OK)
194                    return(tmp);
195                pPicParamSet->bottomRight[i] = value;
196                /* param values checked in CheckPps() */
197            }
198        }
199        else if ( (pPicParamSet->sliceGroupMapType == 3) ||
200                  (pPicParamSet->sliceGroupMapType == 4) ||
201                  (pPicParamSet->sliceGroupMapType == 5) )
202        {
203            tmp = h264bsdGetBits(pStrmData, 1);
204            if (tmp == END_OF_STREAM)
205                return(HANTRO_NOK);
206            pPicParamSet->sliceGroupChangeDirectionFlag =
207                (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
208            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
209            if (tmp != HANTRO_OK)
210                return(tmp);
211            pPicParamSet->sliceGroupChangeRate = value + 1;
212            /* param value checked in CheckPps() */
213        }
214        else if (pPicParamSet->sliceGroupMapType == 6)
215        {
216            tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
217            if (tmp != HANTRO_OK)
218                return(tmp);
219            pPicParamSet->picSizeInMapUnits = value + 1;
220
221            ALLOCATE(pPicParamSet->sliceGroupId,
222                pPicParamSet->picSizeInMapUnits, u32);
223            if (pPicParamSet->sliceGroupId == NULL)
224                return(MEMORY_ALLOCATION_ERROR);
225
226            /* determine number of bits needed to represent range
227             * [0, numSliceGroups) */
228            tmp = CeilLog2NumSliceGroups[pPicParamSet->numSliceGroups-1];
229
230            for (i = 0; i < pPicParamSet->picSizeInMapUnits; i++)
231            {
232                pPicParamSet->sliceGroupId[i] = h264bsdGetBits(pStrmData, tmp);
233                if ( pPicParamSet->sliceGroupId[i] >=
234                     pPicParamSet->numSliceGroups )
235                {
236                    EPRINT("slice_group_id");
237                    return(HANTRO_NOK);
238                }
239            }
240        }
241    }
242
243    /* num_ref_idx_l0_active_minus1 */
244    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
245    if (tmp != HANTRO_OK)
246        return(tmp);
247    if (value > 31)
248    {
249        EPRINT("num_ref_idx_l0_active_minus1");
250        return(HANTRO_NOK);
251    }
252    pPicParamSet->numRefIdxL0Active = value + 1;
253
254    /* num_ref_idx_l1_active_minus1 */
255    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
256    if (tmp != HANTRO_OK)
257        return(tmp);
258    if (value > 31)
259    {
260        EPRINT("num_ref_idx_l1_active_minus1");
261        return(HANTRO_NOK);
262    }
263
264    /* weighted_pred_flag, this shall be 0 for baseline profile */
265    tmp = h264bsdGetBits(pStrmData, 1);
266    if (tmp)
267    {
268        EPRINT("weighted_pred_flag");
269        return(HANTRO_NOK);
270    }
271
272    /* weighted_bipred_idc */
273    tmp = h264bsdGetBits(pStrmData, 2);
274    if (tmp > 2)
275    {
276        EPRINT("weighted_bipred_idc");
277        return(HANTRO_NOK);
278    }
279
280    /* pic_init_qp_minus26 */
281    tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
282    if (tmp != HANTRO_OK)
283        return(tmp);
284    if ((itmp < -26) || (itmp > 25))
285    {
286        EPRINT("pic_init_qp_minus26");
287        return(HANTRO_NOK);
288    }
289    pPicParamSet->picInitQp = (u32)(itmp + 26);
290
291    /* pic_init_qs_minus26 */
292    tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
293    if (tmp != HANTRO_OK)
294        return(tmp);
295    if ((itmp < -26) || (itmp > 25))
296    {
297        EPRINT("pic_init_qs_minus26");
298        return(HANTRO_NOK);
299    }
300
301    tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
302    if (tmp != HANTRO_OK)
303        return(tmp);
304    if ((itmp < -12) || (itmp > 12))
305    {
306        EPRINT("chroma_qp_index_offset");
307        return(HANTRO_NOK);
308    }
309    pPicParamSet->chromaQpIndexOffset = itmp;
310
311    tmp = h264bsdGetBits(pStrmData, 1);
312    if (tmp == END_OF_STREAM)
313        return(HANTRO_NOK);
314    pPicParamSet->deblockingFilterControlPresentFlag =
315        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
316
317    tmp = h264bsdGetBits(pStrmData, 1);
318    if (tmp == END_OF_STREAM)
319        return(HANTRO_NOK);
320    pPicParamSet->constrainedIntraPredFlag = (tmp == 1) ?
321                                    HANTRO_TRUE : HANTRO_FALSE;
322
323    tmp = h264bsdGetBits(pStrmData, 1);
324    if (tmp == END_OF_STREAM)
325        return(HANTRO_NOK);
326    pPicParamSet->redundantPicCntPresentFlag = (tmp == 1) ?
327                                    HANTRO_TRUE : HANTRO_FALSE;
328
329    tmp = h264bsdRbspTrailingBits(pStrmData);
330
331    /* ignore possible errors in trailing bits of parameters sets */
332    return(HANTRO_OK);
333
334}
335
336