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 
h264bsdInitStorage(storage_t * pStorage)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 
h264bsdStoreSeqParamSet(storage_t * pStorage,seqParamSet_t * pSeqParamSet)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 
h264bsdStorePicParamSet(storage_t * pStorage,picParamSet_t * pPicParamSet)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 
h264bsdActivateParamSets(storage_t * pStorage,u32 ppsId,u32 isIdr)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 
h264bsdResetStorage(storage_t * pStorage)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 
h264bsdIsStartOfPicture(storage_t * pStorage)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 
h264bsdIsEndOfPicture(storage_t * pStorage)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 
h264bsdComputeSliceGroupMap(storage_t * pStorage,u32 sliceGroupChangeCycle)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 
h264bsdCheckAccessUnitBoundary(strmData_t * strm,nalUnit_t * nuNext,storage_t * storage,u32 * accessUnitBoundaryFlag)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 ------------------------------------------------------------------------------*/
CheckPps(picParamSet_t * pps,seqParamSet_t * sps)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 
h264bsdValidParamSets(storage_t * pStorage)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