summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c')
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c888
1 files changed, 888 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c
new file mode 100755
index 0000000..3234754
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c
@@ -0,0 +1,888 @@
+/*
+ * 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
+ h264bsdInitStorage
+ h264bsdStoreSeqParamSet
+ h264bsdStorePicParamSet
+ h264bsdActivateParamSets
+ h264bsdResetStorage
+ h264bsdIsStartOfPicture
+ h264bsdIsEndOfPicture
+ h264bsdComputeSliceGroupMap
+ h264bsdCheckAccessUnitBoundary
+ CheckPps
+ h264bsdValidParamSets
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_storage.h"
+#include "h264bsd_util.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_slice_group_map.h"
+#include "h264bsd_dpb.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_seq_param_set.h"
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps);
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdInitStorage
+
+ Functional description:
+ Initialize storage structure. Sets contents of the storage to '0'
+ except for the active parameter set ids, which are initialized
+ to invalid values.
+
+ Inputs:
+
+ Outputs:
+ pStorage initialized data stored here
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdInitStorage(storage_t *pStorage)
+{
+
+/* Variables */
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ H264SwDecMemset(pStorage, 0, sizeof(storage_t));
+
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
+
+ pStorage->aub->firstCallFlag = HANTRO_TRUE;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdStoreSeqParamSet
+
+ Functional description:
+ Store sequence parameter set into the storage. If active SPS is
+ overwritten -> check if contents changes and if it does, set
+ parameters to force reactivation of parameter sets
+
+ Inputs:
+ pStorage pointer to storage structure
+ pSeqParamSet pointer to param set to be stored
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdStoreSeqParamSet(storage_t *pStorage, seqParamSet_t *pSeqParamSet)
+{
+
+/* Variables */
+
+ u32 id;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(pSeqParamSet);
+ ASSERT(pSeqParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
+
+ id = pSeqParamSet->seqParameterSetId;
+
+ /* seq parameter set with id not used before -> allocate memory */
+ if (pStorage->sps[id] == NULL)
+ {
+ ALLOCATE(pStorage->sps[id], 1, seqParamSet_t);
+ if (pStorage->sps[id] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ }
+ /* sequence parameter set with id equal to id of active sps */
+ else if (id == pStorage->activeSpsId)
+ {
+ /* if seq parameter set contents changes
+ * -> overwrite and re-activate when next IDR picture decoded
+ * ids of active param sets set to invalid values to force
+ * re-activation. Memories allocated for old sps freed
+ * otherwise free memeries allocated for just decoded sps and
+ * continue */
+ if (h264bsdCompareSeqParamSets(pSeqParamSet, pStorage->activeSps) != 0)
+ {
+ FREE(pStorage->sps[id]->offsetForRefFrame);
+ FREE(pStorage->sps[id]->vuiParameters);
+ pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS + 1;
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
+ pStorage->activeSps = NULL;
+ pStorage->activePps = NULL;
+ }
+ else
+ {
+ FREE(pSeqParamSet->offsetForRefFrame);
+ FREE(pSeqParamSet->vuiParameters);
+ return(HANTRO_OK);
+ }
+ }
+ /* overwrite seq param set other than active one -> free memories
+ * allocated for old param set */
+ else
+ {
+ FREE(pStorage->sps[id]->offsetForRefFrame);
+ FREE(pStorage->sps[id]->vuiParameters);
+ }
+
+ *pStorage->sps[id] = *pSeqParamSet;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdStorePicParamSet
+
+ Functional description:
+ Store picture parameter set into the storage. If active PPS is
+ overwritten -> check if active SPS changes and if it does -> set
+ parameters to force reactivation of parameter sets
+
+ Inputs:
+ pStorage pointer to storage structure
+ pPicParamSet pointer to param set to be stored
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdStorePicParamSet(storage_t *pStorage, picParamSet_t *pPicParamSet)
+{
+
+/* Variables */
+
+ u32 id;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(pPicParamSet);
+ ASSERT(pPicParamSet->picParameterSetId < MAX_NUM_PIC_PARAM_SETS);
+ ASSERT(pPicParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
+
+ id = pPicParamSet->picParameterSetId;
+
+ /* pic parameter set with id not used before -> allocate memory */
+ if (pStorage->pps[id] == NULL)
+ {
+ ALLOCATE(pStorage->pps[id], 1, picParamSet_t);
+ if (pStorage->pps[id] == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+ }
+ /* picture parameter set with id equal to id of active pps */
+ else if (id == pStorage->activePpsId)
+ {
+ /* check whether seq param set changes, force re-activation of
+ * param set if it does. Set activeSpsId to invalid value to
+ * accomplish this */
+ if (pPicParamSet->seqParameterSetId != pStorage->activeSpsId)
+ {
+ pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
+ }
+ /* free memories allocated for old param set */
+ FREE(pStorage->pps[id]->runLength);
+ FREE(pStorage->pps[id]->topLeft);
+ FREE(pStorage->pps[id]->bottomRight);
+ FREE(pStorage->pps[id]->sliceGroupId);
+ }
+ /* overwrite pic param set other than active one -> free memories
+ * allocated for old param set */
+ else
+ {
+ FREE(pStorage->pps[id]->runLength);
+ FREE(pStorage->pps[id]->topLeft);
+ FREE(pStorage->pps[id]->bottomRight);
+ FREE(pStorage->pps[id]->sliceGroupId);
+ }
+
+ *pStorage->pps[id] = *pPicParamSet;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdActivateParamSets
+
+ Functional description:
+ Activate certain SPS/PPS combination. This function shall be
+ called in the beginning of each picture. Picture parameter set
+ can be changed as wanted, but sequence parameter set may only be
+ changed when the starting picture is an IDR picture.
+
+ When new SPS is activated the function allocates memory for
+ macroblock storages and slice group map and (re-)initializes the
+ decoded picture buffer. If this is not the first activation the old
+ allocations are freed and FreeDpb called before new allocations.
+
+ Inputs:
+ pStorage pointer to storage data structure
+ ppsId identifies the PPS to be activated, SPS id obtained
+ from the PPS
+ isIdr flag to indicate if the picture is an IDR picture
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK non-existing or invalid param set combination,
+ trying to change SPS with non-IDR picture
+ MEMORY_ALLOCATION_ERROR failure in memory allocation
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr)
+{
+
+/* Variables */
+
+ u32 tmp;
+ u32 flag;
+
+/* Code */
+
+ ASSERT(pStorage);
+ ASSERT(ppsId < MAX_NUM_PIC_PARAM_SETS);
+
+ /* check that pps and corresponding sps exist */
+ if ( (pStorage->pps[ppsId] == NULL) ||
+ (pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId] == NULL) )
+ {
+ return(HANTRO_NOK);
+ }
+
+ /* check that pps parameters do not violate picture size constraints */
+ tmp = CheckPps(pStorage->pps[ppsId],
+ pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId]);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* first activation part1 */
+ if (pStorage->activePpsId == MAX_NUM_PIC_PARAM_SETS)
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
+ pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
+ pStorage->picSizeInMbs =
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
+ pStorage->currImage->height = pStorage->activeSps->picHeightInMbs;
+
+ pStorage->pendingActivation = HANTRO_TRUE;
+ }
+ /* first activation part2 */
+ else if (pStorage->pendingActivation)
+ {
+ pStorage->pendingActivation = HANTRO_FALSE;
+
+ FREE(pStorage->mb);
+ FREE(pStorage->sliceGroupMap);
+
+ ALLOCATE(pStorage->mb, pStorage->picSizeInMbs, mbStorage_t);
+ ALLOCATE(pStorage->sliceGroupMap, pStorage->picSizeInMbs, u32);
+ if (pStorage->mb == NULL || pStorage->sliceGroupMap == NULL)
+ return(MEMORY_ALLOCATION_ERROR);
+
+ H264SwDecMemset(pStorage->mb, 0,
+ pStorage->picSizeInMbs * sizeof(mbStorage_t));
+
+ h264bsdInitMbNeighbours(pStorage->mb,
+ pStorage->activeSps->picWidthInMbs,
+ pStorage->picSizeInMbs);
+
+ /* dpb output reordering disabled if
+ * 1) application set noReordering flag
+ * 2) POC type equal to 2
+ * 3) num_reorder_frames in vui equal to 0 */
+ if ( pStorage->noReordering ||
+ pStorage->activeSps->picOrderCntType == 2 ||
+ (pStorage->activeSps->vuiParametersPresentFlag &&
+ pStorage->activeSps->vuiParameters->bitstreamRestrictionFlag &&
+ !pStorage->activeSps->vuiParameters->numReorderFrames) )
+ flag = HANTRO_TRUE;
+ else
+ flag = HANTRO_FALSE;
+
+ tmp = h264bsdResetDpb(pStorage->dpb,
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs,
+ pStorage->activeSps->maxDpbSize,
+ pStorage->activeSps->numRefFrames,
+ pStorage->activeSps->maxFrameNum,
+ flag);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ else if (ppsId != pStorage->activePpsId)
+ {
+ /* sequence parameter set shall not change but before an IDR picture */
+ if (pStorage->pps[ppsId]->seqParameterSetId != pStorage->activeSpsId)
+ {
+ DEBUG(("SEQ PARAM SET CHANGING...\n"));
+ if (isIdr)
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
+ pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
+ pStorage->picSizeInMbs =
+ pStorage->activeSps->picWidthInMbs *
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
+ pStorage->currImage->height =
+ pStorage->activeSps->picHeightInMbs;
+
+ pStorage->pendingActivation = HANTRO_TRUE;
+ }
+ else
+ {
+ DEBUG(("TRYING TO CHANGE SPS IN NON-IDR SLICE\n"));
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ {
+ pStorage->activePpsId = ppsId;
+ pStorage->activePps = pStorage->pps[ppsId];
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdResetStorage
+
+ Functional description:
+ Reset contents of the storage. This should be called before
+ processing of new image is started.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+
+------------------------------------------------------------------------------*/
+
+void h264bsdResetStorage(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ pStorage->slice->numDecodedMbs = 0;
+ pStorage->slice->sliceId = 0;
+
+ for (i = 0; i < pStorage->picSizeInMbs; i++)
+ {
+ pStorage->mb[i].sliceId = 0;
+ pStorage->mb[i].decoded = 0;
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsStartOfPicture
+
+ Functional description:
+ Determine if the decoder is in the start of a picture. This
+ information is needed to decide if h264bsdActivateParamSets and
+ h264bsdCheckGapsInFrameNum functions should be called. Function
+ considers that new picture is starting if no slice headers
+ have been successfully decoded for the current access unit.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE new picture is starting
+ HANTRO_FALSE not starting
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsStartOfPicture(storage_t *pStorage)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ if (pStorage->validSliceInAccessUnit == HANTRO_FALSE)
+ return(HANTRO_TRUE);
+ else
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdIsEndOfPicture
+
+ Functional description:
+ Determine if the decoder is in the end of a picture. This
+ information is needed to determine when deblocking filtering
+ and reference picture marking processes should be performed.
+
+ If the decoder is processing primary slices the return value
+ is determined by checking the value of numDecodedMbs in the
+ storage. On the other hand, if the decoder is processing
+ redundant slices the numDecodedMbs may not contain valid
+ informationa and each macroblock has to be checked separately.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_TRUE end of picture
+ HANTRO_FALSE noup
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdIsEndOfPicture(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+
+/* Code */
+
+ /* primary picture */
+ if (!pStorage->sliceHeader[0].redundantPicCnt)
+ {
+ if (pStorage->slice->numDecodedMbs == pStorage->picSizeInMbs)
+ return(HANTRO_TRUE);
+ }
+ else
+ {
+ for (i = 0, tmp = 0; i < pStorage->picSizeInMbs; i++)
+ tmp += pStorage->mb[i].decoded ? 1 : 0;
+
+ if (tmp == pStorage->picSizeInMbs)
+ return(HANTRO_TRUE);
+ }
+
+ return(HANTRO_FALSE);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdComputeSliceGroupMap
+
+ Functional description:
+ Compute slice group map. Just call h264bsdDecodeSliceGroupMap with
+ appropriate parameters.
+
+ Inputs:
+ pStorage pointer to storage structure
+ sliceGroupChangeCycle
+
+ Outputs:
+ none
+
+ Returns:
+ none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdComputeSliceGroupMap(storage_t *pStorage, u32 sliceGroupChangeCycle)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ h264bsdDecodeSliceGroupMap(pStorage->sliceGroupMap,
+ pStorage->activePps, sliceGroupChangeCycle,
+ pStorage->activeSps->picWidthInMbs,
+ pStorage->activeSps->picHeightInMbs);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdCheckAccessUnitBoundary
+
+ Functional description:
+ Check if next NAL unit starts a new access unit. Following
+ conditions specify start of a new access unit:
+
+ -NAL unit types 6-11, 13-18 (e.g. SPS, PPS)
+
+ following conditions checked only for slice NAL units, values
+ compared to ones obtained from previous slice:
+
+ -NAL unit type differs (slice / IDR slice)
+ -frame_num differs
+ -nal_ref_idc differs and one of the values is 0
+ -POC information differs
+ -both are IDR slices and idr_pic_id differs
+
+ Inputs:
+ strm pointer to stream data structure
+ nuNext pointer to NAL unit structure
+ storage pointer to storage structure
+
+ Outputs:
+ accessUnitBoundaryFlag the result is stored here, TRUE for
+ access unit boundary, FALSE otherwise
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK failure, invalid stream data
+ PARAM_SET_ERROR invalid param set usage
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdCheckAccessUnitBoundary(
+ strmData_t *strm,
+ nalUnit_t *nuNext,
+ storage_t *storage,
+ u32 *accessUnitBoundaryFlag)
+{
+
+/* Variables */
+
+ u32 tmp, ppsId, frameNum, idrPicId, picOrderCntLsb;
+ i32 deltaPicOrderCntBottom, deltaPicOrderCnt[2];
+ seqParamSet_t *sps;
+ picParamSet_t *pps;
+
+/* Code */
+
+ ASSERT(strm);
+ ASSERT(nuNext);
+ ASSERT(storage);
+ ASSERT(storage->sps);
+ ASSERT(storage->pps);
+
+ /* initialize default output to FALSE */
+ *accessUnitBoundaryFlag = HANTRO_FALSE;
+
+ if ( ( (nuNext->nalUnitType > 5) && (nuNext->nalUnitType < 12) ) ||
+ ( (nuNext->nalUnitType > 12) && (nuNext->nalUnitType <= 18) ) )
+ {
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ return(HANTRO_OK);
+ }
+ else if ( nuNext->nalUnitType != NAL_CODED_SLICE &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR )
+ {
+ return(HANTRO_OK);
+ }
+
+ /* check if this is the very first call to this function */
+ if (storage->aub->firstCallFlag)
+ {
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ storage->aub->firstCallFlag = HANTRO_FALSE;
+ }
+
+ /* get picture parameter set id */
+ tmp = h264bsdCheckPpsId(strm, &ppsId);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ /* store sps and pps in separate pointers just to make names shorter */
+ pps = storage->pps[ppsId];
+ if ( pps == NULL || storage->sps[pps->seqParameterSetId] == NULL ||
+ (storage->activeSpsId != MAX_NUM_SEQ_PARAM_SETS &&
+ pps->seqParameterSetId != storage->activeSpsId &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR) )
+ return(PARAM_SET_ERROR);
+ sps = storage->sps[pps->seqParameterSetId];
+
+ if (storage->aub->nuPrev->nalRefIdc != nuNext->nalRefIdc &&
+ (storage->aub->nuPrev->nalRefIdc == 0 || nuNext->nalRefIdc == 0))
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ if ((storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
+ nuNext->nalUnitType != NAL_CODED_SLICE_IDR) ||
+ (storage->aub->nuPrev->nalUnitType != NAL_CODED_SLICE_IDR &&
+ nuNext->nalUnitType == NAL_CODED_SLICE_IDR))
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ tmp = h264bsdCheckFrameNum(strm, sps->maxFrameNum, &frameNum);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->prevFrameNum != frameNum)
+ {
+ storage->aub->prevFrameNum = frameNum;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (nuNext->nalUnitType == NAL_CODED_SLICE_IDR)
+ {
+ tmp = h264bsdCheckIdrPicId(strm, sps->maxFrameNum, nuNext->nalUnitType,
+ &idrPicId);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
+ storage->aub->prevIdrPicId != idrPicId)
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+
+ storage->aub->prevIdrPicId = idrPicId;
+ }
+
+ if (sps->picOrderCntType == 0)
+ {
+ tmp = h264bsdCheckPicOrderCntLsb(strm, sps, nuNext->nalUnitType,
+ &picOrderCntLsb);
+ if (tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (storage->aub->prevPicOrderCntLsb != picOrderCntLsb)
+ {
+ storage->aub->prevPicOrderCntLsb = picOrderCntLsb;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (pps->picOrderPresentFlag)
+ {
+ tmp = h264bsdCheckDeltaPicOrderCntBottom(strm, sps,
+ nuNext->nalUnitType, &deltaPicOrderCntBottom);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (storage->aub->prevDeltaPicOrderCntBottom !=
+ deltaPicOrderCntBottom)
+ {
+ storage->aub->prevDeltaPicOrderCntBottom =
+ deltaPicOrderCntBottom;
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+ }
+ }
+ else if (sps->picOrderCntType == 1 && !sps->deltaPicOrderAlwaysZeroFlag)
+ {
+ tmp = h264bsdCheckDeltaPicOrderCnt(strm, sps, nuNext->nalUnitType,
+ pps->picOrderPresentFlag, deltaPicOrderCnt);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (storage->aub->prevDeltaPicOrderCnt[0] != deltaPicOrderCnt[0])
+ {
+ storage->aub->prevDeltaPicOrderCnt[0] = deltaPicOrderCnt[0];
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+
+ if (pps->picOrderPresentFlag)
+ if (storage->aub->prevDeltaPicOrderCnt[1] != deltaPicOrderCnt[1])
+ {
+ storage->aub->prevDeltaPicOrderCnt[1] = deltaPicOrderCnt[1];
+ *accessUnitBoundaryFlag = HANTRO_TRUE;
+ }
+ }
+
+ *storage->aub->nuPrev = *nuNext;
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: CheckPps
+
+ Functional description:
+ Check picture parameter set. Contents of the picture parameter
+ set information that depends on the image dimensions is checked
+ against the dimensions in the sps.
+
+ Inputs:
+ pps pointer to picture paramter set
+ sps pointer to sequence parameter set
+
+ Outputs:
+ none
+
+ Returns:
+ HANTRO_OK everything ok
+ HANTRO_NOK invalid data in picture parameter set
+
+------------------------------------------------------------------------------*/
+u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps)
+{
+
+ u32 i;
+ u32 picSize;
+
+ picSize = sps->picWidthInMbs * sps->picHeightInMbs;
+
+ /* check slice group params */
+ if (pps->numSliceGroups > 1)
+ {
+ if (pps->sliceGroupMapType == 0)
+ {
+ ASSERT(pps->runLength);
+ for (i = 0; i < pps->numSliceGroups; i++)
+ {
+ if (pps->runLength[i] > picSize)
+ return(HANTRO_NOK);
+ }
+ }
+ else if (pps->sliceGroupMapType == 2)
+ {
+ ASSERT(pps->topLeft);
+ ASSERT(pps->bottomRight);
+ for (i = 0; i < pps->numSliceGroups-1; i++)
+ {
+ if (pps->topLeft[i] > pps->bottomRight[i] ||
+ pps->bottomRight[i] >= picSize)
+ return(HANTRO_NOK);
+
+ if ( (pps->topLeft[i] % sps->picWidthInMbs) >
+ (pps->bottomRight[i] % sps->picWidthInMbs) )
+ return(HANTRO_NOK);
+ }
+ }
+ else if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
+ {
+ if (pps->sliceGroupChangeRate > picSize)
+ return(HANTRO_NOK);
+ }
+ else if (pps->sliceGroupMapType == 6 &&
+ pps->picSizeInMapUnits < picSize)
+ return(HANTRO_NOK);
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdValidParamSets
+
+ Functional description:
+ Check if any valid SPS/PPS combination exists in the storage.
+ Function tries each PPS in the buffer and checks if corresponding
+ SPS exists and calls CheckPps to determine if the PPS conforms
+ to image dimensions of the SPS.
+
+ Inputs:
+ pStorage pointer to storage structure
+
+ Outputs:
+ HANTRO_OK there is at least one valid combination
+ HANTRO_NOK no valid combinations found
+
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdValidParamSets(storage_t *pStorage)
+{
+
+/* Variables */
+
+ u32 i;
+
+/* Code */
+
+ ASSERT(pStorage);
+
+ for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
+ {
+ if ( pStorage->pps[i] &&
+ pStorage->sps[pStorage->pps[i]->seqParameterSetId] &&
+ CheckPps(pStorage->pps[i],
+ pStorage->sps[pStorage->pps[i]->seqParameterSetId]) ==
+ HANTRO_OK)
+ {
+ return(HANTRO_OK);
+ }
+ }
+
+ return(HANTRO_NOK);
+
+}
+