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