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