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 h264bsdInit 27 h264bsdDecode 28 h264bsdShutdown 29 h264bsdCurrentImage 30 h264bsdNextOutputPicture 31 h264bsdPicWidth 32 h264bsdPicHeight 33 h264bsdFlushBuffer 34 h264bsdCheckValidParamSets 35 h264bsdVideoRange 36 h264bsdMatrixCoefficients 37 h264bsdCroppingParams 38 39 ------------------------------------------------------------------------------*/ 40 41 /*------------------------------------------------------------------------------ 42 1. Include headers 43 ------------------------------------------------------------------------------*/ 44 45 #include "h264bsd_decoder.h" 46 #include "h264bsd_nal_unit.h" 47 #include "h264bsd_byte_stream.h" 48 #include "h264bsd_seq_param_set.h" 49 #include "h264bsd_pic_param_set.h" 50 #include "h264bsd_slice_header.h" 51 #include "h264bsd_slice_data.h" 52 #include "h264bsd_neighbour.h" 53 #include "h264bsd_util.h" 54 #include "h264bsd_dpb.h" 55 #include "h264bsd_deblocking.h" 56 #include "h264bsd_conceal.h" 57 58 /*------------------------------------------------------------------------------ 59 2. External compiler flags 60 -------------------------------------------------------------------------------- 61 62 -------------------------------------------------------------------------------- 63 3. Module defines 64 ------------------------------------------------------------------------------*/ 65 66 /*------------------------------------------------------------------------------ 67 4. Local function prototypes 68 ------------------------------------------------------------------------------*/ 69 70 /*------------------------------------------------------------------------------ 71 72 Function name: h264bsdInit 73 74 Functional description: 75 Initialize the decoder. 76 77 Inputs: 78 noOutputReordering flag to indicate the decoder that it does not 79 have to perform reordering of display images. 80 81 Outputs: 82 pStorage pointer to initialized storage structure 83 84 Returns: 85 none 86 87 ------------------------------------------------------------------------------*/ 88 89 u32 h264bsdInit(storage_t *pStorage, u32 noOutputReordering) 90 { 91 92 /* Variables */ 93 u32 size; 94 /* Code */ 95 96 ASSERT(pStorage); 97 98 h264bsdInitStorage(pStorage); 99 100 /* allocate mbLayer to be next multiple of 64 to enable use of 101 * specific NEON optimized "memset" for clearing the structure */ 102 size = (sizeof(macroblockLayer_t) + 63) & ~0x3F; 103 104 pStorage->mbLayer = (macroblockLayer_t*)H264SwDecMalloc(size, 1); 105 if (!pStorage->mbLayer) 106 return HANTRO_NOK; 107 108 if (noOutputReordering) 109 pStorage->noReordering = HANTRO_TRUE; 110 111 return HANTRO_OK; 112 } 113 114 /*------------------------------------------------------------------------------ 115 116 Function: h264bsdDecode 117 118 Functional description: 119 Decode a NAL unit. This function calls other modules to perform 120 tasks like 121 * extract and decode NAL unit from the byte stream 122 * decode parameter sets 123 * decode slice header and slice data 124 * conceal errors in the picture 125 * perform deblocking filtering 126 127 This function contains top level control logic of the decoder. 128 129 Inputs: 130 pStorage pointer to storage data structure 131 byteStrm pointer to stream buffer given by application 132 len length of the buffer in bytes 133 picId identifier for a picture, assigned by the 134 application 135 136 Outputs: 137 readBytes number of bytes read from the stream is stored 138 here 139 140 Returns: 141 H264BSD_RDY decoding finished, nothing special 142 H264BSD_PIC_RDY decoding of a picture finished 143 H264BSD_HDRS_RDY param sets activated, information like 144 picture dimensions etc can be read 145 H264BSD_ERROR error in decoding 146 H264BSD_PARAM_SET_ERROR serius error in decoding, failed to 147 activate param sets 148 149 ------------------------------------------------------------------------------*/ 150 151 u32 h264bsdDecode(storage_t *pStorage, u8 *byteStrm, u32 len, u32 picId, 152 u32 *readBytes) 153 { 154 155 /* Variables */ 156 157 u32 tmp, ppsId, spsId; 158 i32 picOrderCnt; 159 nalUnit_t nalUnit; 160 seqParamSet_t seqParamSet; 161 picParamSet_t picParamSet; 162 strmData_t strm; 163 u32 accessUnitBoundaryFlag = HANTRO_FALSE; 164 u32 picReady = HANTRO_FALSE; 165 166 /* Code */ 167 168 ASSERT(pStorage); 169 ASSERT(byteStrm); 170 ASSERT(len); 171 ASSERT(readBytes); 172 173 /* if previous buffer was not finished and same pointer given -> skip NAL 174 * unit extraction */ 175 if (pStorage->prevBufNotFinished && byteStrm == pStorage->prevBufPointer) 176 { 177 strm = pStorage->strm[0]; 178 strm.pStrmCurrPos = strm.pStrmBuffStart; 179 strm.strmBuffReadBits = strm.bitPosInWord = 0; 180 *readBytes = pStorage->prevBytesConsumed; 181 } 182 else 183 { 184 tmp = h264bsdExtractNalUnit(byteStrm, len, &strm, readBytes); 185 if (tmp != HANTRO_OK) 186 { 187 EPRINT("BYTE_STREAM"); 188 return(H264BSD_ERROR); 189 } 190 /* store stream */ 191 pStorage->strm[0] = strm; 192 pStorage->prevBytesConsumed = *readBytes; 193 pStorage->prevBufPointer = byteStrm; 194 } 195 pStorage->prevBufNotFinished = HANTRO_FALSE; 196 197 tmp = h264bsdDecodeNalUnit(&strm, &nalUnit); 198 if (tmp != HANTRO_OK) 199 { 200 EPRINT("NAL_UNIT"); 201 return(H264BSD_ERROR); 202 } 203 204 /* Discard unspecified, reserved, SPS extension and auxiliary picture slices */ 205 if(nalUnit.nalUnitType == 0 || nalUnit.nalUnitType >= 13) 206 { 207 DEBUG(("DISCARDED NAL (UNSPECIFIED, REGISTERED, SPS ext or AUX slice)\n")); 208 return(H264BSD_RDY); 209 } 210 211 tmp = h264bsdCheckAccessUnitBoundary( 212 &strm, 213 &nalUnit, 214 pStorage, 215 &accessUnitBoundaryFlag); 216 if (tmp != HANTRO_OK) 217 { 218 EPRINT("ACCESS UNIT BOUNDARY CHECK"); 219 if (tmp == PARAM_SET_ERROR) 220 return(H264BSD_PARAM_SET_ERROR); 221 else 222 return(H264BSD_ERROR); 223 } 224 225 if ( accessUnitBoundaryFlag ) 226 { 227 DEBUG(("Access unit boundary\n")); 228 /* conceal if picture started and param sets activated */ 229 if (pStorage->picStarted && pStorage->activeSps != NULL) 230 { 231 DEBUG(("CONCEALING...")); 232 233 /* return error if second phase of 234 * initialization is not completed */ 235 if (pStorage->pendingActivation) 236 { 237 EPRINT("Pending activation not completed"); 238 return (H264BSD_ERROR); 239 } 240 241 if (!pStorage->validSliceInAccessUnit) 242 { 243 pStorage->currImage->data = 244 h264bsdAllocateDpbImage(pStorage->dpb); 245 h264bsdInitRefPicList(pStorage->dpb); 246 tmp = h264bsdConceal(pStorage, pStorage->currImage, P_SLICE); 247 } 248 else 249 tmp = h264bsdConceal(pStorage, pStorage->currImage, 250 pStorage->sliceHeader->sliceType); 251 252 picReady = HANTRO_TRUE; 253 254 /* current NAL unit should be decoded on next activation -> set 255 * readBytes to 0 */ 256 *readBytes = 0; 257 pStorage->prevBufNotFinished = HANTRO_TRUE; 258 DEBUG(("...DONE\n")); 259 } 260 else 261 { 262 pStorage->validSliceInAccessUnit = HANTRO_FALSE; 263 } 264 pStorage->skipRedundantSlices = HANTRO_FALSE; 265 } 266 267 if (!picReady) 268 { 269 switch (nalUnit.nalUnitType) 270 { 271 case NAL_SEQ_PARAM_SET: 272 DEBUG(("SEQ PARAM SET\n")); 273 tmp = h264bsdDecodeSeqParamSet(&strm, &seqParamSet); 274 if (tmp != HANTRO_OK) 275 { 276 EPRINT("SEQ_PARAM_SET"); 277 FREE(seqParamSet.offsetForRefFrame); 278 FREE(seqParamSet.vuiParameters); 279 return(H264BSD_ERROR); 280 } 281 tmp = h264bsdStoreSeqParamSet(pStorage, &seqParamSet); 282 break; 283 284 case NAL_PIC_PARAM_SET: 285 DEBUG(("PIC PARAM SET\n")); 286 tmp = h264bsdDecodePicParamSet(&strm, &picParamSet); 287 if (tmp != HANTRO_OK) 288 { 289 EPRINT("PIC_PARAM_SET"); 290 FREE(picParamSet.runLength); 291 FREE(picParamSet.topLeft); 292 FREE(picParamSet.bottomRight); 293 FREE(picParamSet.sliceGroupId); 294 return(H264BSD_ERROR); 295 } 296 tmp = h264bsdStorePicParamSet(pStorage, &picParamSet); 297 break; 298 299 case NAL_CODED_SLICE_IDR: 300 DEBUG(("IDR ")); 301 /* fall through */ 302 case NAL_CODED_SLICE: 303 DEBUG(("SLICE HEADER\n")); 304 305 /* picture successfully finished and still decoding same old 306 * access unit -> no need to decode redundant slices */ 307 if (pStorage->skipRedundantSlices) 308 return(H264BSD_RDY); 309 310 pStorage->picStarted = HANTRO_TRUE; 311 312 if (h264bsdIsStartOfPicture(pStorage)) 313 { 314 pStorage->numConcealedMbs = 0; 315 pStorage->currentPicId = picId; 316 317 tmp = h264bsdCheckPpsId(&strm, &ppsId); 318 ASSERT(tmp == HANTRO_OK); 319 /* store old activeSpsId and return headers ready 320 * indication if activeSps changes */ 321 spsId = pStorage->activeSpsId; 322 tmp = h264bsdActivateParamSets(pStorage, ppsId, 323 IS_IDR_NAL_UNIT(&nalUnit) ? 324 HANTRO_TRUE : HANTRO_FALSE); 325 if (tmp != HANTRO_OK) 326 { 327 EPRINT("Param set activation"); 328 pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS; 329 pStorage->activePps = NULL; 330 pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS; 331 pStorage->activeSps = NULL; 332 pStorage->pendingActivation = HANTRO_FALSE; 333 334 if(tmp == MEMORY_ALLOCATION_ERROR) 335 { 336 return H264BSD_MEMALLOC_ERROR; 337 } 338 else 339 return(H264BSD_PARAM_SET_ERROR); 340 } 341 342 if (spsId != pStorage->activeSpsId) 343 { 344 seqParamSet_t *oldSPS = NULL; 345 seqParamSet_t *newSPS = pStorage->activeSps; 346 u32 noOutputOfPriorPicsFlag = 1; 347 348 if(pStorage->oldSpsId < MAX_NUM_SEQ_PARAM_SETS) 349 { 350 oldSPS = pStorage->sps[pStorage->oldSpsId]; 351 } 352 353 *readBytes = 0; 354 pStorage->prevBufNotFinished = HANTRO_TRUE; 355 356 357 if(nalUnit.nalUnitType == NAL_CODED_SLICE_IDR) 358 { 359 tmp = 360 h264bsdCheckPriorPicsFlag(&noOutputOfPriorPicsFlag, 361 &strm, newSPS, 362 pStorage->activePps, 363 nalUnit.nalUnitType); 364 } 365 else 366 { 367 tmp = HANTRO_NOK; 368 } 369 370 if((tmp != HANTRO_OK) || 371 (noOutputOfPriorPicsFlag != 0) || 372 (pStorage->dpb->noReordering) || 373 (oldSPS == NULL) || 374 (oldSPS->picWidthInMbs != newSPS->picWidthInMbs) || 375 (oldSPS->picHeightInMbs != newSPS->picHeightInMbs) || 376 (oldSPS->maxDpbSize != newSPS->maxDpbSize)) 377 { 378 pStorage->dpb->flushed = 0; 379 } 380 else 381 { 382 h264bsdFlushDpb(pStorage->dpb); 383 } 384 385 pStorage->oldSpsId = pStorage->activeSpsId; 386 387 return(H264BSD_HDRS_RDY); 388 } 389 } 390 391 /* return error if second phase of 392 * initialization is not completed */ 393 if (pStorage->pendingActivation) 394 { 395 EPRINT("Pending activation not completed"); 396 return (H264BSD_ERROR); 397 } 398 tmp = h264bsdDecodeSliceHeader(&strm, pStorage->sliceHeader + 1, 399 pStorage->activeSps, pStorage->activePps, &nalUnit); 400 if (tmp != HANTRO_OK) 401 { 402 EPRINT("SLICE_HEADER"); 403 return(H264BSD_ERROR); 404 } 405 if (h264bsdIsStartOfPicture(pStorage)) 406 { 407 if (!IS_IDR_NAL_UNIT(&nalUnit)) 408 { 409 tmp = h264bsdCheckGapsInFrameNum(pStorage->dpb, 410 pStorage->sliceHeader[1].frameNum, 411 nalUnit.nalRefIdc != 0 ? 412 HANTRO_TRUE : HANTRO_FALSE, 413 pStorage->activeSps-> 414 gapsInFrameNumValueAllowedFlag); 415 if (tmp != HANTRO_OK) 416 { 417 EPRINT("Gaps in frame num"); 418 return(H264BSD_ERROR); 419 } 420 } 421 pStorage->currImage->data = 422 h264bsdAllocateDpbImage(pStorage->dpb); 423 } 424 425 /* store slice header to storage if successfully decoded */ 426 pStorage->sliceHeader[0] = pStorage->sliceHeader[1]; 427 pStorage->validSliceInAccessUnit = HANTRO_TRUE; 428 pStorage->prevNalUnit[0] = nalUnit; 429 430 h264bsdComputeSliceGroupMap(pStorage, 431 pStorage->sliceHeader->sliceGroupChangeCycle); 432 433 h264bsdInitRefPicList(pStorage->dpb); 434 tmp = h264bsdReorderRefPicList(pStorage->dpb, 435 &pStorage->sliceHeader->refPicListReordering, 436 pStorage->sliceHeader->frameNum, 437 pStorage->sliceHeader->numRefIdxL0Active); 438 if (tmp != HANTRO_OK) 439 { 440 EPRINT("Reordering"); 441 return(H264BSD_ERROR); 442 } 443 444 DEBUG(("SLICE DATA, FIRST %d\n", 445 pStorage->sliceHeader->firstMbInSlice)); 446 tmp = h264bsdDecodeSliceData(&strm, pStorage, 447 pStorage->currImage, pStorage->sliceHeader); 448 if (tmp != HANTRO_OK) 449 { 450 EPRINT("SLICE_DATA"); 451 h264bsdMarkSliceCorrupted(pStorage, 452 pStorage->sliceHeader->firstMbInSlice); 453 return(H264BSD_ERROR); 454 } 455 456 if (h264bsdIsEndOfPicture(pStorage)) 457 { 458 picReady = HANTRO_TRUE; 459 pStorage->skipRedundantSlices = HANTRO_TRUE; 460 } 461 break; 462 463 case NAL_SEI: 464 DEBUG(("SEI MESSAGE, NOT DECODED")); 465 break; 466 467 default: 468 DEBUG(("NOT IMPLEMENTED YET %d\n",nalUnit.nalUnitType)); 469 } 470 } 471 472 if (picReady) 473 { 474 h264bsdFilterPicture(pStorage->currImage, pStorage->mb); 475 476 h264bsdResetStorage(pStorage); 477 478 picOrderCnt = h264bsdDecodePicOrderCnt(pStorage->poc, 479 pStorage->activeSps, pStorage->sliceHeader, pStorage->prevNalUnit); 480 481 if (pStorage->validSliceInAccessUnit) 482 { 483 if (pStorage->prevNalUnit->nalRefIdc) 484 { 485 tmp = h264bsdMarkDecRefPic(pStorage->dpb, 486 &pStorage->sliceHeader->decRefPicMarking, 487 pStorage->currImage, pStorage->sliceHeader->frameNum, 488 picOrderCnt, 489 IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ? 490 HANTRO_TRUE : HANTRO_FALSE, 491 pStorage->currentPicId, pStorage->numConcealedMbs); 492 } 493 /* non-reference picture, just store for possible display 494 * reordering */ 495 else 496 { 497 tmp = h264bsdMarkDecRefPic(pStorage->dpb, NULL, 498 pStorage->currImage, pStorage->sliceHeader->frameNum, 499 picOrderCnt, 500 IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ? 501 HANTRO_TRUE : HANTRO_FALSE, 502 pStorage->currentPicId, pStorage->numConcealedMbs); 503 } 504 } 505 506 pStorage->picStarted = HANTRO_FALSE; 507 pStorage->validSliceInAccessUnit = HANTRO_FALSE; 508 509 return(H264BSD_PIC_RDY); 510 } 511 else 512 return(H264BSD_RDY); 513 514 } 515 516 /*------------------------------------------------------------------------------ 517 518 Function: h264bsdShutdown 519 520 Functional description: 521 Shutdown a decoder instance. Function frees all the memories 522 allocated for the decoder instance. 523 524 Inputs: 525 pStorage pointer to storage data structure 526 527 Returns: 528 none 529 530 531 ------------------------------------------------------------------------------*/ 532 533 void h264bsdShutdown(storage_t *pStorage) 534 { 535 536 /* Variables */ 537 538 u32 i; 539 540 /* Code */ 541 542 ASSERT(pStorage); 543 544 for (i = 0; i < MAX_NUM_SEQ_PARAM_SETS; i++) 545 { 546 if (pStorage->sps[i]) 547 { 548 FREE(pStorage->sps[i]->offsetForRefFrame); 549 FREE(pStorage->sps[i]->vuiParameters); 550 FREE(pStorage->sps[i]); 551 } 552 } 553 554 for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++) 555 { 556 if (pStorage->pps[i]) 557 { 558 FREE(pStorage->pps[i]->runLength); 559 FREE(pStorage->pps[i]->topLeft); 560 FREE(pStorage->pps[i]->bottomRight); 561 FREE(pStorage->pps[i]->sliceGroupId); 562 FREE(pStorage->pps[i]); 563 } 564 } 565 566 FREE(pStorage->mbLayer); 567 FREE(pStorage->mb); 568 FREE(pStorage->sliceGroupMap); 569 570 h264bsdFreeDpb(pStorage->dpb); 571 572 } 573 574 /*------------------------------------------------------------------------------ 575 576 Function: h264bsdNextOutputPicture 577 578 Functional description: 579 Get next output picture in display order. 580 581 Inputs: 582 pStorage pointer to storage data structure 583 584 Outputs: 585 picId identifier of the picture will be stored here 586 isIdrPic IDR flag of the picture will be stored here 587 numErrMbs number of concealed macroblocks in the picture 588 will be stored here 589 590 Returns: 591 pointer to the picture data 592 NULL if no pictures available for display 593 594 ------------------------------------------------------------------------------*/ 595 596 u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic, 597 u32 *numErrMbs) 598 { 599 600 /* Variables */ 601 602 dpbOutPicture_t *pOut; 603 604 /* Code */ 605 606 ASSERT(pStorage); 607 608 pOut = h264bsdDpbOutputPicture(pStorage->dpb); 609 610 if (pOut != NULL) 611 { 612 *picId = pOut->picId; 613 *isIdrPic = pOut->isIdr; 614 *numErrMbs = pOut->numErrMbs; 615 return (pOut->data); 616 } 617 else 618 return(NULL); 619 620 } 621 622 /*------------------------------------------------------------------------------ 623 624 Function: h264bsdPicWidth 625 626 Functional description: 627 Get width of the picture in macroblocks 628 629 Inputs: 630 pStorage pointer to storage data structure 631 632 Outputs: 633 none 634 635 Returns: 636 picture width 637 0 if parameters sets not yet activated 638 639 ------------------------------------------------------------------------------*/ 640 641 u32 h264bsdPicWidth(storage_t *pStorage) 642 { 643 644 /* Variables */ 645 646 /* Code */ 647 648 ASSERT(pStorage); 649 650 if (pStorage->activeSps) 651 return(pStorage->activeSps->picWidthInMbs); 652 else 653 return(0); 654 655 } 656 657 /*------------------------------------------------------------------------------ 658 659 Function: h264bsdPicHeight 660 661 Functional description: 662 Get height of the picture in macroblocks 663 664 Inputs: 665 pStorage pointer to storage data structure 666 667 Outputs: 668 none 669 670 Returns: 671 picture width 672 0 if parameters sets not yet activated 673 674 ------------------------------------------------------------------------------*/ 675 676 u32 h264bsdPicHeight(storage_t *pStorage) 677 { 678 679 /* Variables */ 680 681 /* Code */ 682 683 ASSERT(pStorage); 684 685 if (pStorage->activeSps) 686 return(pStorage->activeSps->picHeightInMbs); 687 else 688 return(0); 689 690 } 691 692 /*------------------------------------------------------------------------------ 693 694 Function: h264bsdFlushBuffer 695 696 Functional description: 697 Flush the decoded picture buffer, see dpb.c for details 698 699 Inputs: 700 pStorage pointer to storage data structure 701 702 ------------------------------------------------------------------------------*/ 703 704 void h264bsdFlushBuffer(storage_t *pStorage) 705 { 706 707 /* Variables */ 708 709 /* Code */ 710 711 ASSERT(pStorage); 712 713 h264bsdFlushDpb(pStorage->dpb); 714 715 } 716 717 /*------------------------------------------------------------------------------ 718 719 Function: h264bsdCheckValidParamSets 720 721 Functional description: 722 Check if any valid parameter set combinations (SPS/PPS) exists. 723 724 Inputs: 725 pStorage pointer to storage structure 726 727 Returns: 728 1 at least one valid SPS/PPS combination found 729 0 no valid param set combinations found 730 731 732 ------------------------------------------------------------------------------*/ 733 734 u32 h264bsdCheckValidParamSets(storage_t *pStorage) 735 { 736 737 /* Variables */ 738 739 /* Code */ 740 741 ASSERT(pStorage); 742 743 return(h264bsdValidParamSets(pStorage) == HANTRO_OK ? 1 : 0); 744 745 } 746 747 /*------------------------------------------------------------------------------ 748 749 Function: h264bsdVideoRange 750 751 Functional description: 752 Get value of video_full_range_flag received in the VUI data. 753 754 Inputs: 755 pStorage pointer to storage structure 756 757 Returns: 758 1 video_full_range_flag received and value is 1 759 0 otherwise 760 761 ------------------------------------------------------------------------------*/ 762 763 u32 h264bsdVideoRange(storage_t *pStorage) 764 { 765 766 /* Variables */ 767 768 /* Code */ 769 770 ASSERT(pStorage); 771 772 if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag && 773 pStorage->activeSps->vuiParameters && 774 pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag && 775 pStorage->activeSps->vuiParameters->videoFullRangeFlag) 776 return(1); 777 else /* default value of video_full_range_flag is 0 */ 778 return(0); 779 780 } 781 782 /*------------------------------------------------------------------------------ 783 784 Function: h264bsdMatrixCoefficients 785 786 Functional description: 787 Get value of matrix_coefficients received in the VUI data 788 789 Inputs: 790 pStorage pointer to storage structure 791 792 Outputs: 793 value of matrix_coefficients if received 794 2 otherwise (this is the default value) 795 796 ------------------------------------------------------------------------------*/ 797 798 u32 h264bsdMatrixCoefficients(storage_t *pStorage) 799 { 800 801 /* Variables */ 802 803 /* Code */ 804 805 ASSERT(pStorage); 806 807 if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag && 808 pStorage->activeSps->vuiParameters && 809 pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag && 810 pStorage->activeSps->vuiParameters->colourDescriptionPresentFlag) 811 return(pStorage->activeSps->vuiParameters->matrixCoefficients); 812 else /* default unspecified */ 813 return(2); 814 815 } 816 817 /*------------------------------------------------------------------------------ 818 819 Function: hh264bsdCroppingParams 820 821 Functional description: 822 Get cropping parameters of the active SPS 823 824 Inputs: 825 pStorage pointer to storage structure 826 827 Outputs: 828 croppingFlag flag indicating if cropping params present is 829 stored here 830 leftOffset cropping left offset in pixels is stored here 831 width width of the image after cropping is stored here 832 topOffset cropping top offset in pixels is stored here 833 height height of the image after cropping is stored here 834 835 Returns: 836 none 837 838 ------------------------------------------------------------------------------*/ 839 840 void h264bsdCroppingParams(storage_t *pStorage, u32 *croppingFlag, 841 u32 *leftOffset, u32 *width, u32 *topOffset, u32 *height) 842 { 843 844 /* Variables */ 845 846 /* Code */ 847 848 ASSERT(pStorage); 849 850 if (pStorage->activeSps && pStorage->activeSps->frameCroppingFlag) 851 { 852 *croppingFlag = 1; 853 *leftOffset = 2 * pStorage->activeSps->frameCropLeftOffset; 854 *width = 16 * pStorage->activeSps->picWidthInMbs - 855 2 * (pStorage->activeSps->frameCropLeftOffset + 856 pStorage->activeSps->frameCropRightOffset); 857 *topOffset = 2 * pStorage->activeSps->frameCropTopOffset; 858 *height = 16 * pStorage->activeSps->picHeightInMbs - 859 2 * (pStorage->activeSps->frameCropTopOffset + 860 pStorage->activeSps->frameCropBottomOffset); 861 } 862 else 863 { 864 *croppingFlag = 0; 865 *leftOffset = 0; 866 *width = 0; 867 *topOffset = 0; 868 *height = 0; 869 } 870 871 } 872 873 /*------------------------------------------------------------------------------ 874 875 Function: h264bsdSampleAspectRatio 876 877 Functional description: 878 Get aspect ratio received in the VUI data 879 880 Inputs: 881 pStorage pointer to storage structure 882 883 Outputs: 884 sarWidth sample aspect ratio height 885 sarHeight sample aspect ratio width 886 887 ------------------------------------------------------------------------------*/ 888 889 void h264bsdSampleAspectRatio(storage_t *pStorage, u32 *sarWidth, u32 *sarHeight) 890 { 891 892 /* Variables */ 893 u32 w = 1; 894 u32 h = 1; 895 /* Code */ 896 897 ASSERT(pStorage); 898 899 900 if (pStorage->activeSps && 901 pStorage->activeSps->vuiParametersPresentFlag && 902 pStorage->activeSps->vuiParameters && 903 pStorage->activeSps->vuiParameters->aspectRatioPresentFlag ) 904 { 905 switch (pStorage->activeSps->vuiParameters->aspectRatioIdc) 906 { 907 case ASPECT_RATIO_UNSPECIFIED: w = 0; h = 0; break; 908 case ASPECT_RATIO_1_1: w = 1; h = 1; break; 909 case ASPECT_RATIO_12_11: w = 12; h = 11; break; 910 case ASPECT_RATIO_10_11: w = 10; h = 11; break; 911 case ASPECT_RATIO_16_11: w = 16; h = 11; break; 912 case ASPECT_RATIO_40_33: w = 40; h = 33; break; 913 case ASPECT_RATIO_24_11: w = 24; h = 11; break; 914 case ASPECT_RATIO_20_11: w = 20; h = 11; break; 915 case ASPECT_RATIO_32_11: w = 32; h = 11; break; 916 case ASPECT_RATIO_80_33: w = 80; h = 33; break; 917 case ASPECT_RATIO_18_11: w = 18; h = 11; break; 918 case ASPECT_RATIO_15_11: w = 15; h = 11; break; 919 case ASPECT_RATIO_64_33: w = 64; h = 33; break; 920 case ASPECT_RATIO_160_99: w = 160; h = 99; break; 921 case ASPECT_RATIO_EXTENDED_SAR: 922 w = pStorage->activeSps->vuiParameters->sarWidth; 923 h = pStorage->activeSps->vuiParameters->sarHeight; 924 if ((w == 0) || (h == 0)) 925 w = h = 0; 926 break; 927 default: 928 w = 0; 929 h = 0; 930 break; 931 } 932 } 933 934 /* set aspect ratio*/ 935 *sarWidth = w; 936 *sarHeight = h; 937 938 } 939 940 /*------------------------------------------------------------------------------ 941 942 Function: h264bsdProfile 943 944 Functional description: 945 Get profile information from active SPS 946 947 Inputs: 948 pStorage pointer to storage structure 949 950 Outputs: 951 profile current profile 952 953 ------------------------------------------------------------------------------*/ 954 u32 h264bsdProfile(storage_t *pStorage) 955 { 956 if (pStorage->activeSps) 957 return pStorage->activeSps->profileIdc; 958 else 959 return 0; 960 } 961 962