summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c')
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c347
1 files changed, 347 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c
new file mode 100755
index 0000000..fb23352
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodePicOrderCnt
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_util.h"
+#include "h264bsd_pic_order_cnt.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodePicOrderCnt
+
+ Functional description:
+ Compute picture order count for a picture. Function implements
+ computation of all POC types (0, 1 and 2), type is obtained from
+ sps. See standard for description of the POC types and how POC is
+ computed for each type.
+
+ Function returns the minimum of top field and bottom field pic
+ order counts.
+
+ Inputs:
+ poc pointer to previous results
+ sps pointer to sequence parameter set
+ slicHeader pointer to current slice header, frame number and
+ other params needed for POC computation
+ pNalUnit pointer to current NAL unit structrue, function needs
+ to know if this is an IDR picture and also if this is
+ a reference picture
+
+ Outputs:
+ poc results stored here for computation of next POC
+
+ Returns:
+ picture order count
+
+------------------------------------------------------------------------------*/
+
+i32 h264bsdDecodePicOrderCnt(pocStorage_t *poc, seqParamSet_t *sps,
+ sliceHeader_t *pSliceHeader, nalUnit_t *pNalUnit)
+{
+
+/* Variables */
+
+ u32 i;
+ i32 picOrderCnt;
+ u32 frameNumOffset, absFrameNum, picOrderCntCycleCnt;
+ u32 frameNumInPicOrderCntCycle;
+ i32 expectedDeltaPicOrderCntCycle;
+ u32 containsMmco5;
+
+/* Code */
+
+ ASSERT(poc);
+ ASSERT(sps);
+ ASSERT(pSliceHeader);
+ ASSERT(pNalUnit);
+ ASSERT(sps->picOrderCntType <= 2);
+
+#if 0
+ /* JanSa: I don't think this is necessary, don't see any reason to
+ * increment prevFrameNum one by one instead of one big increment.
+ * However, standard specifies that this should be done -> if someone
+ * figures out any case when the outcome would be different for step by
+ * step increment, this part of the code should be enabled */
+
+ /* if there was a gap in frame numbering and picOrderCntType is 1 or 2 ->
+ * "compute" pic order counts for non-existing frames. These are not
+ * actually computed, but process needs to be done to update the
+ * prevFrameNum and prevFrameNumOffset */
+ if ( sps->picOrderCntType > 0 &&
+ pSliceHeader->frameNum != poc->prevFrameNum &&
+ pSliceHeader->frameNum != ((poc->prevFrameNum + 1) % sps->maxFrameNum))
+ {
+
+ /* use variable i for unUsedShortTermFrameNum */
+ i = (poc->prevFrameNum + 1) % sps->maxFrameNum;
+
+ do
+ {
+ if (poc->prevFrameNum > i)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = i;
+
+ i = (i + 1) % sps->maxFrameNum;
+
+ } while (i != pSliceHeader->frameNum);
+ }
+#endif
+
+ /* check if current slice includes mmco equal to 5 */
+ containsMmco5 = HANTRO_FALSE;
+ if (pSliceHeader->decRefPicMarking.adaptiveRefPicMarkingModeFlag)
+ {
+ i = 0;
+ while (pSliceHeader->decRefPicMarking.operation[i].
+ memoryManagementControlOperation)
+ {
+ if (pSliceHeader->decRefPicMarking.operation[i].
+ memoryManagementControlOperation == 5)
+ {
+ containsMmco5 = HANTRO_TRUE;
+ break;
+ }
+ i++;
+ }
+ }
+ switch (sps->picOrderCntType)
+ {
+
+ case 0:
+ /* set prevPicOrderCnt values for IDR frame */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ {
+ poc->prevPicOrderCntMsb = 0;
+ poc->prevPicOrderCntLsb = 0;
+ }
+
+ /* compute picOrderCntMsb (stored in picOrderCnt variable) */
+ if ( (pSliceHeader->picOrderCntLsb < poc->prevPicOrderCntLsb) &&
+ ((poc->prevPicOrderCntLsb - pSliceHeader->picOrderCntLsb) >=
+ sps->maxPicOrderCntLsb/2) )
+ {
+ picOrderCnt = poc->prevPicOrderCntMsb +
+ (i32)sps->maxPicOrderCntLsb;
+ }
+ else if ((pSliceHeader->picOrderCntLsb > poc->prevPicOrderCntLsb) &&
+ ((pSliceHeader->picOrderCntLsb - poc->prevPicOrderCntLsb) >
+ sps->maxPicOrderCntLsb/2) )
+ {
+ picOrderCnt = poc->prevPicOrderCntMsb -
+ (i32)sps->maxPicOrderCntLsb;
+ }
+ else
+ picOrderCnt = poc->prevPicOrderCntMsb;
+
+ /* standard specifies that prevPicOrderCntMsb is from previous
+ * rererence frame -> replace old value only if current frame is
+ * rererence frame */
+ if (pNalUnit->nalRefIdc)
+ poc->prevPicOrderCntMsb = picOrderCnt;
+
+ /* compute top field order cnt (stored in picOrderCnt) */
+ picOrderCnt += (i32)pSliceHeader->picOrderCntLsb;
+
+ /* if delta for bottom field is negative -> bottom will be the
+ * minimum pic order count */
+ if (pSliceHeader->deltaPicOrderCntBottom < 0)
+ picOrderCnt += pSliceHeader->deltaPicOrderCntBottom;
+
+ /* standard specifies that prevPicOrderCntLsb is from previous
+ * rererence frame -> replace old value only if current frame is
+ * rererence frame */
+ if (pNalUnit->nalRefIdc)
+ {
+ /* if current frame contains mmco5 -> modify values to be
+ * stored */
+ if (containsMmco5)
+ {
+ poc->prevPicOrderCntMsb = 0;
+ /* prevPicOrderCntLsb should be the top field picOrderCnt
+ * if previous frame included mmco5. Top field picOrderCnt
+ * for frames containing mmco5 is obtained by subtracting
+ * the picOrderCnt from original top field order count ->
+ * value is zero if top field was the minimum, i.e. delta
+ * for bottom was positive, otherwise value is
+ * -deltaPicOrderCntBottom */
+ if (pSliceHeader->deltaPicOrderCntBottom < 0)
+ poc->prevPicOrderCntLsb =
+ (u32)(-pSliceHeader->deltaPicOrderCntBottom);
+ else
+ poc->prevPicOrderCntLsb = 0;
+ picOrderCnt = 0;
+ }
+ else
+ {
+ poc->prevPicOrderCntLsb = pSliceHeader->picOrderCntLsb;
+ }
+ }
+
+ break;
+
+ case 1:
+
+ /* step 1 (in the description in the standard) */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ frameNumOffset = 0;
+ else if (poc->prevFrameNum > pSliceHeader->frameNum)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ /* step 2 */
+ if (sps->numRefFramesInPicOrderCntCycle)
+ absFrameNum = frameNumOffset + pSliceHeader->frameNum;
+ else
+ absFrameNum = 0;
+
+ if (pNalUnit->nalRefIdc == 0 && absFrameNum > 0)
+ absFrameNum -= 1;
+
+ /* step 3 */
+ if (absFrameNum > 0)
+ {
+ picOrderCntCycleCnt =
+ (absFrameNum - 1)/sps->numRefFramesInPicOrderCntCycle;
+ frameNumInPicOrderCntCycle =
+ (absFrameNum - 1)%sps->numRefFramesInPicOrderCntCycle;
+ }
+
+ /* step 4 */
+ expectedDeltaPicOrderCntCycle = 0;
+ for (i = 0; i < sps->numRefFramesInPicOrderCntCycle; i++)
+ expectedDeltaPicOrderCntCycle += sps->offsetForRefFrame[i];
+
+ /* step 5 (picOrderCnt used to store expectedPicOrderCnt) */
+ /*lint -esym(644,picOrderCntCycleCnt) always initialized */
+ /*lint -esym(644,frameNumInPicOrderCntCycle) always initialized */
+ if (absFrameNum > 0)
+ {
+ picOrderCnt =
+ (i32)picOrderCntCycleCnt * expectedDeltaPicOrderCntCycle;
+ for (i = 0; i <= frameNumInPicOrderCntCycle; i++)
+ picOrderCnt += sps->offsetForRefFrame[i];
+ }
+ else
+ picOrderCnt = 0;
+
+ if (pNalUnit->nalRefIdc == 0)
+ picOrderCnt += sps->offsetForNonRefPic;
+
+ /* step 6 (picOrderCnt is top field order cnt if delta for bottom
+ * is positive, otherwise it is bottom field order cnt) */
+ picOrderCnt += pSliceHeader->deltaPicOrderCnt[0];
+
+ if ( (sps->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1]) < 0 )
+ {
+ picOrderCnt += sps->offsetForTopToBottomField +
+ pSliceHeader->deltaPicOrderCnt[1];
+ }
+
+ /* if current picture contains mmco5 -> set prevFrameNumOffset and
+ * prevFrameNum to 0 for computation of picOrderCnt of next
+ * frame, otherwise store frameNum and frameNumOffset to poc
+ * structure */
+ if (!containsMmco5)
+ {
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = pSliceHeader->frameNum;
+ }
+ else
+ {
+ poc->prevFrameNumOffset = 0;
+ poc->prevFrameNum = 0;
+ picOrderCnt = 0;
+ }
+ break;
+
+ default: /* case 2 */
+ /* derive frameNumOffset */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ frameNumOffset = 0;
+ else if (poc->prevFrameNum > pSliceHeader->frameNum)
+ frameNumOffset = poc->prevFrameNumOffset + sps->maxFrameNum;
+ else
+ frameNumOffset = poc->prevFrameNumOffset;
+
+ /* derive picOrderCnt (type 2 has same value for top and bottom
+ * field order cnts) */
+ if (IS_IDR_NAL_UNIT(pNalUnit))
+ picOrderCnt = 0;
+ else if (pNalUnit->nalRefIdc == 0)
+ picOrderCnt =
+ 2 * (i32)(frameNumOffset + pSliceHeader->frameNum) - 1;
+ else
+ picOrderCnt =
+ 2 * (i32)(frameNumOffset + pSliceHeader->frameNum);
+
+ /* if current picture contains mmco5 -> set prevFrameNumOffset and
+ * prevFrameNum to 0 for computation of picOrderCnt of next
+ * frame, otherwise store frameNum and frameNumOffset to poc
+ * structure */
+ if (!containsMmco5)
+ {
+ poc->prevFrameNumOffset = frameNumOffset;
+ poc->prevFrameNum = pSliceHeader->frameNum;
+ }
+ else
+ {
+ poc->prevFrameNumOffset = 0;
+ poc->prevFrameNum = 0;
+ picOrderCnt = 0;
+ }
+ break;
+
+ }
+
+ /*lint -esym(644,picOrderCnt) always initialized */
+ return(picOrderCnt);
+
+}
+