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