PageRenderTime 55ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Show/avc/dpb.cpp

http://github.com/mbebenita/Broadway
C++ | 724 lines | 563 code | 97 blank | 64 comment | 131 complexity | aef88045213c5c044b526fe8d1e03651 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* ------------------------------------------------------------------
  2. * Copyright (C) 1998-2009 PacketVideo
  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
  13. * express or implied.
  14. * See the License for the specific language governing permissions
  15. * and limitations under the License.
  16. * -------------------------------------------------------------------
  17. */
  18. #include "avclib_common.h"
  19. #define DPB_MEM_ATTR 0
  20. AVCStatus InitDPB(AVCHandle *avcHandle, AVCCommonObj *video, int FrameHeightInMbs, int PicWidthInMbs, bool padding)
  21. {
  22. AVCDecPicBuffer *dpb = video->decPicBuf;
  23. int level, framesize, num_fs;
  24. void *userData = avcHandle->userData;
  25. #ifndef PV_MEMORY_POOL
  26. uint32 addr;
  27. #endif
  28. uint16 refIdx = 0;
  29. level = video->currSeqParams->level_idc;
  30. for (num_fs = 0; num_fs < MAX_FS; num_fs++)
  31. {
  32. dpb->fs[num_fs] = NULL;
  33. }
  34. framesize = (int)(((FrameHeightInMbs * PicWidthInMbs) << 7) * 3);
  35. if (padding)
  36. {
  37. video->padded_size = (int)((((FrameHeightInMbs + 2) * (PicWidthInMbs + 2)) << 7) * 3) - framesize;
  38. }
  39. else
  40. {
  41. video->padded_size = 0;
  42. }
  43. #ifndef PV_MEMORY_POOL
  44. if (dpb->decoded_picture_buffer)
  45. {
  46. avcHandle->CBAVC_Free(userData, (uintptr_t)dpb->decoded_picture_buffer);
  47. dpb->decoded_picture_buffer = NULL;
  48. }
  49. #endif
  50. /* need to allocate one extra frame for current frame, DPB only defines for reference frames */
  51. dpb->num_fs = (uint32)(MaxDPBX2[mapLev2Idx[level]] << 2) / (3 * FrameHeightInMbs * PicWidthInMbs) + 1;
  52. if (dpb->num_fs > MAX_FS)
  53. {
  54. dpb->num_fs = MAX_FS;
  55. }
  56. if (video->currSeqParams->num_ref_frames + 1 > (uint32)dpb->num_fs)
  57. {
  58. dpb->num_fs = video->currSeqParams->num_ref_frames + 1;
  59. }
  60. dpb->dpb_size = dpb->num_fs * (framesize + video->padded_size);
  61. // dpb->dpb_size = (uint32)MaxDPBX2[mapLev2Idx[level]]*512 + framesize;
  62. #ifndef PV_MEMORY_POOL
  63. dpb->decoded_picture_buffer = (uint8*) avcHandle->CBAVC_Malloc(userData, dpb->dpb_size, 100/*DPB_MEM_ATTR*/);
  64. if (dpb->decoded_picture_buffer == NULL || ((uintptr_t)dpb->decoded_picture_buffer) & 0x3) // not word aligned
  65. return AVC_MEMORY_FAIL;
  66. #endif
  67. dpb->used_size = 0;
  68. num_fs = 0;
  69. while (num_fs < dpb->num_fs)
  70. {
  71. /* fs is an array pointers to AVCDecPicture */
  72. dpb->fs[num_fs] = (AVCFrameStore*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCFrameStore), 101/*DEFAULT_ATTR*/);
  73. if (dpb->fs[num_fs] == NULL)
  74. {
  75. return AVC_MEMORY_FAIL;
  76. }
  77. #ifndef PV_MEMORY_POOL
  78. /* assign the actual memory for Sl, Scb, Scr */
  79. dpb->fs[num_fs]->base_dpb = dpb->decoded_picture_buffer + dpb->used_size;
  80. #endif
  81. dpb->fs[num_fs]->IsReference = 0;
  82. dpb->fs[num_fs]->IsLongTerm = 0;
  83. dpb->fs[num_fs]->IsOutputted = 3;
  84. dpb->fs[num_fs]->frame.RefIdx = refIdx++; /* this value will remain unchanged through out the encoding session */
  85. dpb->fs[num_fs]->frame.picType = AVC_FRAME;
  86. dpb->fs[num_fs]->frame.isLongTerm = 0;
  87. dpb->fs[num_fs]->frame.isReference = 0;
  88. video->RefPicList0[num_fs] = &(dpb->fs[num_fs]->frame);
  89. dpb->fs[num_fs]->frame.padded = 0;
  90. dpb->used_size += (framesize + video->padded_size);
  91. num_fs++;
  92. }
  93. return AVC_SUCCESS;
  94. }
  95. OSCL_EXPORT_REF AVCStatus AVCConfigureSequence(AVCHandle *avcHandle, AVCCommonObj *video, bool padding)
  96. {
  97. void *userData = avcHandle->userData;
  98. AVCDecPicBuffer *dpb = video->decPicBuf;
  99. int framesize, ii; /* size of one frame */
  100. uint PicWidthInMbs, PicHeightInMapUnits, FrameHeightInMbs, PicSizeInMapUnits;
  101. uint num_fs;
  102. /* derived variables from SPS */
  103. PicWidthInMbs = video->currSeqParams->pic_width_in_mbs_minus1 + 1;
  104. PicHeightInMapUnits = video->currSeqParams->pic_height_in_map_units_minus1 + 1 ;
  105. FrameHeightInMbs = (2 - video->currSeqParams->frame_mbs_only_flag) * PicHeightInMapUnits ;
  106. PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits ;
  107. if (video->PicSizeInMapUnits != PicSizeInMapUnits || video->currSeqParams->level_idc != video->level_idc)
  108. {
  109. /* make sure you mark all the frames as unused for reference for flushing*/
  110. for (ii = 0; ii < dpb->num_fs; ii++)
  111. {
  112. dpb->fs[ii]->IsReference = 0;
  113. dpb->fs[ii]->IsOutputted |= 0x02;
  114. }
  115. num_fs = (uint32)(MaxDPBX2[(uint32)mapLev2Idx[video->currSeqParams->level_idc]] << 2) / (3 * PicSizeInMapUnits) + 1;
  116. if (num_fs >= MAX_FS)
  117. {
  118. num_fs = MAX_FS;
  119. }
  120. #ifdef PV_MEMORY_POOL
  121. if (padding)
  122. {
  123. avcHandle->CBAVC_DPBAlloc(avcHandle->userData,
  124. PicSizeInMapUnits + ((PicWidthInMbs + 2) << 1) + (PicHeightInMapUnits << 1), num_fs);
  125. }
  126. else
  127. {
  128. avcHandle->CBAVC_DPBAlloc(avcHandle->userData, PicSizeInMapUnits, num_fs);
  129. }
  130. #endif
  131. CleanUpDPB(avcHandle, video);
  132. if (InitDPB(avcHandle, video, FrameHeightInMbs, PicWidthInMbs, padding) != AVC_SUCCESS)
  133. {
  134. return AVC_FAIL;
  135. }
  136. /* Allocate video->mblock upto PicSizeInMbs and populate the structure such as the neighboring MB pointers. */
  137. framesize = (FrameHeightInMbs * PicWidthInMbs);
  138. if (video->mblock)
  139. {
  140. avcHandle->CBAVC_Free(userData, (uintptr_t)video->mblock);
  141. video->mblock = NULL;
  142. }
  143. video->mblock = (AVCMacroblock*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCMacroblock) * framesize, DEFAULT_ATTR);
  144. if (video->mblock == NULL)
  145. {
  146. return AVC_FAIL;
  147. }
  148. for (ii = 0; ii < framesize; ii++)
  149. {
  150. video->mblock[ii].slice_id = -1;
  151. }
  152. /* Allocate memory for intra prediction */
  153. #ifdef MB_BASED_DEBLOCK
  154. video->intra_pred_top = (uint8*) avcHandle->CBAVC_Malloc(userData, PicWidthInMbs << 4, FAST_MEM_ATTR);
  155. if (video->intra_pred_top == NULL)
  156. {
  157. return AVC_FAIL;
  158. }
  159. video->intra_pred_top_cb = (uint8*) avcHandle->CBAVC_Malloc(userData, PicWidthInMbs << 3, FAST_MEM_ATTR);
  160. if (video->intra_pred_top_cb == NULL)
  161. {
  162. return AVC_FAIL;
  163. }
  164. video->intra_pred_top_cr = (uint8*) avcHandle->CBAVC_Malloc(userData, PicWidthInMbs << 3, FAST_MEM_ATTR);
  165. if (video->intra_pred_top_cr == NULL)
  166. {
  167. return AVC_FAIL;
  168. }
  169. #endif
  170. /* Allocate slice group MAP map */
  171. if (video->MbToSliceGroupMap)
  172. {
  173. avcHandle->CBAVC_Free(userData, (uintptr_t)video->MbToSliceGroupMap);
  174. video->MbToSliceGroupMap = NULL;
  175. }
  176. video->MbToSliceGroupMap = (int*) avcHandle->CBAVC_Malloc(userData, sizeof(uint) * PicSizeInMapUnits * 2, 7/*DEFAULT_ATTR*/);
  177. if (video->MbToSliceGroupMap == NULL)
  178. {
  179. return AVC_FAIL;
  180. }
  181. video->PicSizeInMapUnits = PicSizeInMapUnits;
  182. video->level_idc = video->currSeqParams->level_idc;
  183. }
  184. return AVC_SUCCESS;
  185. }
  186. OSCL_EXPORT_REF AVCStatus CleanUpDPB(AVCHandle *avcHandle, AVCCommonObj *video)
  187. {
  188. AVCDecPicBuffer *dpb = video->decPicBuf;
  189. int ii;
  190. void *userData = avcHandle->userData;
  191. for (ii = 0; ii < MAX_FS; ii++)
  192. {
  193. if (dpb->fs[ii] != NULL)
  194. {
  195. avcHandle->CBAVC_Free(userData, (uintptr_t)dpb->fs[ii]);
  196. dpb->fs[ii] = NULL;
  197. }
  198. }
  199. #ifndef PV_MEMORY_POOL
  200. if (dpb->decoded_picture_buffer)
  201. {
  202. avcHandle->CBAVC_Free(userData, (uintptr_t)dpb->decoded_picture_buffer);
  203. dpb->decoded_picture_buffer = NULL;
  204. }
  205. #endif
  206. dpb->used_size = 0;
  207. dpb->dpb_size = 0;
  208. return AVC_SUCCESS;
  209. }
  210. OSCL_EXPORT_REF AVCStatus DPBInitBuffer(AVCHandle *avcHandle, AVCCommonObj *video)
  211. {
  212. AVCDecPicBuffer *dpb = video->decPicBuf;
  213. int ii, status;
  214. /* Before doing any decoding, check if there's a frame memory available */
  215. /* look for next unused dpb->fs, or complementary field pair */
  216. /* video->currPic is assigned to this */
  217. /* There's also restriction on the frame_num, see page 59 of JVT-I1010.doc. */
  218. for (ii = 0; ii < dpb->num_fs; ii++)
  219. {
  220. /* looking for the one not used or not reference and has been outputted */
  221. if (dpb->fs[ii]->IsReference == 0 && dpb->fs[ii]->IsOutputted == 3)
  222. {
  223. video->currFS = dpb->fs[ii];
  224. #ifdef PV_MEMORY_POOL
  225. status = avcHandle->CBAVC_FrameBind(avcHandle->userData, ii, &(video->currFS->base_dpb));
  226. if (status == AVC_FAIL)
  227. {
  228. return AVC_NO_BUFFER; /* this should not happen */
  229. }
  230. #endif
  231. break;
  232. }
  233. }
  234. if (ii == dpb->num_fs)
  235. {
  236. return AVC_PICTURE_OUTPUT_READY; /* no empty frame available */
  237. }
  238. return AVC_SUCCESS;
  239. }
  240. OSCL_EXPORT_REF void DPBInitPic(AVCCommonObj *video, int CurrPicNum)
  241. {
  242. int offset = 0;
  243. int offsetc = 0;
  244. int luma_framesize;
  245. /* this part has to be set here, assuming that slice header and POC have been decoded. */
  246. /* used in GetOutput API */
  247. video->currFS->PicOrderCnt = video->PicOrderCnt;
  248. video->currFS->FrameNum = video->sliceHdr->frame_num;
  249. video->currFS->FrameNumWrap = CurrPicNum; // MC_FIX
  250. /* initialize everything to zero */
  251. video->currFS->IsOutputted = 0;
  252. video->currFS->IsReference = 0;
  253. video->currFS->IsLongTerm = 0;
  254. video->currFS->frame.isReference = FALSE;
  255. video->currFS->frame.isLongTerm = FALSE;
  256. /* initialize the pixel pointer to NULL */
  257. video->currFS->frame.Sl = video->currFS->frame.Scb = video->currFS->frame.Scr = NULL;
  258. /* determine video->currPic */
  259. /* assign dbp->base_dpb to fs[i]->frame.Sl, Scb, Scr .*/
  260. /* For PicSizeInMbs, see DecodeSliceHeader() */
  261. video->currPic = &(video->currFS->frame);
  262. video->currPic->padded = 0; // reset this flag to not-padded
  263. if (video->padded_size)
  264. {
  265. offset = ((video->PicWidthInSamplesL + 32) << 4) + 16; // offset to the origin
  266. offsetc = (offset >> 2) + 4;
  267. luma_framesize = (int)((((video->FrameHeightInMbs + 2) * (video->PicWidthInMbs + 2)) << 8));
  268. }
  269. else
  270. luma_framesize = video->PicSizeInMbs << 8;
  271. video->currPic->Sl = video->currFS->base_dpb + offset;
  272. video->currPic->Scb = video->currFS->base_dpb + luma_framesize + offsetc;
  273. video->currPic->Scr = video->currPic->Scb + (luma_framesize >> 2);
  274. video->currPic->pitch = video->PicWidthInSamplesL + (video->padded_size == 0 ? 0 : 32);
  275. video->currPic->height = video->PicHeightInSamplesL;
  276. video->currPic->width = video->PicWidthInSamplesL;
  277. video->currPic->PicNum = CurrPicNum;
  278. }
  279. /* to release skipped frame after encoding */
  280. OSCL_EXPORT_REF void DPBReleaseCurrentFrame(AVCHandle *avcHandle, AVCCommonObj *video)
  281. {
  282. AVCDecPicBuffer *dpb = video->decPicBuf;
  283. int ii;
  284. video->currFS->IsOutputted = 3; // return this buffer.
  285. #ifdef PV_MEMORY_POOL /* for non-memory pool, no need to do anything */
  286. /* search for current frame index */
  287. ii = dpb->num_fs;
  288. while (ii--)
  289. {
  290. if (dpb->fs[ii] == video->currFS)
  291. {
  292. avcHandle->CBAVC_FrameUnbind(avcHandle->userData, ii);
  293. break;
  294. }
  295. }
  296. #endif
  297. return ;
  298. }
  299. /* see subclause 8.2.5.1 */
  300. OSCL_EXPORT_REF AVCStatus StorePictureInDPB(AVCHandle *avcHandle, AVCCommonObj *video)
  301. {
  302. AVCStatus status;
  303. AVCDecPicBuffer *dpb = video->decPicBuf;
  304. AVCSliceHeader *sliceHdr = video->sliceHdr;
  305. int ii, num_ref;
  306. /* number 1 of 8.2.5.1, we handle gaps in frame_num differently without using the memory */
  307. /* to be done!!!! */
  308. /* number 3 of 8.2.5.1 */
  309. if (video->nal_unit_type == AVC_NALTYPE_IDR)
  310. {
  311. for (ii = 0; ii < dpb->num_fs; ii++)
  312. {
  313. if (dpb->fs[ii] != video->currFS) /* not current frame */
  314. {
  315. dpb->fs[ii]->IsReference = 0; /* mark as unused for reference */
  316. dpb->fs[ii]->IsLongTerm = 0; /* but still used until output */
  317. dpb->fs[ii]->IsOutputted |= 0x02;
  318. #ifdef PV_MEMORY_POOL
  319. if (dpb->fs[ii]->IsOutputted == 3)
  320. {
  321. avcHandle->CBAVC_FrameUnbind(avcHandle->userData, ii);
  322. }
  323. #endif
  324. }
  325. }
  326. video->currPic->isReference = TRUE;
  327. video->currFS->IsReference = 3;
  328. if (sliceHdr->long_term_reference_flag == 0)
  329. {
  330. video->currPic->isLongTerm = FALSE;
  331. video->currFS->IsLongTerm = 0;
  332. video->MaxLongTermFrameIdx = -1;
  333. }
  334. else
  335. {
  336. video->currPic->isLongTerm = TRUE;
  337. video->currFS->IsLongTerm = 3;
  338. video->currFS->LongTermFrameIdx = 0;
  339. video->MaxLongTermFrameIdx = 0;
  340. }
  341. if (sliceHdr->no_output_of_prior_pics_flag)
  342. {
  343. for (ii = 0; ii < dpb->num_fs; ii++)
  344. {
  345. if (dpb->fs[ii] != video->currFS) /* not current frame */
  346. {
  347. dpb->fs[ii]->IsOutputted = 3;
  348. #ifdef PV_MEMORY_POOL
  349. avcHandle->CBAVC_FrameUnbind(avcHandle->userData, ii);
  350. #endif
  351. }
  352. }
  353. }
  354. video->mem_mgr_ctrl_eq_5 = TRUE; /* flush reference frames MC_FIX */
  355. }
  356. else
  357. {
  358. if (video->currPic->isReference == TRUE)
  359. {
  360. if (sliceHdr->adaptive_ref_pic_marking_mode_flag == 0)
  361. {
  362. status = sliding_window_process(avcHandle, video, dpb); /* we may have to do this after adaptive_memory_marking */
  363. }
  364. else
  365. {
  366. status = adaptive_memory_marking(avcHandle, video, dpb, sliceHdr);
  367. }
  368. if (status != AVC_SUCCESS)
  369. {
  370. return status;
  371. }
  372. }
  373. }
  374. /* number 4 of 8.2.5.1 */
  375. /* This basically says every frame must be at least used for short-term ref. */
  376. /* Need to be revisited!!! */
  377. /* look at insert_picture_in_dpb() */
  378. if (video->nal_unit_type != AVC_NALTYPE_IDR && video->currPic->isLongTerm == FALSE)
  379. {
  380. if (video->currPic->isReference)
  381. {
  382. video->currFS->IsReference = 3;
  383. }
  384. else
  385. {
  386. video->currFS->IsReference = 0;
  387. }
  388. video->currFS->IsLongTerm = 0;
  389. }
  390. /* check if number of reference frames doesn't exceed num_ref_frames */
  391. num_ref = 0;
  392. for (ii = 0; ii < dpb->num_fs; ii++)
  393. {
  394. if (dpb->fs[ii]->IsReference)
  395. {
  396. num_ref++;
  397. }
  398. }
  399. if (num_ref > (int)video->currSeqParams->num_ref_frames)
  400. {
  401. return AVC_FAIL; /* out of range */
  402. }
  403. return AVC_SUCCESS;
  404. }
  405. AVCStatus sliding_window_process(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb)
  406. {
  407. int ii, numShortTerm, numLongTerm;
  408. int32 MinFrameNumWrap;
  409. int MinIdx;
  410. numShortTerm = 0;
  411. numLongTerm = 0;
  412. for (ii = 0; ii < dpb->num_fs; ii++)
  413. {
  414. if (dpb->fs[ii] != video->currFS) /* do not count the current frame */
  415. {
  416. if (dpb->fs[ii]->IsLongTerm)
  417. {
  418. numLongTerm++;
  419. }
  420. else if (dpb->fs[ii]->IsReference)
  421. {
  422. numShortTerm++;
  423. }
  424. }
  425. }
  426. while (numShortTerm + numLongTerm >= (int)video->currSeqParams->num_ref_frames)
  427. {
  428. /* get short-term ref frame with smallest PicOrderCnt */
  429. /* this doesn't work for all I-slice clip since PicOrderCnt will not be initialized */
  430. MinFrameNumWrap = 0x7FFFFFFF;
  431. MinIdx = -1;
  432. for (ii = 0; ii < dpb->num_fs; ii++)
  433. {
  434. if (dpb->fs[ii]->IsReference && !dpb->fs[ii]->IsLongTerm)
  435. {
  436. if (dpb->fs[ii]->FrameNumWrap < MinFrameNumWrap)
  437. {
  438. MinFrameNumWrap = dpb->fs[ii]->FrameNumWrap;
  439. MinIdx = ii;
  440. }
  441. }
  442. }
  443. if (MinIdx < 0) /* something wrong, impossible */
  444. {
  445. return AVC_FAIL;
  446. }
  447. /* mark the frame with smallest PicOrderCnt to be unused for reference */
  448. dpb->fs[MinIdx]->IsReference = 0;
  449. dpb->fs[MinIdx]->IsLongTerm = 0;
  450. dpb->fs[MinIdx]->frame.isReference = FALSE;
  451. dpb->fs[MinIdx]->frame.isLongTerm = FALSE;
  452. dpb->fs[MinIdx]->IsOutputted |= 0x02;
  453. #ifdef PV_MEMORY_POOL
  454. if (dpb->fs[MinIdx]->IsOutputted == 3)
  455. {
  456. avcHandle->CBAVC_FrameUnbind(avcHandle->userData, MinIdx);
  457. }
  458. #endif
  459. numShortTerm--;
  460. }
  461. return AVC_SUCCESS;
  462. }
  463. /* see subclause 8.2.5.4 */
  464. AVCStatus adaptive_memory_marking(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, AVCSliceHeader *sliceHdr)
  465. {
  466. int ii;
  467. ii = 0;
  468. while (ii < MAX_DEC_REF_PIC_MARKING && sliceHdr->memory_management_control_operation[ii] != 0)
  469. {
  470. switch (sliceHdr->memory_management_control_operation[ii])
  471. {
  472. case 1:
  473. MemMgrCtrlOp1(avcHandle, video, dpb, sliceHdr->difference_of_pic_nums_minus1[ii]);
  474. // update_ref_list(dpb);
  475. break;
  476. case 2:
  477. MemMgrCtrlOp2(avcHandle, dpb, sliceHdr->long_term_pic_num[ii]);
  478. break;
  479. case 3:
  480. MemMgrCtrlOp3(avcHandle, video, dpb, sliceHdr->difference_of_pic_nums_minus1[ii], sliceHdr->long_term_frame_idx[ii]);
  481. break;
  482. case 4:
  483. MemMgrCtrlOp4(avcHandle, video, dpb, sliceHdr->max_long_term_frame_idx_plus1[ii]);
  484. break;
  485. case 5:
  486. MemMgrCtrlOp5(avcHandle, video, dpb);
  487. video->currFS->FrameNum = 0; //
  488. video->currFS->PicOrderCnt = 0;
  489. break;
  490. case 6:
  491. MemMgrCtrlOp6(avcHandle, video, dpb, sliceHdr->long_term_frame_idx[ii]);
  492. break;
  493. }
  494. ii++;
  495. }
  496. if (ii == MAX_DEC_REF_PIC_MARKING)
  497. {
  498. return AVC_FAIL; /* exceed the limit */
  499. }
  500. return AVC_SUCCESS;
  501. }
  502. /* see subclause 8.2.5.4.1, mark short-term picture as "unused for reference" */
  503. void MemMgrCtrlOp1(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, int difference_of_pic_nums_minus1)
  504. {
  505. int picNumX, ii;
  506. picNumX = video->CurrPicNum - (difference_of_pic_nums_minus1 + 1);
  507. for (ii = 0; ii < dpb->num_fs; ii++)
  508. {
  509. if (dpb->fs[ii]->IsReference == 3 && dpb->fs[ii]->IsLongTerm == 0)
  510. {
  511. if (dpb->fs[ii]->frame.PicNum == picNumX)
  512. {
  513. unmark_for_reference(avcHandle, dpb, ii);
  514. return ;
  515. }
  516. }
  517. }
  518. return ;
  519. }
  520. /* see subclause 8.2.5.4.2 mark long-term picture as "unused for reference" */
  521. void MemMgrCtrlOp2(AVCHandle *avcHandle, AVCDecPicBuffer *dpb, int long_term_pic_num)
  522. {
  523. int ii;
  524. for (ii = 0; ii < dpb->num_fs; ii++)
  525. {
  526. if (dpb->fs[ii]->IsLongTerm == 3)
  527. {
  528. if (dpb->fs[ii]->frame.LongTermPicNum == long_term_pic_num)
  529. {
  530. unmark_for_reference(avcHandle, dpb, ii);
  531. }
  532. }
  533. }
  534. }
  535. /* see subclause 8.2.5.4.3 assign LongTermFrameIdx to a short-term ref picture */
  536. void MemMgrCtrlOp3(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, uint difference_of_pic_nums_minus1,
  537. uint long_term_frame_idx)
  538. {
  539. int picNumX, ii;
  540. picNumX = video->CurrPicNum - (difference_of_pic_nums_minus1 + 1);
  541. /* look for fs[i] with long_term_frame_idx */
  542. unmark_long_term_frame_for_reference_by_frame_idx(avcHandle, dpb, long_term_frame_idx);
  543. /* now mark the picture with picNumX to long term frame idx */
  544. for (ii = 0; ii < dpb->num_fs; ii++)
  545. {
  546. if (dpb->fs[ii]->IsReference == 3)
  547. {
  548. if ((dpb->fs[ii]->frame.isLongTerm == FALSE) && (dpb->fs[ii]->frame.PicNum == picNumX))
  549. {
  550. dpb->fs[ii]->LongTermFrameIdx = long_term_frame_idx;
  551. dpb->fs[ii]->frame.LongTermPicNum = long_term_frame_idx;
  552. dpb->fs[ii]->frame.isLongTerm = TRUE;
  553. dpb->fs[ii]->IsLongTerm = 3;
  554. return;
  555. }
  556. }
  557. }
  558. }
  559. /* see subclause 8.2.5.4.4, MaxLongTermFrameIdx */
  560. void MemMgrCtrlOp4(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, uint max_long_term_frame_idx_plus1)
  561. {
  562. int ii;
  563. video->MaxLongTermFrameIdx = max_long_term_frame_idx_plus1 - 1;
  564. /* then mark long term frame with exceeding LongTermFrameIdx to unused for reference. */
  565. for (ii = 0; ii < dpb->num_fs; ii++)
  566. {
  567. if (dpb->fs[ii]->IsLongTerm && dpb->fs[ii] != video->currFS)
  568. {
  569. if (dpb->fs[ii]->LongTermFrameIdx > video->MaxLongTermFrameIdx)
  570. {
  571. unmark_for_reference(avcHandle, dpb, ii);
  572. }
  573. }
  574. }
  575. }
  576. /* see subclause 8.2.5.4.5 mark all reference picture as "unused for reference" and setting
  577. MaxLongTermFrameIdx to "no long-term frame indices" */
  578. void MemMgrCtrlOp5(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb)
  579. {
  580. int ii;
  581. video->MaxLongTermFrameIdx = -1;
  582. for (ii = 0; ii < dpb->num_fs; ii++) /* including the current frame ??????*/
  583. {
  584. if (dpb->fs[ii] != video->currFS) // MC_FIX
  585. {
  586. unmark_for_reference(avcHandle, dpb, ii);
  587. }
  588. }
  589. video->mem_mgr_ctrl_eq_5 = TRUE;
  590. }
  591. /* see subclause 8.2.5.4.6 assing long-term frame index to the current picture */
  592. void MemMgrCtrlOp6(AVCHandle *avcHandle, AVCCommonObj *video, AVCDecPicBuffer *dpb, uint long_term_frame_idx)
  593. {
  594. unmark_long_term_frame_for_reference_by_frame_idx(avcHandle, dpb, long_term_frame_idx);
  595. video->currFS->IsLongTerm = 3;
  596. video->currFS->IsReference = 3;
  597. video->currPic->isLongTerm = TRUE;
  598. video->currPic->isReference = TRUE;
  599. video->currFS->LongTermFrameIdx = long_term_frame_idx;
  600. }
  601. void unmark_for_reference(AVCHandle *avcHandle, AVCDecPicBuffer *dpb, uint idx)
  602. {
  603. AVCFrameStore *fs = dpb->fs[idx];
  604. fs->frame.isReference = FALSE;
  605. fs->frame.isLongTerm = FALSE;
  606. fs->IsLongTerm = 0;
  607. fs->IsReference = 0;
  608. fs->IsOutputted |= 0x02;
  609. #ifdef PV_MEMORY_POOL
  610. if (fs->IsOutputted == 3)
  611. {
  612. avcHandle->CBAVC_FrameUnbind(avcHandle->userData, idx);
  613. }
  614. #endif
  615. return ;
  616. }
  617. void unmark_long_term_frame_for_reference_by_frame_idx(AVCHandle *avcHandle, AVCDecPicBuffer *dpb, uint long_term_frame_idx)
  618. {
  619. int ii;
  620. for (ii = 0; ii < dpb->num_fs; ii++)
  621. {
  622. if (dpb->fs[ii]->IsLongTerm && (dpb->fs[ii]->LongTermFrameIdx == (int)long_term_frame_idx))
  623. {
  624. unmark_for_reference(avcHandle, dpb, ii);
  625. }
  626. }
  627. }