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 h264bsdDecodePicOrderCnt 27 28 ------------------------------------------------------------------------------*/ 29 30 /*------------------------------------------------------------------------------ 31 1. Include headers 32 ------------------------------------------------------------------------------*/ 33 34 #include "h264bsd_util.h" 35 #include "h264bsd_pic_order_cnt.h" 36 37 /*------------------------------------------------------------------------------ 38 2. External compiler flags 39 -------------------------------------------------------------------------------- 40 41 -------------------------------------------------------------------------------- 42 3. Module defines 43 ------------------------------------------------------------------------------*/ 44 45 /*------------------------------------------------------------------------------ 46 4. Local function prototypes 47 ------------------------------------------------------------------------------*/ 48 49 /*------------------------------------------------------------------------------ 50 51 Function: h264bsdDecodePicOrderCnt 52 53 Functional description: 54 Compute picture order count for a picture. Function implements 55 computation of all POC types (0, 1 and 2), type is obtained from 56 sps. See standard for description of the POC types and how POC is 57 computed for each type. 58 59 Function returns the minimum of top field and bottom field pic 60 order counts. 61 62 Inputs: 63 poc pointer to previous results 64 sps pointer to sequence parameter set 65 slicHeader pointer to current slice header, frame number and 66 other params needed for POC computation 67 pNalUnit pointer to current NAL unit structrue, function needs 68 to know if this is an IDR picture and also if this is 69 a reference picture 70 71 Outputs: 72 poc results stored here for computation of next POC 73 74 Returns: 75 picture order count 76 77 ------------------------------------------------------------------------------*/ 78 79 i32 h264bsdDecodePicOrderCnt(pocStorage_t *poc, seqParamSet_t *sps, 80 sliceHeader_t *pSliceHeader, nalUnit_t *pNalUnit) 81 { 82 83 /* Variables */ 84 85 u32 i; 86 i32 picOrderCnt; 87 u32 frameNumOffset, absFrameNum, picOrderCntCycleCnt; 88 u32 frameNumInPicOrderCntCycle; 89 i32 expectedDeltaPicOrderCntCycle; 90 u32 containsMmco5; 91 92 /* Code */ 93 94 ASSERT(poc); 95 ASSERT(sps); 96 ASSERT(pSliceHeader); 97 ASSERT(pNalUnit); 98 ASSERT(sps->picOrderCntType <= 2); 99 100 #if 0 101 /* JanSa: I don't think this is necessary, don't see any reason to 102 * increment prevFrameNum one by one instead of one big increment. 103 * However, standard specifies that this should be done -> if someone 104 * figures out any case when the outcome would be different for step by 105 * step increment, this part of the code should be enabled */ 106 107 /* if there was a gap in frame numbering and picOrderCntType is 1 or 2 -> 108 * "compute" pic order counts for non-existing frames. These are not 109 * actually computed, but process needs to be done to update the 110 * prevFrameNum and prevFrameNumOffset */ 111 if ( sps->picOrderCntType > 0 && 112 pSliceHeader->frameNum != poc->prevFrameNum && 113 pSliceHeader->frameNum != ((poc->prevFrameNum + 1) % sps->maxFrameNum)) 114 { 115 116 /* use variable i for unUsedShortTermFrameNum */ 117 i = (poc->prevFrameNum + 1) % sps->maxFrameNum; 118 119 do 120 { 121 if (poc->prevFrameNum > i) 122 frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum; 123 else 124 frameNumOffset = poc->prevFrameNumOffset; 125 126 poc->prevFrameNumOffset = frameNumOffset; 127 poc->prevFrameNum = i; 128 129 i = (i + 1) % sps->maxFrameNum; 130 131 } while (i != pSliceHeader->frameNum); 132 } 133 #endif 134 135 /* check if current slice includes mmco equal to 5 */ 136 containsMmco5 = HANTRO_FALSE; 137 if (pSliceHeader->decRefPicMarking.adaptiveRefPicMarkingModeFlag) 138 { 139 i = 0; 140 while (pSliceHeader->decRefPicMarking.operation[i]. 141 memoryManagementControlOperation) 142 { 143 if (pSliceHeader->decRefPicMarking.operation[i]. 144 memoryManagementControlOperation == 5) 145 { 146 containsMmco5 = HANTRO_TRUE; 147 break; 148 } 149 i++; 150 } 151 } 152 switch (sps->picOrderCntType) 153 { 154 155 case 0: 156 /* set prevPicOrderCnt values for IDR frame */ 157 if (IS_IDR_NAL_UNIT(pNalUnit)) 158 { 159 poc->prevPicOrderCntMsb = 0; 160 poc->prevPicOrderCntLsb = 0; 161 } 162 163 /* compute picOrderCntMsb (stored in picOrderCnt variable) */ 164 if ( (pSliceHeader->picOrderCntLsb < poc->prevPicOrderCntLsb) && 165 ((poc->prevPicOrderCntLsb - pSliceHeader->picOrderCntLsb) >= 166 sps->maxPicOrderCntLsb/2) ) 167 { 168 picOrderCnt = poc->prevPicOrderCntMsb + 169 (i32)sps->maxPicOrderCntLsb; 170 } 171 else if ((pSliceHeader->picOrderCntLsb > poc->prevPicOrderCntLsb) && 172 ((pSliceHeader->picOrderCntLsb - poc->prevPicOrderCntLsb) > 173 sps->maxPicOrderCntLsb/2) ) 174 { 175 picOrderCnt = poc->prevPicOrderCntMsb - 176 (i32)sps->maxPicOrderCntLsb; 177 } 178 else 179 picOrderCnt = poc->prevPicOrderCntMsb; 180 181 /* standard specifies that prevPicOrderCntMsb is from previous 182 * rererence frame -> replace old value only if current frame is 183 * rererence frame */ 184 if (pNalUnit->nalRefIdc) 185 poc->prevPicOrderCntMsb = picOrderCnt; 186 187 /* compute top field order cnt (stored in picOrderCnt) */ 188 picOrderCnt += (i32)pSliceHeader->picOrderCntLsb; 189 190 /* if delta for bottom field is negative -> bottom will be the 191 * minimum pic order count */ 192 if (pSliceHeader->deltaPicOrderCntBottom < 0) 193 picOrderCnt += pSliceHeader->deltaPicOrderCntBottom; 194 195 /* standard specifies that prevPicOrderCntLsb is from previous 196 * rererence frame -> replace old value only if current frame is 197 * rererence frame */ 198 if (pNalUnit->nalRefIdc) 199 { 200 /* if current frame contains mmco5 -> modify values to be 201 * stored */ 202 if (containsMmco5) 203 { 204 poc->prevPicOrderCntMsb = 0; 205 /* prevPicOrderCntLsb should be the top field picOrderCnt 206 * if previous frame included mmco5. Top field picOrderCnt 207 * for frames containing mmco5 is obtained by subtracting 208 * the picOrderCnt from original top field order count -> 209 * value is zero if top field was the minimum, i.e. delta 210 * for bottom was positive, otherwise value is 211 * -deltaPicOrderCntBottom */ 212 if (pSliceHeader->deltaPicOrderCntBottom < 0) 213 poc->prevPicOrderCntLsb = 214 (u32)(-pSliceHeader->deltaPicOrderCntBottom); 215 else 216 poc->prevPicOrderCntLsb = 0; 217 picOrderCnt = 0; 218 } 219 else 220 { 221 poc->prevPicOrderCntLsb = pSliceHeader->picOrderCntLsb; 222 } 223 } 224 225 break; 226 227 case 1: 228 229 /* step 1 (in the description in the standard) */ 230 if (IS_IDR_NAL_UNIT(pNalUnit)) 231 frameNumOffset = 0; 232 else if (poc->prevFrameNum > pSliceHeader->frameNum) 233 frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum; 234 else 235 frameNumOffset = poc->prevFrameNumOffset; 236 237 /* step 2 */ 238 if (sps->numRefFramesInPicOrderCntCycle) 239 absFrameNum = frameNumOffset + pSliceHeader->frameNum; 240 else 241 absFrameNum = 0; 242 243 if (pNalUnit->nalRefIdc == 0 && absFrameNum > 0) 244 absFrameNum -= 1; 245 246 /* step 3 */ 247 if (absFrameNum > 0) 248 { 249 picOrderCntCycleCnt = 250 (absFrameNum - 1)/sps->numRefFramesInPicOrderCntCycle; 251 frameNumInPicOrderCntCycle = 252 (absFrameNum - 1)%sps->numRefFramesInPicOrderCntCycle; 253 } 254 255 /* step 4 */ 256 expectedDeltaPicOrderCntCycle = 0; 257 for (i = 0; i < sps->numRefFramesInPicOrderCntCycle; i++) 258 expectedDeltaPicOrderCntCycle += sps->offsetForRefFrame[i]; 259 260 /* step 5 (picOrderCnt used to store expectedPicOrderCnt) */ 261 /*lint -esym(644,picOrderCntCycleCnt) always initialized */ 262 /*lint -esym(644,frameNumInPicOrderCntCycle) always initialized */ 263 if (absFrameNum > 0) 264 { 265 picOrderCnt = 266 (i32)picOrderCntCycleCnt * expectedDeltaPicOrderCntCycle; 267 for (i = 0; i <= frameNumInPicOrderCntCycle; i++) 268 picOrderCnt += sps->offsetForRefFrame[i]; 269 } 270 else 271 picOrderCnt = 0; 272 273 if (pNalUnit->nalRefIdc == 0) 274 picOrderCnt += sps->offsetForNonRefPic; 275 276 /* step 6 (picOrderCnt is top field order cnt if delta for bottom 277 * is positive, otherwise it is bottom field order cnt) */ 278 picOrderCnt += pSliceHeader->deltaPicOrderCnt[0]; 279 280 if ( (sps->offsetForTopToBottomField + 281 pSliceHeader->deltaPicOrderCnt[1]) < 0 ) 282 { 283 picOrderCnt += sps->offsetForTopToBottomField + 284 pSliceHeader->deltaPicOrderCnt[1]; 285 } 286 287 /* if current picture contains mmco5 -> set prevFrameNumOffset and 288 * prevFrameNum to 0 for computation of picOrderCnt of next 289 * frame, otherwise store frameNum and frameNumOffset to poc 290 * structure */ 291 if (!containsMmco5) 292 { 293 poc->prevFrameNumOffset = frameNumOffset; 294 poc->prevFrameNum = pSliceHeader->frameNum; 295 } 296 else 297 { 298 poc->prevFrameNumOffset = 0; 299 poc->prevFrameNum = 0; 300 picOrderCnt = 0; 301 } 302 break; 303 304 default: /* case 2 */ 305 /* derive frameNumOffset */ 306 if (IS_IDR_NAL_UNIT(pNalUnit)) 307 frameNumOffset = 0; 308 else if (poc->prevFrameNum > pSliceHeader->frameNum) 309 frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum; 310 else 311 frameNumOffset = poc->prevFrameNumOffset; 312 313 /* derive picOrderCnt (type 2 has same value for top and bottom 314 * field order cnts) */ 315 if (IS_IDR_NAL_UNIT(pNalUnit)) 316 picOrderCnt = 0; 317 else if (pNalUnit->nalRefIdc == 0) 318 picOrderCnt = 319 2 * (i32)(frameNumOffset + pSliceHeader->frameNum) - 1; 320 else 321 picOrderCnt = 322 2 * (i32)(frameNumOffset + pSliceHeader->frameNum); 323 324 /* if current picture contains mmco5 -> set prevFrameNumOffset and 325 * prevFrameNum to 0 for computation of picOrderCnt of next 326 * frame, otherwise store frameNum and frameNumOffset to poc 327 * structure */ 328 if (!containsMmco5) 329 { 330 poc->prevFrameNumOffset = frameNumOffset; 331 poc->prevFrameNum = pSliceHeader->frameNum; 332 } 333 else 334 { 335 poc->prevFrameNumOffset = 0; 336 poc->prevFrameNum = 0; 337 picOrderCnt = 0; 338 } 339 break; 340 341 } 342 343 /*lint -esym(644,picOrderCnt) always initialized */ 344 return(picOrderCnt); 345 346 } 347 348