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