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 */ 52 static 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 89 u32 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