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
h264bsdDecodePicOrderCnt(pocStorage_t * poc,seqParamSet_t * sps,sliceHeader_t * pSliceHeader,nalUnit_t * pNalUnit)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