Home | History | Annotate | Download | only in source
      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           h264bsdInitStorage
     27           h264bsdStoreSeqParamSet
     28           h264bsdStorePicParamSet
     29           h264bsdActivateParamSets
     30           h264bsdResetStorage
     31           h264bsdIsStartOfPicture
     32           h264bsdIsEndOfPicture
     33           h264bsdComputeSliceGroupMap
     34           h264bsdCheckAccessUnitBoundary
     35           CheckPps
     36           h264bsdValidParamSets
     37 
     38 ------------------------------------------------------------------------------*/
     39 
     40 /*------------------------------------------------------------------------------
     41     1. Include headers
     42 ------------------------------------------------------------------------------*/
     43 
     44 #include "h264bsd_storage.h"
     45 #include "h264bsd_util.h"
     46 #include "h264bsd_neighbour.h"
     47 #include "h264bsd_slice_group_map.h"
     48 #include "h264bsd_dpb.h"
     49 #include "h264bsd_nal_unit.h"
     50 #include "h264bsd_slice_header.h"
     51 #include "h264bsd_seq_param_set.h"
     52 
     53 /*------------------------------------------------------------------------------
     54     2. External compiler flags
     55 --------------------------------------------------------------------------------
     56 
     57 --------------------------------------------------------------------------------
     58     3. Module defines
     59 ------------------------------------------------------------------------------*/
     60 
     61 #ifndef UINT32_MAX
     62 #define UINT32_MAX       (4294967295U)
     63 #endif
     64 
     65 /*------------------------------------------------------------------------------
     66     4. Local function prototypes
     67 ------------------------------------------------------------------------------*/
     68 
     69 static u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps);
     70 
     71 /*------------------------------------------------------------------------------
     72 
     73     Function name: h264bsdInitStorage
     74 
     75         Functional description:
     76             Initialize storage structure. Sets contents of the storage to '0'
     77             except for the active parameter set ids, which are initialized
     78             to invalid values.
     79 
     80         Inputs:
     81 
     82         Outputs:
     83             pStorage    initialized data stored here
     84 
     85         Returns:
     86             none
     87 
     88 ------------------------------------------------------------------------------*/
     89 
     90 void h264bsdInitStorage(storage_t *pStorage)
     91 {
     92 
     93 /* Variables */
     94 
     95 /* Code */
     96 
     97     ASSERT(pStorage);
     98 
     99     H264SwDecMemset(pStorage, 0, sizeof(storage_t));
    100 
    101     pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
    102     pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
    103 
    104     pStorage->aub->firstCallFlag = HANTRO_TRUE;
    105 }
    106 
    107 /*------------------------------------------------------------------------------
    108 
    109     Function: h264bsdStoreSeqParamSet
    110 
    111         Functional description:
    112             Store sequence parameter set into the storage. If active SPS is
    113             overwritten -> check if contents changes and if it does, set
    114             parameters to force reactivation of parameter sets
    115 
    116         Inputs:
    117             pStorage        pointer to storage structure
    118             pSeqParamSet    pointer to param set to be stored
    119 
    120         Outputs:
    121             none
    122 
    123         Returns:
    124             HANTRO_OK                success
    125             MEMORY_ALLOCATION_ERROR  failure in memory allocation
    126 
    127 
    128 ------------------------------------------------------------------------------*/
    129 
    130 u32 h264bsdStoreSeqParamSet(storage_t *pStorage, seqParamSet_t *pSeqParamSet)
    131 {
    132 
    133 /* Variables */
    134 
    135     u32 id;
    136 
    137 /* Code */
    138 
    139     ASSERT(pStorage);
    140     ASSERT(pSeqParamSet);
    141     ASSERT(pSeqParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
    142 
    143     id = pSeqParamSet->seqParameterSetId;
    144 
    145     /* seq parameter set with id not used before -> allocate memory */
    146     if (pStorage->sps[id] == NULL)
    147     {
    148         ALLOCATE(pStorage->sps[id], 1, seqParamSet_t);
    149         if (pStorage->sps[id] == NULL)
    150             return(MEMORY_ALLOCATION_ERROR);
    151     }
    152     /* sequence parameter set with id equal to id of active sps */
    153     else if (id == pStorage->activeSpsId)
    154     {
    155         /* if seq parameter set contents changes
    156          *    -> overwrite and re-activate when next IDR picture decoded
    157          *    ids of active param sets set to invalid values to force
    158          *    re-activation. Memories allocated for old sps freed
    159          * otherwise free memeries allocated for just decoded sps and
    160          * continue */
    161         if (h264bsdCompareSeqParamSets(pSeqParamSet, pStorage->activeSps) != 0)
    162         {
    163             FREE(pStorage->sps[id]->offsetForRefFrame);
    164             FREE(pStorage->sps[id]->vuiParameters);
    165             pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS + 1;
    166             pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
    167             pStorage->activeSps = NULL;
    168             pStorage->activePps = NULL;
    169         }
    170         else
    171         {
    172             FREE(pSeqParamSet->offsetForRefFrame);
    173             FREE(pSeqParamSet->vuiParameters);
    174             return(HANTRO_OK);
    175         }
    176     }
    177     /* overwrite seq param set other than active one -> free memories
    178      * allocated for old param set */
    179     else
    180     {
    181         FREE(pStorage->sps[id]->offsetForRefFrame);
    182         FREE(pStorage->sps[id]->vuiParameters);
    183     }
    184 
    185     *pStorage->sps[id] = *pSeqParamSet;
    186 
    187     return(HANTRO_OK);
    188 
    189 }
    190 
    191 /*------------------------------------------------------------------------------
    192 
    193     Function: h264bsdStorePicParamSet
    194 
    195         Functional description:
    196             Store picture parameter set into the storage. If active PPS is
    197             overwritten -> check if active SPS changes and if it does -> set
    198             parameters to force reactivation of parameter sets
    199 
    200         Inputs:
    201             pStorage        pointer to storage structure
    202             pPicParamSet    pointer to param set to be stored
    203 
    204         Outputs:
    205             none
    206 
    207         Returns:
    208             HANTRO_OK                success
    209             MEMORY_ALLOCATION_ERROR  failure in memory allocation
    210 
    211 ------------------------------------------------------------------------------*/
    212 
    213 u32 h264bsdStorePicParamSet(storage_t *pStorage, picParamSet_t *pPicParamSet)
    214 {
    215 
    216 /* Variables */
    217 
    218     u32 id;
    219 
    220 /* Code */
    221 
    222     ASSERT(pStorage);
    223     ASSERT(pPicParamSet);
    224     ASSERT(pPicParamSet->picParameterSetId < MAX_NUM_PIC_PARAM_SETS);
    225     ASSERT(pPicParamSet->seqParameterSetId < MAX_NUM_SEQ_PARAM_SETS);
    226 
    227     id = pPicParamSet->picParameterSetId;
    228 
    229     /* pic parameter set with id not used before -> allocate memory */
    230     if (pStorage->pps[id] == NULL)
    231     {
    232         ALLOCATE(pStorage->pps[id], 1, picParamSet_t);
    233         if (pStorage->pps[id] == NULL)
    234             return(MEMORY_ALLOCATION_ERROR);
    235     }
    236     /* picture parameter set with id equal to id of active pps */
    237     else if (id == pStorage->activePpsId)
    238     {
    239         /* check whether seq param set changes, force re-activation of
    240          * param set if it does. Set activeSpsId to invalid value to
    241          * accomplish this */
    242         if (pPicParamSet->seqParameterSetId != pStorage->activeSpsId)
    243         {
    244             pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS + 1;
    245         }
    246         /* free memories allocated for old param set */
    247         FREE(pStorage->pps[id]->runLength);
    248         FREE(pStorage->pps[id]->topLeft);
    249         FREE(pStorage->pps[id]->bottomRight);
    250         FREE(pStorage->pps[id]->sliceGroupId);
    251     }
    252     /* overwrite pic param set other than active one -> free memories
    253      * allocated for old param set */
    254     else
    255     {
    256         FREE(pStorage->pps[id]->runLength);
    257         FREE(pStorage->pps[id]->topLeft);
    258         FREE(pStorage->pps[id]->bottomRight);
    259         FREE(pStorage->pps[id]->sliceGroupId);
    260     }
    261 
    262     *pStorage->pps[id] = *pPicParamSet;
    263 
    264     return(HANTRO_OK);
    265 
    266 }
    267 
    268 /*------------------------------------------------------------------------------
    269 
    270     Function: h264bsdActivateParamSets
    271 
    272         Functional description:
    273             Activate certain SPS/PPS combination. This function shall be
    274             called in the beginning of each picture. Picture parameter set
    275             can be changed as wanted, but sequence parameter set may only be
    276             changed when the starting picture is an IDR picture.
    277 
    278             When new SPS is activated the function allocates memory for
    279             macroblock storages and slice group map and (re-)initializes the
    280             decoded picture buffer. If this is not the first activation the old
    281             allocations are freed and FreeDpb called before new allocations.
    282 
    283         Inputs:
    284             pStorage        pointer to storage data structure
    285             ppsId           identifies the PPS to be activated, SPS id obtained
    286                             from the PPS
    287             isIdr           flag to indicate if the picture is an IDR picture
    288 
    289         Outputs:
    290             none
    291 
    292         Returns:
    293             HANTRO_OK       success
    294             HANTRO_NOK      non-existing or invalid param set combination,
    295                             trying to change SPS with non-IDR picture
    296             MEMORY_ALLOCATION_ERROR     failure in memory allocation
    297 
    298 ------------------------------------------------------------------------------*/
    299 
    300 u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr)
    301 {
    302 
    303 /* Variables */
    304 
    305     u32 tmp;
    306     u32 flag;
    307 
    308 /* Code */
    309 
    310     ASSERT(pStorage);
    311     ASSERT(ppsId < MAX_NUM_PIC_PARAM_SETS);
    312 
    313     /* check that pps and corresponding sps exist */
    314     if ( (pStorage->pps[ppsId] == NULL) ||
    315          (pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId] == NULL) )
    316     {
    317         return(HANTRO_NOK);
    318     }
    319 
    320     /* check that pps parameters do not violate picture size constraints */
    321     tmp = CheckPps(pStorage->pps[ppsId],
    322                    pStorage->sps[pStorage->pps[ppsId]->seqParameterSetId]);
    323     if (tmp != HANTRO_OK)
    324         return(tmp);
    325 
    326     /* first activation part1 */
    327     if (pStorage->activePpsId == MAX_NUM_PIC_PARAM_SETS)
    328     {
    329         pStorage->activePpsId = ppsId;
    330         pStorage->activePps = pStorage->pps[ppsId];
    331         pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
    332         pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
    333 
    334         /* report error before multiplication to prevent integer overflow */
    335         if (pStorage->activeSps->picWidthInMbs == 0)
    336         {
    337             pStorage->picSizeInMbs = 0;
    338         }
    339         else if (pStorage->activeSps->picHeightInMbs >
    340                  UINT32_MAX / pStorage->activeSps->picWidthInMbs)
    341         {
    342             return(MEMORY_ALLOCATION_ERROR);
    343         }
    344         else
    345         {
    346             pStorage->picSizeInMbs =
    347                 pStorage->activeSps->picWidthInMbs *
    348                 pStorage->activeSps->picHeightInMbs;
    349         }
    350 
    351         pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
    352         pStorage->currImage->height = pStorage->activeSps->picHeightInMbs;
    353 
    354         pStorage->pendingActivation = HANTRO_TRUE;
    355     }
    356     /* first activation part2 */
    357     else if (pStorage->pendingActivation)
    358     {
    359         pStorage->pendingActivation = HANTRO_FALSE;
    360 
    361         FREE(pStorage->mb);
    362         FREE(pStorage->sliceGroupMap);
    363 
    364         ALLOCATE(pStorage->mb, pStorage->picSizeInMbs, mbStorage_t);
    365         ALLOCATE(pStorage->sliceGroupMap, pStorage->picSizeInMbs, u32);
    366         if (pStorage->mb == NULL || pStorage->sliceGroupMap == NULL)
    367             return(MEMORY_ALLOCATION_ERROR);
    368 
    369         H264SwDecMemset(pStorage->mb, 0,
    370             pStorage->picSizeInMbs * sizeof(mbStorage_t));
    371 
    372         h264bsdInitMbNeighbours(pStorage->mb,
    373             pStorage->activeSps->picWidthInMbs,
    374             pStorage->picSizeInMbs);
    375 
    376         /* dpb output reordering disabled if
    377          * 1) application set noReordering flag
    378          * 2) POC type equal to 2
    379          * 3) num_reorder_frames in vui equal to 0 */
    380         if ( pStorage->noReordering ||
    381              pStorage->activeSps->picOrderCntType == 2 ||
    382              (pStorage->activeSps->vuiParametersPresentFlag &&
    383               pStorage->activeSps->vuiParameters->bitstreamRestrictionFlag &&
    384               !pStorage->activeSps->vuiParameters->numReorderFrames) )
    385             flag = HANTRO_TRUE;
    386         else
    387             flag = HANTRO_FALSE;
    388 
    389         tmp = h264bsdResetDpb(pStorage->dpb,
    390             pStorage->activeSps->picWidthInMbs *
    391             pStorage->activeSps->picHeightInMbs,
    392             pStorage->activeSps->maxDpbSize,
    393             pStorage->activeSps->numRefFrames,
    394             pStorage->activeSps->maxFrameNum,
    395             flag);
    396         if (tmp != HANTRO_OK)
    397             return(tmp);
    398     }
    399     else if (ppsId != pStorage->activePpsId)
    400     {
    401         /* sequence parameter set shall not change but before an IDR picture */
    402         if (pStorage->pps[ppsId]->seqParameterSetId != pStorage->activeSpsId)
    403         {
    404             DEBUG(("SEQ PARAM SET CHANGING...\n"));
    405             if (isIdr)
    406             {
    407                 pStorage->activePpsId = ppsId;
    408                 pStorage->activePps = pStorage->pps[ppsId];
    409                 pStorage->activeSpsId = pStorage->activePps->seqParameterSetId;
    410                 pStorage->activeSps = pStorage->sps[pStorage->activeSpsId];
    411                 pStorage->picSizeInMbs =
    412                     pStorage->activeSps->picWidthInMbs *
    413                     pStorage->activeSps->picHeightInMbs;
    414 
    415                 pStorage->currImage->width = pStorage->activeSps->picWidthInMbs;
    416                 pStorage->currImage->height =
    417                     pStorage->activeSps->picHeightInMbs;
    418 
    419                 pStorage->pendingActivation = HANTRO_TRUE;
    420             }
    421             else
    422             {
    423                 DEBUG(("TRYING TO CHANGE SPS IN NON-IDR SLICE\n"));
    424                 return(HANTRO_NOK);
    425             }
    426         }
    427         else
    428         {
    429             pStorage->activePpsId = ppsId;
    430             pStorage->activePps = pStorage->pps[ppsId];
    431         }
    432     }
    433 
    434     return(HANTRO_OK);
    435 
    436 }
    437 
    438 /*------------------------------------------------------------------------------
    439 
    440     Function: h264bsdResetStorage
    441 
    442         Functional description:
    443             Reset contents of the storage. This should be called before
    444             processing of new image is started.
    445 
    446         Inputs:
    447             pStorage    pointer to storage structure
    448 
    449         Outputs:
    450             none
    451 
    452         Returns:
    453             none
    454 
    455 
    456 ------------------------------------------------------------------------------*/
    457 
    458 void h264bsdResetStorage(storage_t *pStorage)
    459 {
    460 
    461 /* Variables */
    462 
    463     u32 i;
    464 
    465 /* Code */
    466 
    467     ASSERT(pStorage);
    468 
    469     pStorage->slice->numDecodedMbs = 0;
    470     pStorage->slice->sliceId = 0;
    471 
    472     for (i = 0; i < pStorage->picSizeInMbs; i++)
    473     {
    474         pStorage->mb[i].sliceId = 0;
    475         pStorage->mb[i].decoded = 0;
    476     }
    477 
    478 }
    479 
    480 /*------------------------------------------------------------------------------
    481 
    482     Function: h264bsdIsStartOfPicture
    483 
    484         Functional description:
    485             Determine if the decoder is in the start of a picture. This
    486             information is needed to decide if h264bsdActivateParamSets and
    487             h264bsdCheckGapsInFrameNum functions should be called. Function
    488             considers that new picture is starting if no slice headers
    489             have been successfully decoded for the current access unit.
    490 
    491         Inputs:
    492             pStorage    pointer to storage structure
    493 
    494         Outputs:
    495             none
    496 
    497         Returns:
    498             HANTRO_TRUE        new picture is starting
    499             HANTRO_FALSE       not starting
    500 
    501 ------------------------------------------------------------------------------*/
    502 
    503 u32 h264bsdIsStartOfPicture(storage_t *pStorage)
    504 {
    505 
    506 /* Variables */
    507 
    508 
    509 /* Code */
    510 
    511     if (pStorage->validSliceInAccessUnit == HANTRO_FALSE)
    512         return(HANTRO_TRUE);
    513     else
    514         return(HANTRO_FALSE);
    515 
    516 }
    517 
    518 /*------------------------------------------------------------------------------
    519 
    520     Function: h264bsdIsEndOfPicture
    521 
    522         Functional description:
    523             Determine if the decoder is in the end of a picture. This
    524             information is needed to determine when deblocking filtering
    525             and reference picture marking processes should be performed.
    526 
    527             If the decoder is processing primary slices the return value
    528             is determined by checking the value of numDecodedMbs in the
    529             storage. On the other hand, if the decoder is processing
    530             redundant slices the numDecodedMbs may not contain valid
    531             informationa and each macroblock has to be checked separately.
    532 
    533         Inputs:
    534             pStorage    pointer to storage structure
    535 
    536         Outputs:
    537             none
    538 
    539         Returns:
    540             HANTRO_TRUE        end of picture
    541             HANTRO_FALSE       noup
    542 
    543 ------------------------------------------------------------------------------*/
    544 
    545 u32 h264bsdIsEndOfPicture(storage_t *pStorage)
    546 {
    547 
    548 /* Variables */
    549 
    550     u32 i, tmp;
    551 
    552 /* Code */
    553 
    554     /* primary picture */
    555     if (!pStorage->sliceHeader[0].redundantPicCnt)
    556     {
    557         if (pStorage->slice->numDecodedMbs == pStorage->picSizeInMbs)
    558             return(HANTRO_TRUE);
    559     }
    560     else
    561     {
    562         for (i = 0, tmp = 0; i < pStorage->picSizeInMbs; i++)
    563             tmp += pStorage->mb[i].decoded ? 1 : 0;
    564 
    565         if (tmp == pStorage->picSizeInMbs)
    566             return(HANTRO_TRUE);
    567     }
    568 
    569     return(HANTRO_FALSE);
    570 
    571 }
    572 
    573 /*------------------------------------------------------------------------------
    574 
    575     Function: h264bsdComputeSliceGroupMap
    576 
    577         Functional description:
    578             Compute slice group map. Just call h264bsdDecodeSliceGroupMap with
    579             appropriate parameters.
    580 
    581         Inputs:
    582             pStorage                pointer to storage structure
    583             sliceGroupChangeCycle
    584 
    585         Outputs:
    586             none
    587 
    588         Returns:
    589             none
    590 
    591 ------------------------------------------------------------------------------*/
    592 
    593 void h264bsdComputeSliceGroupMap(storage_t *pStorage, u32 sliceGroupChangeCycle)
    594 {
    595 
    596 /* Variables */
    597 
    598 
    599 /* Code */
    600 
    601     h264bsdDecodeSliceGroupMap(pStorage->sliceGroupMap,
    602                         pStorage->activePps, sliceGroupChangeCycle,
    603                         pStorage->activeSps->picWidthInMbs,
    604                         pStorage->activeSps->picHeightInMbs);
    605 
    606 }
    607 
    608 /*------------------------------------------------------------------------------
    609 
    610     Function: h264bsdCheckAccessUnitBoundary
    611 
    612         Functional description:
    613             Check if next NAL unit starts a new access unit. Following
    614             conditions specify start of a new access unit:
    615 
    616                 -NAL unit types 6-11, 13-18 (e.g. SPS, PPS)
    617 
    618            following conditions checked only for slice NAL units, values
    619            compared to ones obtained from previous slice:
    620 
    621                 -NAL unit type differs (slice / IDR slice)
    622                 -frame_num differs
    623                 -nal_ref_idc differs and one of the values is 0
    624                 -POC information differs
    625                 -both are IDR slices and idr_pic_id differs
    626 
    627         Inputs:
    628             strm        pointer to stream data structure
    629             nuNext      pointer to NAL unit structure
    630             storage     pointer to storage structure
    631 
    632         Outputs:
    633             accessUnitBoundaryFlag  the result is stored here, TRUE for
    634                                     access unit boundary, FALSE otherwise
    635 
    636         Returns:
    637             HANTRO_OK           success
    638             HANTRO_NOK          failure, invalid stream data
    639             PARAM_SET_ERROR     invalid param set usage
    640 
    641 ------------------------------------------------------------------------------*/
    642 
    643 u32 h264bsdCheckAccessUnitBoundary(
    644   strmData_t *strm,
    645   nalUnit_t *nuNext,
    646   storage_t *storage,
    647   u32 *accessUnitBoundaryFlag)
    648 {
    649 
    650 /* Variables */
    651 
    652     u32 tmp, ppsId, frameNum, idrPicId, picOrderCntLsb;
    653     i32 deltaPicOrderCntBottom, deltaPicOrderCnt[2];
    654     seqParamSet_t *sps;
    655     picParamSet_t *pps;
    656 
    657 /* Code */
    658 
    659     ASSERT(strm);
    660     ASSERT(nuNext);
    661     ASSERT(storage);
    662     ASSERT(storage->sps);
    663     ASSERT(storage->pps);
    664 
    665     /* initialize default output to FALSE */
    666     *accessUnitBoundaryFlag = HANTRO_FALSE;
    667 
    668     if ( ( (nuNext->nalUnitType > 5) && (nuNext->nalUnitType < 12) ) ||
    669          ( (nuNext->nalUnitType > 12) && (nuNext->nalUnitType <= 18) ) )
    670     {
    671         *accessUnitBoundaryFlag = HANTRO_TRUE;
    672         return(HANTRO_OK);
    673     }
    674     else if ( nuNext->nalUnitType != NAL_CODED_SLICE &&
    675               nuNext->nalUnitType != NAL_CODED_SLICE_IDR )
    676     {
    677         return(HANTRO_OK);
    678     }
    679 
    680     /* check if this is the very first call to this function */
    681     if (storage->aub->firstCallFlag)
    682     {
    683         *accessUnitBoundaryFlag = HANTRO_TRUE;
    684         storage->aub->firstCallFlag = HANTRO_FALSE;
    685     }
    686 
    687     /* get picture parameter set id */
    688     tmp = h264bsdCheckPpsId(strm, &ppsId);
    689     if (tmp != HANTRO_OK)
    690         return(tmp);
    691 
    692     /* store sps and pps in separate pointers just to make names shorter */
    693     pps = storage->pps[ppsId];
    694     if ( pps == NULL || storage->sps[pps->seqParameterSetId] == NULL  ||
    695          (storage->activeSpsId != MAX_NUM_SEQ_PARAM_SETS &&
    696           pps->seqParameterSetId != storage->activeSpsId &&
    697           nuNext->nalUnitType != NAL_CODED_SLICE_IDR) )
    698         return(PARAM_SET_ERROR);
    699     sps = storage->sps[pps->seqParameterSetId];
    700 
    701     if (storage->aub->nuPrev->nalRefIdc != nuNext->nalRefIdc &&
    702       (storage->aub->nuPrev->nalRefIdc == 0 || nuNext->nalRefIdc == 0))
    703         *accessUnitBoundaryFlag = HANTRO_TRUE;
    704 
    705     if ((storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
    706           nuNext->nalUnitType != NAL_CODED_SLICE_IDR) ||
    707       (storage->aub->nuPrev->nalUnitType != NAL_CODED_SLICE_IDR &&
    708        nuNext->nalUnitType == NAL_CODED_SLICE_IDR))
    709         *accessUnitBoundaryFlag = HANTRO_TRUE;
    710 
    711     tmp = h264bsdCheckFrameNum(strm, sps->maxFrameNum, &frameNum);
    712     if (tmp != HANTRO_OK)
    713         return(HANTRO_NOK);
    714 
    715     if (storage->aub->prevFrameNum != frameNum)
    716     {
    717         storage->aub->prevFrameNum = frameNum;
    718         *accessUnitBoundaryFlag = HANTRO_TRUE;
    719     }
    720 
    721     if (nuNext->nalUnitType == NAL_CODED_SLICE_IDR)
    722     {
    723         tmp = h264bsdCheckIdrPicId(strm, sps->maxFrameNum, nuNext->nalUnitType,
    724           &idrPicId);
    725         if (tmp != HANTRO_OK)
    726             return(HANTRO_NOK);
    727 
    728         if (storage->aub->nuPrev->nalUnitType == NAL_CODED_SLICE_IDR &&
    729           storage->aub->prevIdrPicId != idrPicId)
    730             *accessUnitBoundaryFlag = HANTRO_TRUE;
    731 
    732         storage->aub->prevIdrPicId = idrPicId;
    733     }
    734 
    735     if (sps->picOrderCntType == 0)
    736     {
    737         tmp = h264bsdCheckPicOrderCntLsb(strm, sps, nuNext->nalUnitType,
    738           &picOrderCntLsb);
    739         if (tmp != HANTRO_OK)
    740             return(HANTRO_NOK);
    741 
    742         if (storage->aub->prevPicOrderCntLsb != picOrderCntLsb)
    743         {
    744             storage->aub->prevPicOrderCntLsb = picOrderCntLsb;
    745             *accessUnitBoundaryFlag = HANTRO_TRUE;
    746         }
    747 
    748         if (pps->picOrderPresentFlag)
    749         {
    750             tmp = h264bsdCheckDeltaPicOrderCntBottom(strm, sps,
    751                 nuNext->nalUnitType, &deltaPicOrderCntBottom);
    752             if (tmp != HANTRO_OK)
    753                 return(tmp);
    754 
    755             if (storage->aub->prevDeltaPicOrderCntBottom !=
    756                 deltaPicOrderCntBottom)
    757             {
    758                 storage->aub->prevDeltaPicOrderCntBottom =
    759                     deltaPicOrderCntBottom;
    760                 *accessUnitBoundaryFlag = HANTRO_TRUE;
    761             }
    762         }
    763     }
    764     else if (sps->picOrderCntType == 1 && !sps->deltaPicOrderAlwaysZeroFlag)
    765     {
    766         tmp = h264bsdCheckDeltaPicOrderCnt(strm, sps, nuNext->nalUnitType,
    767           pps->picOrderPresentFlag, deltaPicOrderCnt);
    768         if (tmp != HANTRO_OK)
    769             return(tmp);
    770 
    771         if (storage->aub->prevDeltaPicOrderCnt[0] != deltaPicOrderCnt[0])
    772         {
    773             storage->aub->prevDeltaPicOrderCnt[0] = deltaPicOrderCnt[0];
    774             *accessUnitBoundaryFlag = HANTRO_TRUE;
    775         }
    776 
    777         if (pps->picOrderPresentFlag)
    778             if (storage->aub->prevDeltaPicOrderCnt[1] != deltaPicOrderCnt[1])
    779             {
    780                 storage->aub->prevDeltaPicOrderCnt[1] = deltaPicOrderCnt[1];
    781                 *accessUnitBoundaryFlag = HANTRO_TRUE;
    782             }
    783     }
    784 
    785     *storage->aub->nuPrev = *nuNext;
    786 
    787     return(HANTRO_OK);
    788 
    789 }
    790 
    791 /*------------------------------------------------------------------------------
    792 
    793     Function: CheckPps
    794 
    795         Functional description:
    796             Check picture parameter set. Contents of the picture parameter
    797             set information that depends on the image dimensions is checked
    798             against the dimensions in the sps.
    799 
    800         Inputs:
    801             pps     pointer to picture paramter set
    802             sps     pointer to sequence parameter set
    803 
    804         Outputs:
    805             none
    806 
    807         Returns:
    808             HANTRO_OK      everything ok
    809             HANTRO_NOK     invalid data in picture parameter set
    810 
    811 ------------------------------------------------------------------------------*/
    812 u32 CheckPps(picParamSet_t *pps, seqParamSet_t *sps)
    813 {
    814 
    815     u32 i;
    816     u32 picSize;
    817 
    818     picSize = sps->picWidthInMbs * sps->picHeightInMbs;
    819 
    820     /* check slice group params */
    821     if (pps->numSliceGroups > 1)
    822     {
    823         if (pps->sliceGroupMapType == 0)
    824         {
    825             ASSERT(pps->runLength);
    826             for (i = 0; i < pps->numSliceGroups; i++)
    827             {
    828                 if (pps->runLength[i] > picSize)
    829                     return(HANTRO_NOK);
    830             }
    831         }
    832         else if (pps->sliceGroupMapType == 2)
    833         {
    834             ASSERT(pps->topLeft);
    835             ASSERT(pps->bottomRight);
    836             for (i = 0; i < pps->numSliceGroups-1; i++)
    837             {
    838                 if (pps->topLeft[i] > pps->bottomRight[i] ||
    839                     pps->bottomRight[i] >= picSize)
    840                     return(HANTRO_NOK);
    841 
    842                 if ( (pps->topLeft[i] % sps->picWidthInMbs) >
    843                      (pps->bottomRight[i] % sps->picWidthInMbs) )
    844                     return(HANTRO_NOK);
    845             }
    846         }
    847         else if (pps->sliceGroupMapType > 2 && pps->sliceGroupMapType < 6)
    848         {
    849             if (pps->sliceGroupChangeRate > picSize)
    850                 return(HANTRO_NOK);
    851         }
    852         else if (pps->sliceGroupMapType == 6 &&
    853                  pps->picSizeInMapUnits < picSize)
    854             return(HANTRO_NOK);
    855     }
    856 
    857     return(HANTRO_OK);
    858 }
    859 
    860 /*------------------------------------------------------------------------------
    861 
    862     Function: h264bsdValidParamSets
    863 
    864         Functional description:
    865             Check if any valid SPS/PPS combination exists in the storage.
    866             Function tries each PPS in the buffer and checks if corresponding
    867             SPS exists and calls CheckPps to determine if the PPS conforms
    868             to image dimensions of the SPS.
    869 
    870         Inputs:
    871             pStorage    pointer to storage structure
    872 
    873         Outputs:
    874             HANTRO_OK   there is at least one valid combination
    875             HANTRO_NOK  no valid combinations found
    876 
    877 
    878 ------------------------------------------------------------------------------*/
    879 
    880 u32 h264bsdValidParamSets(storage_t *pStorage)
    881 {
    882 
    883 /* Variables */
    884 
    885     u32 i;
    886 
    887 /* Code */
    888 
    889     ASSERT(pStorage);
    890 
    891     for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
    892     {
    893         if ( pStorage->pps[i] &&
    894              pStorage->sps[pStorage->pps[i]->seqParameterSetId] &&
    895              CheckPps(pStorage->pps[i],
    896                       pStorage->sps[pStorage->pps[i]->seqParameterSetId]) ==
    897                  HANTRO_OK)
    898         {
    899             return(HANTRO_OK);
    900         }
    901     }
    902 
    903     return(HANTRO_NOK);
    904 
    905 }
    906 
    907