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