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
65static 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
86void 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
126u32 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
209u32 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
296u32 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
440void 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
485u32 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
527u32 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
575void 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
625u32 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------------------------------------------------------------------------------*/
794u32 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
862u32 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