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