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 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 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 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 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 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 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 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 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 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 ------------------------------------------------------------------------------*/ 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 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