/H264Dec/source/h264bsd_dpb.c

http://github.com/mbebenita/Broadway · C · 1584 lines · 761 code · 267 blank · 556 comment · 178 complexity · 46ab8f2eaf94c6b0f5abbca9b757bc77 MD5 · raw file

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