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
69static 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
90void 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
130u32 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
213u32 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
300u32 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
458void 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
503u32 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
545u32 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
593void 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
643u32 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------------------------------------------------------------------------------*/
812u32 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
880u32 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