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 ComparePictures 27 h264bsdReorderRefPicList 28 Mmcop1 29 Mmcop2 30 Mmcop3 31 Mmcop4 32 Mmcop5 33 Mmcop6 34 h264bsdMarkDecRefPic 35 h264bsdGetRefPicData 36 h264bsdAllocateDpbImage 37 SlidingWindowRefPicMarking 38 h264bsdInitDpb 39 h264bsdResetDpb 40 h264bsdInitRefPicList 41 FindDpbPic 42 SetPicNums 43 h264bsdCheckGapsInFrameNum 44 FindSmallestPicOrderCnt 45 OutputPicture 46 h264bsdDpbOutputPicture 47 h264bsdFlushDpb 48 h264bsdFreeDpb 49 50 ------------------------------------------------------------------------------*/ 51 52 /*------------------------------------------------------------------------------ 53 1. Include headers 54 ------------------------------------------------------------------------------*/ 55 56 #include "h264bsd_cfg.h" 57 #include "h264bsd_dpb.h" 58 #include "h264bsd_slice_header.h" 59 #include "h264bsd_image.h" 60 #include "h264bsd_util.h" 61 #include "basetype.h" 62 63 #include <log/log.h> 64 /*------------------------------------------------------------------------------ 65 2. External compiler flags 66 -------------------------------------------------------------------------------- 67 68 -------------------------------------------------------------------------------- 69 3. Module defines 70 ------------------------------------------------------------------------------*/ 71 72 /* macros to determine picture status. Note that IS_SHORT_TERM macro returns 73 * true also for non-existing pictures because non-existing pictures are 74 * regarded short term pictures according to H.264 standard */ 75 #define IS_REFERENCE(a) ((a).status) 76 #define IS_EXISTING(a) ((a).status > NON_EXISTING) 77 #define IS_SHORT_TERM(a) \ 78 ((a).status == NON_EXISTING || (a).status == SHORT_TERM) 79 #define IS_LONG_TERM(a) ((a).status == LONG_TERM) 80 81 /* macro to set a picture unused for reference */ 82 #define SET_UNUSED(a) (a).status = UNUSED; 83 84 #define MAX_NUM_REF_IDX_L0_ACTIVE 16 85 86 /*------------------------------------------------------------------------------ 87 4. Local function prototypes 88 ------------------------------------------------------------------------------*/ 89 90 static i32 ComparePictures(const void *ptr1, const void *ptr2); 91 92 static u32 Mmcop1(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums); 93 94 static u32 Mmcop2(dpbStorage_t *dpb, u32 longTermPicNum); 95 96 static u32 Mmcop3(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums, 97 u32 longTermFrameIdx); 98 99 static u32 Mmcop4(dpbStorage_t *dpb, u32 maxLongTermFrameIdx); 100 101 static u32 Mmcop5(dpbStorage_t *dpb); 102 103 static u32 Mmcop6(dpbStorage_t *dpb, u32 frameNum, i32 picOrderCnt, 104 u32 longTermFrameIdx); 105 106 static u32 SlidingWindowRefPicMarking(dpbStorage_t *dpb); 107 108 static i32 FindDpbPic(dpbStorage_t *dpb, i32 picNum, u32 isShortTerm); 109 110 static void SetPicNums(dpbStorage_t *dpb, u32 currFrameNum); 111 112 static dpbPicture_t* FindSmallestPicOrderCnt(dpbStorage_t *dpb); 113 114 static u32 OutputPicture(dpbStorage_t *dpb); 115 116 static void ShellSort(dpbPicture_t *pPic, u32 num); 117 118 /*------------------------------------------------------------------------------ 119 120 Function: ComparePictures 121 122 Functional description: 123 Function to compare dpb pictures, used by the ShellSort() function. 124 Order of the pictures after sorting shall be as follows: 125 1) short term reference pictures starting with the largest 126 picNum 127 2) long term reference pictures starting with the smallest 128 longTermPicNum 129 3) pictures unused for reference but needed for display 130 4) other pictures 131 132 Returns: 133 -1 pic 1 is greater than pic 2 134 0 equal from comparison point of view 135 1 pic 2 is greater then pic 1 136 137 ------------------------------------------------------------------------------*/ 138 139 static i32 ComparePictures(const void *ptr1, const void *ptr2) 140 { 141 142 /* Variables */ 143 144 dpbPicture_t *pic1, *pic2; 145 146 /* Code */ 147 148 ASSERT(ptr1); 149 ASSERT(ptr2); 150 151 pic1 = (dpbPicture_t*)ptr1; 152 pic2 = (dpbPicture_t*)ptr2; 153 154 /* both are non-reference pictures, check if needed for display */ 155 if (!IS_REFERENCE(*pic1) && !IS_REFERENCE(*pic2)) 156 { 157 if (pic1->toBeDisplayed && !pic2->toBeDisplayed) 158 return(-1); 159 else if (!pic1->toBeDisplayed && pic2->toBeDisplayed) 160 return(1); 161 else 162 return(0); 163 } 164 /* only pic 1 needed for reference -> greater */ 165 else if (!IS_REFERENCE(*pic2)) 166 return(-1); 167 /* only pic 2 needed for reference -> greater */ 168 else if (!IS_REFERENCE(*pic1)) 169 return(1); 170 /* both are short term reference pictures -> check picNum */ 171 else if (IS_SHORT_TERM(*pic1) && IS_SHORT_TERM(*pic2)) 172 { 173 if (pic1->picNum > pic2->picNum) 174 return(-1); 175 else if (pic1->picNum < pic2->picNum) 176 return(1); 177 else 178 return(0); 179 } 180 /* only pic 1 is short term -> greater */ 181 else if (IS_SHORT_TERM(*pic1)) 182 return(-1); 183 /* only pic 2 is short term -> greater */ 184 else if (IS_SHORT_TERM(*pic2)) 185 return(1); 186 /* both are long term reference pictures -> check picNum (contains the 187 * longTermPicNum */ 188 else 189 { 190 if (pic1->picNum > pic2->picNum) 191 return(1); 192 else if (pic1->picNum < pic2->picNum) 193 return(-1); 194 else 195 return(0); 196 } 197 } 198 199 /*------------------------------------------------------------------------------ 200 201 Function: h264bsdReorderRefPicList 202 203 Functional description: 204 Function to perform reference picture list reordering based on 205 reordering commands received in the slice header. See details 206 of the process in the H.264 standard. 207 208 Inputs: 209 dpb pointer to dpb storage structure 210 order pointer to reordering commands 211 currFrameNum current frame number 212 numRefIdxActive number of active reference indices for current 213 picture 214 215 Outputs: 216 dpb 'list' field of the structure reordered 217 218 Returns: 219 HANTRO_OK success 220 HANTRO_NOK if non-existing pictures referred to in the 221 reordering commands 222 223 ------------------------------------------------------------------------------*/ 224 225 u32 h264bsdReorderRefPicList( 226 dpbStorage_t *dpb, 227 refPicListReordering_t *order, 228 u32 currFrameNum, 229 u32 numRefIdxActive) 230 { 231 232 /* Variables */ 233 234 u32 i, j, k, picNumPred, refIdx; 235 i32 picNum, picNumNoWrap, index; 236 u32 isShortTerm; 237 238 /* Code */ 239 240 ASSERT(order); 241 ASSERT(currFrameNum <= dpb->maxFrameNum); 242 ASSERT(numRefIdxActive <= MAX_NUM_REF_IDX_L0_ACTIVE); 243 244 /* set dpb picture numbers for sorting */ 245 SetPicNums(dpb, currFrameNum); 246 247 if (!order->refPicListReorderingFlagL0) 248 return(HANTRO_OK); 249 250 refIdx = 0; 251 picNumPred = currFrameNum; 252 253 i = 0; 254 while (order->command[i].reorderingOfPicNumsIdc < 3) 255 { 256 /* short term */ 257 if (order->command[i].reorderingOfPicNumsIdc < 2) 258 { 259 if (order->command[i].reorderingOfPicNumsIdc == 0) 260 { 261 picNumNoWrap = 262 (i32)picNumPred - (i32)order->command[i].absDiffPicNum; 263 if (picNumNoWrap < 0) 264 picNumNoWrap += (i32)dpb->maxFrameNum; 265 } 266 else 267 { 268 picNumNoWrap = 269 (i32)(picNumPred + order->command[i].absDiffPicNum); 270 if (picNumNoWrap >= (i32)dpb->maxFrameNum) 271 picNumNoWrap -= (i32)dpb->maxFrameNum; 272 } 273 picNumPred = (u32)picNumNoWrap; 274 picNum = picNumNoWrap; 275 if ((u32)picNumNoWrap > currFrameNum) 276 picNum -= (i32)dpb->maxFrameNum; 277 isShortTerm = HANTRO_TRUE; 278 } 279 /* long term */ 280 else 281 { 282 picNum = (i32)order->command[i].longTermPicNum; 283 isShortTerm = HANTRO_FALSE; 284 285 } 286 /* find corresponding picture from dpb */ 287 index = FindDpbPic(dpb, picNum, isShortTerm); 288 if (index < 0 || !IS_EXISTING(dpb->buffer[index])) 289 return(HANTRO_NOK); 290 291 /* shift pictures */ 292 for (j = numRefIdxActive; j > refIdx; j--) 293 dpb->list[j] = dpb->list[j-1]; 294 /* put picture into the list */ 295 dpb->list[refIdx++] = &dpb->buffer[index]; 296 /* remove later references to the same picture */ 297 for (j = k = refIdx; j <= numRefIdxActive; j++) 298 if(dpb->list[j] != &dpb->buffer[index]) 299 dpb->list[k++] = dpb->list[j]; 300 301 i++; 302 } 303 304 return(HANTRO_OK); 305 306 } 307 308 /*------------------------------------------------------------------------------ 309 310 Function: Mmcop1 311 312 Functional description: 313 Function to mark a short-term reference picture unused for 314 reference, memory_management_control_operation equal to 1 315 316 Returns: 317 HANTRO_OK success 318 HANTRO_NOK failure, picture does not exist in the buffer 319 320 ------------------------------------------------------------------------------*/ 321 322 static u32 Mmcop1(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums) 323 { 324 325 /* Variables */ 326 327 i32 index, picNum; 328 329 /* Code */ 330 331 ASSERT(currPicNum < dpb->maxFrameNum); 332 333 picNum = (i32)currPicNum - (i32)differenceOfPicNums; 334 335 index = FindDpbPic(dpb, picNum, HANTRO_TRUE); 336 if (index < 0) 337 return(HANTRO_NOK); 338 339 SET_UNUSED(dpb->buffer[index]); 340 dpb->numRefFrames--; 341 if (!dpb->buffer[index].toBeDisplayed) 342 dpb->fullness--; 343 344 return(HANTRO_OK); 345 346 } 347 348 /*------------------------------------------------------------------------------ 349 350 Function: Mmcop2 351 352 Functional description: 353 Function to mark a long-term reference picture unused for 354 reference, memory_management_control_operation equal to 2 355 356 Returns: 357 HANTRO_OK success 358 HANTRO_NOK failure, picture does not exist in the buffer 359 360 ------------------------------------------------------------------------------*/ 361 362 static u32 Mmcop2(dpbStorage_t *dpb, u32 longTermPicNum) 363 { 364 365 /* Variables */ 366 367 i32 index; 368 369 /* Code */ 370 371 index = FindDpbPic(dpb, (i32)longTermPicNum, HANTRO_FALSE); 372 if (index < 0) 373 return(HANTRO_NOK); 374 375 SET_UNUSED(dpb->buffer[index]); 376 dpb->numRefFrames--; 377 if (!dpb->buffer[index].toBeDisplayed) 378 dpb->fullness--; 379 380 return(HANTRO_OK); 381 382 } 383 384 /*------------------------------------------------------------------------------ 385 386 Function: Mmcop3 387 388 Functional description: 389 Function to assing a longTermFrameIdx to a short-term reference 390 frame (i.e. to change it to a long-term reference picture), 391 memory_management_control_operation equal to 3 392 393 Returns: 394 HANTRO_OK success 395 HANTRO_NOK failure, short-term picture does not exist in the 396 buffer or is a non-existing picture, or invalid 397 longTermFrameIdx given 398 399 ------------------------------------------------------------------------------*/ 400 401 static u32 Mmcop3(dpbStorage_t *dpb, u32 currPicNum, u32 differenceOfPicNums, 402 u32 longTermFrameIdx) 403 { 404 405 /* Variables */ 406 407 i32 index, picNum; 408 u32 i; 409 410 /* Code */ 411 412 ASSERT(dpb); 413 ASSERT(currPicNum < dpb->maxFrameNum); 414 415 if ( (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) || 416 (longTermFrameIdx > dpb->maxLongTermFrameIdx) ) 417 return(HANTRO_NOK); 418 419 /* check if a long term picture with the same longTermFrameIdx already 420 * exist and remove it if necessary */ 421 for (i = 0; i < dpb->maxRefFrames; i++) 422 if (IS_LONG_TERM(dpb->buffer[i]) && 423 (u32)dpb->buffer[i].picNum == longTermFrameIdx) 424 { 425 SET_UNUSED(dpb->buffer[i]); 426 dpb->numRefFrames--; 427 if (!dpb->buffer[i].toBeDisplayed) 428 dpb->fullness--; 429 break; 430 } 431 432 picNum = (i32)currPicNum - (i32)differenceOfPicNums; 433 434 index = FindDpbPic(dpb, picNum, HANTRO_TRUE); 435 if (index < 0) 436 return(HANTRO_NOK); 437 if (!IS_EXISTING(dpb->buffer[index])) 438 return(HANTRO_NOK); 439 440 dpb->buffer[index].status = LONG_TERM; 441 dpb->buffer[index].picNum = (i32)longTermFrameIdx; 442 443 return(HANTRO_OK); 444 445 } 446 447 /*------------------------------------------------------------------------------ 448 449 Function: Mmcop4 450 451 Functional description: 452 Function to set maxLongTermFrameIdx, 453 memory_management_control_operation equal to 4 454 455 Returns: 456 HANTRO_OK success 457 458 ------------------------------------------------------------------------------*/ 459 460 static u32 Mmcop4(dpbStorage_t *dpb, u32 maxLongTermFrameIdx) 461 { 462 463 /* Variables */ 464 465 u32 i; 466 467 /* Code */ 468 469 dpb->maxLongTermFrameIdx = maxLongTermFrameIdx; 470 471 for (i = 0; i < dpb->maxRefFrames; i++) 472 if (IS_LONG_TERM(dpb->buffer[i]) && 473 ( ((u32)dpb->buffer[i].picNum > maxLongTermFrameIdx) || 474 (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) ) ) 475 { 476 SET_UNUSED(dpb->buffer[i]); 477 dpb->numRefFrames--; 478 if (!dpb->buffer[i].toBeDisplayed) 479 dpb->fullness--; 480 } 481 482 return(HANTRO_OK); 483 484 } 485 486 /*------------------------------------------------------------------------------ 487 488 Function: Mmcop5 489 490 Functional description: 491 Function to mark all reference pictures unused for reference and 492 set maxLongTermFrameIdx to NO_LONG_TERM_FRAME_INDICES, 493 memory_management_control_operation equal to 5. Function flushes 494 the buffer and places all pictures that are needed for display into 495 the output buffer. 496 497 Returns: 498 HANTRO_OK success 499 500 ------------------------------------------------------------------------------*/ 501 502 static u32 Mmcop5(dpbStorage_t *dpb) 503 { 504 505 /* Variables */ 506 507 u32 i; 508 509 /* Code */ 510 511 for (i = 0; i < 16; i++) 512 { 513 if (IS_REFERENCE(dpb->buffer[i])) 514 { 515 SET_UNUSED(dpb->buffer[i]); 516 if (!dpb->buffer[i].toBeDisplayed) 517 dpb->fullness--; 518 } 519 } 520 521 /* output all pictures */ 522 while (OutputPicture(dpb) == HANTRO_OK) 523 ; 524 dpb->numRefFrames = 0; 525 dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES; 526 dpb->prevRefFrameNum = 0; 527 528 return(HANTRO_OK); 529 530 } 531 532 /*------------------------------------------------------------------------------ 533 534 Function: Mmcop6 535 536 Functional description: 537 Function to assign longTermFrameIdx to the current picture, 538 memory_management_control_operation equal to 6 539 540 Returns: 541 HANTRO_OK success 542 HANTRO_NOK invalid longTermFrameIdx or no room for current 543 picture in the buffer 544 545 ------------------------------------------------------------------------------*/ 546 547 static u32 Mmcop6(dpbStorage_t *dpb, u32 frameNum, i32 picOrderCnt, 548 u32 longTermFrameIdx) 549 { 550 551 /* Variables */ 552 553 u32 i; 554 555 /* Code */ 556 557 ASSERT(frameNum < dpb->maxFrameNum); 558 559 if ( (dpb->maxLongTermFrameIdx == NO_LONG_TERM_FRAME_INDICES) || 560 (longTermFrameIdx > dpb->maxLongTermFrameIdx) ) 561 return(HANTRO_NOK); 562 563 /* check if a long term picture with the same longTermFrameIdx already 564 * exist and remove it if necessary */ 565 for (i = 0; i < dpb->maxRefFrames; i++) 566 if (IS_LONG_TERM(dpb->buffer[i]) && 567 (u32)dpb->buffer[i].picNum == longTermFrameIdx) 568 { 569 SET_UNUSED(dpb->buffer[i]); 570 dpb->numRefFrames--; 571 if (!dpb->buffer[i].toBeDisplayed) 572 dpb->fullness--; 573 break; 574 } 575 576 if (dpb->numRefFrames < dpb->maxRefFrames) 577 { 578 dpb->currentOut->frameNum = frameNum; 579 dpb->currentOut->picNum = (i32)longTermFrameIdx; 580 dpb->currentOut->picOrderCnt = picOrderCnt; 581 dpb->currentOut->status = LONG_TERM; 582 if (dpb->noReordering) 583 dpb->currentOut->toBeDisplayed = HANTRO_FALSE; 584 else 585 dpb->currentOut->toBeDisplayed = HANTRO_TRUE; 586 dpb->numRefFrames++; 587 dpb->fullness++; 588 return(HANTRO_OK); 589 } 590 /* if there is no room, return an error */ 591 else 592 return(HANTRO_NOK); 593 594 } 595 596 /*------------------------------------------------------------------------------ 597 598 Function: h264bsdMarkDecRefPic 599 600 Functional description: 601 Function to perform reference picture marking process. This 602 function should be called both for reference and non-reference 603 pictures. Non-reference pictures shall have mark pointer set to 604 NULL. 605 606 Inputs: 607 dpb pointer to the DPB data structure 608 mark pointer to reference picture marking commands 609 image pointer to current picture to be placed in the buffer 610 frameNum frame number of the current picture 611 picOrderCnt picture order count for the current picture 612 isIdr flag to indicate if the current picture is an 613 IDR picture 614 currentPicId identifier for the current picture, from the 615 application, stored along with the picture 616 numErrMbs number of concealed macroblocks in the current 617 picture, stored along with the picture 618 619 Outputs: 620 dpb 'buffer' modified, possible output frames placed into 621 'outBuf' 622 623 Returns: 624 HANTRO_OK success 625 HANTRO_NOK failure 626 627 ------------------------------------------------------------------------------*/ 628 629 u32 h264bsdMarkDecRefPic( 630 dpbStorage_t *dpb, 631 decRefPicMarking_t *mark, 632 image_t *image, 633 u32 frameNum, 634 i32 picOrderCnt, 635 u32 isIdr, 636 u32 currentPicId, 637 u32 numErrMbs) 638 { 639 640 /* Variables */ 641 642 u32 i, status; 643 u32 markedAsLongTerm; 644 u32 toBeDisplayed; 645 646 /* Code */ 647 648 ASSERT(dpb); 649 ASSERT(mark || !isIdr); 650 ASSERT(!isIdr || (frameNum == 0 && picOrderCnt == 0)); 651 ASSERT(frameNum < dpb->maxFrameNum); 652 653 if (image->data != dpb->currentOut->data) 654 { 655 EPRINT("TRYING TO MARK NON-ALLOCATED IMAGE"); 656 return(HANTRO_NOK); 657 } 658 659 dpb->lastContainsMmco5 = HANTRO_FALSE; 660 status = HANTRO_OK; 661 662 toBeDisplayed = dpb->noReordering ? HANTRO_FALSE : HANTRO_TRUE; 663 664 /* non-reference picture, stored for display reordering purposes */ 665 if (mark == NULL) 666 { 667 dpb->currentOut->status = UNUSED; 668 dpb->currentOut->frameNum = frameNum; 669 dpb->currentOut->picNum = (i32)frameNum; 670 dpb->currentOut->picOrderCnt = picOrderCnt; 671 dpb->currentOut->toBeDisplayed = toBeDisplayed; 672 if (!dpb->noReordering) 673 dpb->fullness++; 674 } 675 /* IDR picture */ 676 else if (isIdr) 677 { 678 679 /* h264bsdCheckGapsInFrameNum not called for IDR pictures -> have to 680 * reset numOut and outIndex here */ 681 dpb->numOut = dpb->outIndex = 0; 682 683 /* flush the buffer */ 684 Mmcop5(dpb); 685 /* if noOutputOfPriorPicsFlag was set -> the pictures preceding the 686 * IDR picture shall not be output -> set output buffer empty */ 687 if (mark->noOutputOfPriorPicsFlag || dpb->noReordering) 688 { 689 dpb->numOut = 0; 690 dpb->outIndex = 0; 691 } 692 693 if (mark->longTermReferenceFlag) 694 { 695 dpb->currentOut->status = LONG_TERM; 696 dpb->maxLongTermFrameIdx = 0; 697 } 698 else 699 { 700 dpb->currentOut->status = SHORT_TERM; 701 dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES; 702 } 703 dpb->currentOut->frameNum = 0; 704 dpb->currentOut->picNum = 0; 705 dpb->currentOut->picOrderCnt = 0; 706 dpb->currentOut->toBeDisplayed = toBeDisplayed; 707 dpb->fullness = 1; 708 dpb->numRefFrames = 1; 709 } 710 /* reference picture */ 711 else 712 { 713 markedAsLongTerm = HANTRO_FALSE; 714 if (mark->adaptiveRefPicMarkingModeFlag) 715 { 716 i = 0; 717 while (mark->operation[i].memoryManagementControlOperation) 718 { 719 switch (mark->operation[i].memoryManagementControlOperation) 720 { 721 case 1: 722 status = Mmcop1( 723 dpb, 724 frameNum, 725 mark->operation[i].differenceOfPicNums); 726 break; 727 728 case 2: 729 status = Mmcop2(dpb, mark->operation[i].longTermPicNum); 730 break; 731 732 case 3: 733 status = Mmcop3( 734 dpb, 735 frameNum, 736 mark->operation[i].differenceOfPicNums, 737 mark->operation[i].longTermFrameIdx); 738 break; 739 740 case 4: 741 status = Mmcop4( 742 dpb, 743 mark->operation[i].maxLongTermFrameIdx); 744 break; 745 746 case 5: 747 status = Mmcop5(dpb); 748 dpb->lastContainsMmco5 = HANTRO_TRUE; 749 frameNum = 0; 750 break; 751 752 case 6: 753 status = Mmcop6( 754 dpb, 755 frameNum, 756 picOrderCnt, 757 mark->operation[i].longTermFrameIdx); 758 if (status == HANTRO_OK) 759 markedAsLongTerm = HANTRO_TRUE; 760 break; 761 762 default: /* invalid memory management control operation */ 763 status = HANTRO_NOK; 764 break; 765 } 766 if (status != HANTRO_OK) 767 { 768 break; 769 } 770 i++; 771 } 772 } 773 else 774 { 775 status = SlidingWindowRefPicMarking(dpb); 776 } 777 /* if current picture was not marked as long-term reference by 778 * memory management control operation 6 -> mark current as short 779 * term and insert it into dpb (if there is room) */ 780 if (!markedAsLongTerm) 781 { 782 if (dpb->numRefFrames < dpb->maxRefFrames) 783 { 784 dpb->currentOut->frameNum = frameNum; 785 dpb->currentOut->picNum = (i32)frameNum; 786 dpb->currentOut->picOrderCnt = picOrderCnt; 787 dpb->currentOut->status = SHORT_TERM; 788 dpb->currentOut->toBeDisplayed = toBeDisplayed; 789 dpb->fullness++; 790 dpb->numRefFrames++; 791 } 792 /* no room */ 793 else 794 { 795 status = HANTRO_NOK; 796 } 797 } 798 } 799 800 dpb->currentOut->isIdr = isIdr; 801 dpb->currentOut->picId = currentPicId; 802 dpb->currentOut->numErrMbs = numErrMbs; 803 804 /* dpb was initialized to not to reorder the pictures -> output current 805 * picture immediately */ 806 if (dpb->noReordering) 807 { 808 ASSERT(dpb->numOut == 0); 809 ASSERT(dpb->outIndex == 0); 810 dpb->outBuf[dpb->numOut].data = dpb->currentOut->data; 811 dpb->outBuf[dpb->numOut].isIdr = dpb->currentOut->isIdr; 812 dpb->outBuf[dpb->numOut].picId = dpb->currentOut->picId; 813 dpb->outBuf[dpb->numOut].numErrMbs = dpb->currentOut->numErrMbs; 814 dpb->numOut++; 815 } 816 else 817 { 818 /* output pictures if buffer full */ 819 while (dpb->fullness > dpb->dpbSize) 820 { 821 i = OutputPicture(dpb); 822 ASSERT(i == HANTRO_OK); 823 } 824 } 825 826 /* sort dpb */ 827 ShellSort(dpb->buffer, dpb->dpbSize+1); 828 829 return(status); 830 831 } 832 833 /*------------------------------------------------------------------------------ 834 835 Function: h264bsdGetRefPicData 836 837 Functional description: 838 Function to get reference picture data from the reference picture 839 list 840 841 Returns: 842 pointer to desired reference picture data 843 NULL if invalid index or non-existing picture referred 844 845 ------------------------------------------------------------------------------*/ 846 847 u8* h264bsdGetRefPicData(dpbStorage_t *dpb, u32 index) 848 { 849 850 /* Variables */ 851 852 /* Code */ 853 854 if(index > 16 || dpb->list[index] == NULL) 855 return(NULL); 856 else if(!IS_EXISTING(*dpb->list[index])) 857 return(NULL); 858 else 859 return(dpb->list[index]->data); 860 861 } 862 863 /*------------------------------------------------------------------------------ 864 865 Function: h264bsdAllocateDpbImage 866 867 Functional description: 868 function to allocate memory for a image. This function does not 869 really allocate any memory but reserves one of the buffer 870 positions for decoding of current picture 871 872 Returns: 873 pointer to memory area for the image 874 875 876 ------------------------------------------------------------------------------*/ 877 878 u8* h264bsdAllocateDpbImage(dpbStorage_t *dpb) 879 { 880 881 /* Variables */ 882 883 /* Code */ 884 885 ASSERT( !dpb->buffer[dpb->dpbSize].toBeDisplayed && 886 !IS_REFERENCE(dpb->buffer[dpb->dpbSize]) ); 887 ASSERT(dpb->fullness <= dpb->dpbSize); 888 889 dpb->currentOut = dpb->buffer + dpb->dpbSize; 890 891 return(dpb->currentOut->data); 892 893 } 894 895 /*------------------------------------------------------------------------------ 896 897 Function: SlidingWindowRefPicMarking 898 899 Functional description: 900 Function to perform sliding window refence picture marking process. 901 902 Outputs: 903 HANTRO_OK success 904 HANTRO_NOK failure, no short-term reference frame found that 905 could be marked unused 906 907 908 ------------------------------------------------------------------------------*/ 909 910 static u32 SlidingWindowRefPicMarking(dpbStorage_t *dpb) 911 { 912 913 /* Variables */ 914 915 i32 index, picNum; 916 u32 i; 917 918 /* Code */ 919 920 if (dpb->numRefFrames < dpb->maxRefFrames) 921 { 922 return(HANTRO_OK); 923 } 924 else 925 { 926 index = -1; 927 picNum = 0; 928 /* find the oldest short term picture */ 929 for (i = 0; i < dpb->numRefFrames; i++) 930 if (IS_SHORT_TERM(dpb->buffer[i])) 931 if (dpb->buffer[i].picNum < picNum || index == -1) 932 { 933 index = (i32)i; 934 picNum = dpb->buffer[i].picNum; 935 } 936 if (index >= 0) 937 { 938 SET_UNUSED(dpb->buffer[index]); 939 dpb->numRefFrames--; 940 if (!dpb->buffer[index].toBeDisplayed) 941 dpb->fullness--; 942 943 return(HANTRO_OK); 944 } 945 } 946 947 return(HANTRO_NOK); 948 949 } 950 951 /*------------------------------------------------------------------------------ 952 953 Function: h264bsdInitDpb 954 955 Functional description: 956 Function to initialize DPB. Reserves memories for the buffer, 957 reference picture list and output buffer. dpbSize indicates 958 the maximum DPB size indicated by the levelIdc in the stream. 959 If noReordering flag is FALSE the DPB stores dpbSize pictures 960 for display reordering purposes. On the other hand, if the 961 flag is TRUE the DPB only stores maxRefFrames reference pictures 962 and outputs all the pictures immediately. 963 964 Inputs: 965 picSizeInMbs picture size in macroblocks 966 dpbSize size of the DPB (number of pictures) 967 maxRefFrames max number of reference frames 968 maxFrameNum max frame number 969 noReordering flag to indicate that DPB does not have to 970 prepare to reorder frames for display 971 972 Outputs: 973 dpb pointer to dpb data storage 974 975 Returns: 976 HANTRO_OK success 977 MEMORY_ALLOCATION_ERROR if memory allocation failed 978 979 ------------------------------------------------------------------------------*/ 980 981 u32 h264bsdInitDpb( 982 dpbStorage_t *dpb, 983 u32 picSizeInMbs, 984 u32 dpbSize, 985 u32 maxRefFrames, 986 u32 maxFrameNum, 987 u32 noReordering) 988 { 989 990 /* Variables */ 991 992 u32 i; 993 994 /* Code */ 995 996 ASSERT(picSizeInMbs); 997 ASSERT(maxRefFrames <= MAX_NUM_REF_PICS); 998 ASSERT(maxRefFrames <= dpbSize); 999 ASSERT(maxFrameNum); 1000 ASSERT(dpbSize); 1001 1002 // see comment in loop below about size calculation 1003 if (picSizeInMbs > (UINT32_MAX - 32 - 15) / 384) { 1004 ALOGE("b/28533562"); 1005 android_errorWriteLog(0x534e4554, "28533562"); 1006 return(MEMORY_ALLOCATION_ERROR); 1007 } 1008 1009 dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES; 1010 dpb->maxRefFrames = MAX(maxRefFrames, 1); 1011 if (noReordering) 1012 dpb->dpbSize = dpb->maxRefFrames; 1013 else 1014 dpb->dpbSize = dpbSize; 1015 dpb->maxFrameNum = maxFrameNum; 1016 dpb->noReordering = noReordering; 1017 dpb->fullness = 0; 1018 dpb->numRefFrames = 0; 1019 dpb->prevRefFrameNum = 0; 1020 1021 ALLOCATE(dpb->buffer, MAX_NUM_REF_IDX_L0_ACTIVE + 1, dpbPicture_t); 1022 if (dpb->buffer == NULL) 1023 return(MEMORY_ALLOCATION_ERROR); 1024 H264SwDecMemset(dpb->buffer, 0, 1025 (MAX_NUM_REF_IDX_L0_ACTIVE + 1)*sizeof(dpbPicture_t)); 1026 for (i = 0; i < dpb->dpbSize + 1; i++) 1027 { 1028 /* Allocate needed amount of memory, which is: 1029 * image size + 32 + 15, where 32 cames from the fact that in ARM OpenMax 1030 * DL implementation Functions may read beyond the end of an array, 1031 * by a maximum of 32 bytes. And +15 cames for the need to align memory 1032 * to 16-byte boundary */ 1033 ALLOCATE(dpb->buffer[i].pAllocatedData, (picSizeInMbs*384 + 32+15), u8); 1034 if (dpb->buffer[i].pAllocatedData == NULL) 1035 return(MEMORY_ALLOCATION_ERROR); 1036 1037 dpb->buffer[i].data = ALIGN(dpb->buffer[i].pAllocatedData, 16); 1038 } 1039 1040 ALLOCATE(dpb->list, MAX_NUM_REF_IDX_L0_ACTIVE + 1, dpbPicture_t*); 1041 ALLOCATE(dpb->outBuf, dpb->dpbSize+1, dpbOutPicture_t); 1042 1043 if (dpb->list == NULL || dpb->outBuf == NULL) 1044 return(MEMORY_ALLOCATION_ERROR); 1045 1046 H264SwDecMemset(dpb->list, 0, 1047 ((MAX_NUM_REF_IDX_L0_ACTIVE + 1) * sizeof(dpbPicture_t*)) ); 1048 1049 dpb->numOut = dpb->outIndex = 0; 1050 1051 return(HANTRO_OK); 1052 1053 } 1054 1055 /*------------------------------------------------------------------------------ 1056 1057 Function: h264bsdResetDpb 1058 1059 Functional description: 1060 Function to reset DPB. This function should be called when an IDR 1061 slice (other than the first) activates new sequence parameter set. 1062 Function calls h264bsdFreeDpb to free old allocated memories and 1063 h264bsdInitDpb to re-initialize the DPB. Same inputs, outputs and 1064 returns as for h264bsdInitDpb. 1065 1066 ------------------------------------------------------------------------------*/ 1067 1068 u32 h264bsdResetDpb( 1069 dpbStorage_t *dpb, 1070 u32 picSizeInMbs, 1071 u32 dpbSize, 1072 u32 maxRefFrames, 1073 u32 maxFrameNum, 1074 u32 noReordering) 1075 { 1076 1077 /* Code */ 1078 1079 ASSERT(picSizeInMbs); 1080 ASSERT(maxRefFrames <= MAX_NUM_REF_PICS); 1081 ASSERT(maxRefFrames <= dpbSize); 1082 ASSERT(maxFrameNum); 1083 ASSERT(dpbSize); 1084 1085 h264bsdFreeDpb(dpb); 1086 1087 return h264bsdInitDpb(dpb, picSizeInMbs, dpbSize, maxRefFrames, 1088 maxFrameNum, noReordering); 1089 } 1090 1091 /*------------------------------------------------------------------------------ 1092 1093 Function: h264bsdInitRefPicList 1094 1095 Functional description: 1096 Function to initialize reference picture list. Function just 1097 sets pointers in the list according to pictures in the buffer. 1098 The buffer is assumed to contain pictures sorted according to 1099 what the H.264 standard says about initial reference picture list. 1100 1101 Inputs: 1102 dpb pointer to dpb data structure 1103 1104 Outputs: 1105 dpb 'list' field initialized 1106 1107 Returns: 1108 none 1109 1110 ------------------------------------------------------------------------------*/ 1111 1112 void h264bsdInitRefPicList(dpbStorage_t *dpb) 1113 { 1114 1115 /* Variables */ 1116 1117 u32 i; 1118 1119 /* Code */ 1120 1121 for (i = 0; i < dpb->numRefFrames; i++) 1122 dpb->list[i] = &dpb->buffer[i]; 1123 1124 } 1125 1126 /*------------------------------------------------------------------------------ 1127 1128 Function: FindDpbPic 1129 1130 Functional description: 1131 Function to find a reference picture from the buffer. The picture 1132 to be found is identified by picNum and isShortTerm flag. 1133 1134 Returns: 1135 index of the picture in the buffer 1136 -1 if the specified picture was not found in the buffer 1137 1138 ------------------------------------------------------------------------------*/ 1139 1140 static i32 FindDpbPic(dpbStorage_t *dpb, i32 picNum, u32 isShortTerm) 1141 { 1142 1143 /* Variables */ 1144 1145 u32 i = 0; 1146 u32 found = HANTRO_FALSE; 1147 1148 /* Code */ 1149 1150 if (isShortTerm) 1151 { 1152 while (i < dpb->maxRefFrames && !found) 1153 { 1154 if (IS_SHORT_TERM(dpb->buffer[i]) && 1155 dpb->buffer[i].picNum == picNum) 1156 found = HANTRO_TRUE; 1157 else 1158 i++; 1159 } 1160 } 1161 else 1162 { 1163 ASSERT(picNum >= 0); 1164 while (i < dpb->maxRefFrames && !found) 1165 { 1166 if (IS_LONG_TERM(dpb->buffer[i]) && 1167 dpb->buffer[i].picNum == picNum) 1168 found = HANTRO_TRUE; 1169 else 1170 i++; 1171 } 1172 } 1173 1174 if (found) 1175 return((i32)i); 1176 else 1177 return(-1); 1178 1179 } 1180 1181 /*------------------------------------------------------------------------------ 1182 1183 Function: SetPicNums 1184 1185 Functional description: 1186 Function to set picNum values for short-term pictures in the 1187 buffer. Numbering of pictures is based on frame numbers and as 1188 frame numbers are modulo maxFrameNum -> frame numbers of older 1189 pictures in the buffer may be bigger than the currFrameNum. 1190 picNums will be set so that current frame has the largest picNum 1191 and all the short-term frames in the buffer will get smaller picNum 1192 representing their "distance" from the current frame. This 1193 function kind of maps the modulo arithmetic back to normal. 1194 1195 ------------------------------------------------------------------------------*/ 1196 1197 static void SetPicNums(dpbStorage_t *dpb, u32 currFrameNum) 1198 { 1199 1200 /* Variables */ 1201 1202 u32 i; 1203 i32 frameNumWrap; 1204 1205 /* Code */ 1206 1207 ASSERT(dpb); 1208 ASSERT(currFrameNum < dpb->maxFrameNum); 1209 1210 for (i = 0; i < dpb->numRefFrames; i++) 1211 if (IS_SHORT_TERM(dpb->buffer[i])) 1212 { 1213 if (dpb->buffer[i].frameNum > currFrameNum) 1214 frameNumWrap = 1215 (i32)dpb->buffer[i].frameNum - (i32)dpb->maxFrameNum; 1216 else 1217 frameNumWrap = (i32)dpb->buffer[i].frameNum; 1218 dpb->buffer[i].picNum = frameNumWrap; 1219 } 1220 1221 } 1222 1223 /*------------------------------------------------------------------------------ 1224 1225 Function: h264bsdCheckGapsInFrameNum 1226 1227 Functional description: 1228 Function to check gaps in frame_num and generate non-existing 1229 (short term) reference pictures if necessary. This function should 1230 be called only for non-IDR pictures. 1231 1232 Inputs: 1233 dpb pointer to dpb data structure 1234 frameNum frame number of the current picture 1235 isRefPic flag to indicate if current picture is a reference or 1236 non-reference picture 1237 gapsAllowed Flag which indicates active SPS stance on whether 1238 to allow gaps 1239 1240 Outputs: 1241 dpb 'buffer' possibly modified by inserting non-existing 1242 pictures with sliding window marking process 1243 1244 Returns: 1245 HANTRO_OK success 1246 HANTRO_NOK error in sliding window reference picture marking or 1247 frameNum equal to previous reference frame used for 1248 a reference picture 1249 1250 ------------------------------------------------------------------------------*/ 1251 1252 u32 h264bsdCheckGapsInFrameNum(dpbStorage_t *dpb, u32 frameNum, u32 isRefPic, 1253 u32 gapsAllowed) 1254 { 1255 1256 /* Variables */ 1257 1258 u32 unUsedShortTermFrameNum; 1259 u8 *tmp; 1260 1261 /* Code */ 1262 1263 ASSERT(dpb); 1264 ASSERT(dpb->fullness <= dpb->dpbSize); 1265 ASSERT(frameNum < dpb->maxFrameNum); 1266 1267 dpb->numOut = 0; 1268 dpb->outIndex = 0; 1269 1270 if(!gapsAllowed) 1271 return(HANTRO_OK); 1272 1273 if ( (frameNum != dpb->prevRefFrameNum) && 1274 (frameNum != ((dpb->prevRefFrameNum + 1) % dpb->maxFrameNum))) 1275 { 1276 1277 unUsedShortTermFrameNum = (dpb->prevRefFrameNum + 1) % dpb->maxFrameNum; 1278 1279 /* store data pointer of last buffer position to be used as next 1280 * "allocated" data pointer if last buffer position after this process 1281 * contains data pointer located in outBuf (buffer placed in the output 1282 * shall not be overwritten by the current picture) */ 1283 tmp = dpb->buffer[dpb->dpbSize].data; 1284 do 1285 { 1286 SetPicNums(dpb, unUsedShortTermFrameNum); 1287 1288 if (SlidingWindowRefPicMarking(dpb) != HANTRO_OK) 1289 { 1290 return(HANTRO_NOK); 1291 } 1292 1293 /* output pictures if buffer full */ 1294 while (dpb->fullness >= dpb->dpbSize) 1295 { 1296 #ifdef _ASSERT_USED 1297 ASSERT(!dpb->noReordering); 1298 ASSERT(OutputPicture(dpb) == HANTRO_OK); 1299 #else 1300 OutputPicture(dpb); 1301 #endif 1302 } 1303 1304 /* add to end of list */ 1305 ASSERT( !dpb->buffer[dpb->dpbSize].toBeDisplayed && 1306 !IS_REFERENCE(dpb->buffer[dpb->dpbSize]) ); 1307 dpb->buffer[dpb->dpbSize].status = NON_EXISTING; 1308 dpb->buffer[dpb->dpbSize].frameNum = unUsedShortTermFrameNum; 1309 dpb->buffer[dpb->dpbSize].picNum = (i32)unUsedShortTermFrameNum; 1310 dpb->buffer[dpb->dpbSize].picOrderCnt = 0; 1311 dpb->buffer[dpb->dpbSize].toBeDisplayed = HANTRO_FALSE; 1312 dpb->fullness++; 1313 dpb->numRefFrames++; 1314 1315 /* sort the buffer */ 1316 ShellSort(dpb->buffer, dpb->dpbSize+1); 1317 1318 unUsedShortTermFrameNum = (unUsedShortTermFrameNum + 1) % 1319 dpb->maxFrameNum; 1320 1321 } while (unUsedShortTermFrameNum != frameNum); 1322 1323 /* pictures placed in output buffer -> check that 'data' in 1324 * buffer position dpbSize is not in the output buffer (this will be 1325 * "allocated" by h264bsdAllocateDpbImage). If it is -> exchange data 1326 * pointer with the one stored in the beginning */ 1327 if (dpb->numOut) 1328 { 1329 u32 i; 1330 1331 for (i = 0; i < dpb->numOut; i++) 1332 { 1333 if (dpb->outBuf[i].data == dpb->buffer[dpb->dpbSize].data) 1334 { 1335 /* find buffer position containing data pointer stored in 1336 * tmp */ 1337 for (i = 0; i < dpb->dpbSize; i++) 1338 { 1339 if (dpb->buffer[i].data == tmp) 1340 { 1341 dpb->buffer[i].data = 1342 dpb->buffer[dpb->dpbSize].data; 1343 dpb->buffer[dpb->dpbSize].data = tmp; 1344 break; 1345 } 1346 } 1347 ASSERT(i < dpb->dpbSize); 1348 break; 1349 } 1350 } 1351 } 1352 } 1353 /* frameNum for reference pictures shall not be the same as for previous 1354 * reference picture, otherwise accesses to pictures in the buffer cannot 1355 * be solved unambiguously */ 1356 else if (isRefPic && frameNum == dpb->prevRefFrameNum) 1357 { 1358 return(HANTRO_NOK); 1359 } 1360 1361 /* save current frame_num in prevRefFrameNum. For non-reference frame 1362 * prevFrameNum is set to frame number of last non-existing frame above */ 1363 if (isRefPic) 1364 dpb->prevRefFrameNum = frameNum; 1365 else if (frameNum != dpb->prevRefFrameNum) 1366 { 1367 dpb->prevRefFrameNum = 1368 (frameNum + dpb->maxFrameNum - 1) % dpb->maxFrameNum; 1369 } 1370 1371 return(HANTRO_OK); 1372 1373 } 1374 1375 /*------------------------------------------------------------------------------ 1376 1377 Function: FindSmallestPicOrderCnt 1378 1379 Functional description: 1380 Function to find picture with smallest picture order count. This 1381 will be the next picture in display order. 1382 1383 Returns: 1384 pointer to the picture, NULL if no pictures to be displayed 1385 1386 ------------------------------------------------------------------------------*/ 1387 1388 dpbPicture_t* FindSmallestPicOrderCnt(dpbStorage_t *dpb) 1389 { 1390 1391 /* Variables */ 1392 1393 u32 i; 1394 i32 picOrderCnt; 1395 dpbPicture_t *tmp; 1396 1397 /* Code */ 1398 1399 ASSERT(dpb); 1400 1401 picOrderCnt = 0x7FFFFFFF; 1402 tmp = NULL; 1403 1404 for (i = 0; i <= dpb->dpbSize; i++) 1405 { 1406 if (dpb->buffer[i].toBeDisplayed && 1407 (dpb->buffer[i].picOrderCnt < picOrderCnt)) 1408 { 1409 tmp = dpb->buffer + i; 1410 picOrderCnt = dpb->buffer[i].picOrderCnt; 1411 } 1412 } 1413 1414 return(tmp); 1415 1416 } 1417 1418 /*------------------------------------------------------------------------------ 1419 1420 Function: OutputPicture 1421 1422 Functional description: 1423 Function to put next display order picture into the output buffer. 1424 1425 Returns: 1426 HANTRO_OK success 1427 HANTRO_NOK no pictures to display 1428 1429 ------------------------------------------------------------------------------*/ 1430 1431 u32 OutputPicture(dpbStorage_t *dpb) 1432 { 1433 1434 /* Variables */ 1435 1436 dpbPicture_t *tmp; 1437 1438 /* Code */ 1439 1440 ASSERT(dpb); 1441 1442 if (dpb->noReordering) 1443 return(HANTRO_NOK); 1444 1445 tmp = FindSmallestPicOrderCnt(dpb); 1446 1447 /* no pictures to be displayed */ 1448 if (tmp == NULL) 1449 return(HANTRO_NOK); 1450 1451 dpb->outBuf[dpb->numOut].data = tmp->data; 1452 dpb->outBuf[dpb->numOut].isIdr = tmp->isIdr; 1453 dpb->outBuf[dpb->numOut].picId = tmp->picId; 1454 dpb->outBuf[dpb->numOut].numErrMbs = tmp->numErrMbs; 1455 dpb->numOut++; 1456 1457 tmp->toBeDisplayed = HANTRO_FALSE; 1458 if (!IS_REFERENCE(*tmp)) 1459 { 1460 dpb->fullness--; 1461 } 1462 1463 return(HANTRO_OK); 1464 1465 } 1466 1467 /*------------------------------------------------------------------------------ 1468 1469 Function: h264bsdDpbOutputPicture 1470 1471 Functional description: 1472 Function to get next display order picture from the output buffer. 1473 1474 Return: 1475 pointer to output picture structure, NULL if no pictures to 1476 display 1477 1478 ------------------------------------------------------------------------------*/ 1479 1480 dpbOutPicture_t* h264bsdDpbOutputPicture(dpbStorage_t *dpb) 1481 { 1482 1483 /* Variables */ 1484 1485 /* Code */ 1486 1487 ASSERT(dpb); 1488 1489 if (dpb->outIndex < dpb->numOut) 1490 return(dpb->outBuf + dpb->outIndex++); 1491 else 1492 return(NULL); 1493 1494 } 1495 1496 /*------------------------------------------------------------------------------ 1497 1498 Function: h264bsdFlushDpb 1499 1500 Functional description: 1501 Function to flush the DPB. Function puts all pictures needed for 1502 display into the output buffer. This function shall be called in 1503 the end of the stream to obtain pictures buffered for display 1504 re-ordering purposes. 1505 1506 ------------------------------------------------------------------------------*/ 1507 1508 void h264bsdFlushDpb(dpbStorage_t *dpb) 1509 { 1510 1511 /* don't do anything if buffer not reserved */ 1512 if (dpb->buffer) 1513 { 1514 dpb->flushed = 1; 1515 /* output all pictures */ 1516 while (OutputPicture(dpb) == HANTRO_OK) 1517 ; 1518 } 1519 1520 } 1521 1522 /*------------------------------------------------------------------------------ 1523 1524 Function: h264bsdFreeDpb 1525 1526 Functional description: 1527 Function to free memories reserved for the DPB. 1528 1529 ------------------------------------------------------------------------------*/ 1530 1531 void h264bsdFreeDpb(dpbStorage_t *dpb) 1532 { 1533 1534 /* Variables */ 1535 1536 u32 i; 1537 1538 /* Code */ 1539 1540 ASSERT(dpb); 1541 1542 if (dpb->buffer) 1543 { 1544 for (i = 0; i < dpb->dpbSize+1; i++) 1545 { 1546 FREE(dpb->buffer[i].pAllocatedData); 1547 } 1548 } 1549 FREE(dpb->buffer); 1550 FREE(dpb->list); 1551 FREE(dpb->outBuf); 1552 1553 } 1554 1555 /*------------------------------------------------------------------------------ 1556 1557 Function: ShellSort 1558 1559 Functional description: 1560 Sort pictures in the buffer. Function implements Shell's method, 1561 i.e. diminishing increment sort. See e.g. "Numerical Recipes in C" 1562 for more information. 1563 1564 ------------------------------------------------------------------------------*/ 1565 1566 static void ShellSort(dpbPicture_t *pPic, u32 num) 1567 { 1568 1569 u32 i, j; 1570 u32 step; 1571 dpbPicture_t tmpPic; 1572 1573 step = 7; 1574 1575 while (step) 1576 { 1577 for (i = step; i < num; i++) 1578 { 1579 tmpPic = pPic[i]; 1580 j = i; 1581 while (j >= step && ComparePictures(pPic + j - step, &tmpPic) > 0) 1582 { 1583 pPic[j] = pPic[j-step]; 1584 j -= step; 1585 } 1586 pPic[j] = tmpPic; 1587 } 1588 step >>= 1; 1589 } 1590 1591 } 1592 1593