PageRenderTime 168ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/Show/avc/reflist.cpp

http://github.com/mbebenita/Broadway
C++ | 596 lines | 471 code | 79 blank | 46 comment | 115 complexity | b2ef779b5d544860589a3ab6a577f487 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. /** see subclause 8.2.4 Decoding process for reference picture lists construction. */
  20. OSCL_EXPORT_REF void RefListInit(AVCCommonObj *video)
  21. {
  22. AVCSliceHeader *sliceHdr = video->sliceHdr;
  23. AVCDecPicBuffer *dpb = video->decPicBuf;
  24. int slice_type = video->slice_type;
  25. int i, list0idx;
  26. AVCPictureData *tmp_s;
  27. list0idx = 0;
  28. if (slice_type == AVC_I_SLICE)
  29. {
  30. video->refList0Size = 0;
  31. video->refList1Size = 0;
  32. /* we still have to calculate FrameNumWrap to make sure that all I-slice clip
  33. can perform sliding_window_operation properly. */
  34. for (i = 0; i < dpb->num_fs; i++)
  35. {
  36. if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
  37. {
  38. /* subclause 8.2.4.1 Decoding process for picture numbers. */
  39. if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
  40. {
  41. dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
  42. }
  43. else
  44. {
  45. dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
  46. }
  47. dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
  48. }
  49. }
  50. return ;
  51. }
  52. if (slice_type == AVC_P_SLICE)
  53. {
  54. /* Calculate FrameNumWrap and PicNum */
  55. for (i = 0; i < dpb->num_fs; i++)
  56. {
  57. if ((dpb->fs[i]->IsReference == 3) && (!dpb->fs[i]->IsLongTerm))
  58. {
  59. /* subclause 8.2.4.1 Decoding process for picture numbers. */
  60. if (dpb->fs[i]->FrameNum > (int)sliceHdr->frame_num)
  61. {
  62. dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum - video->MaxFrameNum;
  63. }
  64. else
  65. {
  66. dpb->fs[i]->FrameNumWrap = dpb->fs[i]->FrameNum;
  67. }
  68. dpb->fs[i]->frame.PicNum = dpb->fs[i]->FrameNumWrap;
  69. video->RefPicList0[list0idx++] = &(dpb->fs[i]->frame);
  70. }
  71. }
  72. if (list0idx == 0)
  73. {
  74. dpb->fs[0]->IsReference = 3;
  75. video->RefPicList0[0] = &(dpb->fs[0]->frame);
  76. list0idx = 1;
  77. }
  78. /* order list 0 by PicNum from max to min, see subclause 8.2.4.2.1 */
  79. SortPicByPicNum(video->RefPicList0, list0idx);
  80. video->refList0Size = list0idx;
  81. /* long term handling */
  82. for (i = 0; i < dpb->num_fs; i++)
  83. {
  84. if (dpb->fs[i]->IsLongTerm == 3)
  85. {
  86. /* subclause 8.2.4.1 Decoding process for picture numbers. */
  87. dpb->fs[i]->frame.LongTermPicNum = dpb->fs[i]->LongTermFrameIdx;
  88. video->RefPicList0[list0idx++] = &(dpb->fs[i]->frame);
  89. }
  90. }
  91. /* order PicNum from min to max, see subclause 8.2.4.2.1 */
  92. SortPicByPicNumLongTerm(&(video->RefPicList0[video->refList0Size]), list0idx - video->refList0Size);
  93. video->refList0Size = list0idx;
  94. video->refList1Size = 0;
  95. }
  96. if ((video->refList0Size == video->refList1Size) && (video->refList0Size > 1))
  97. {
  98. /* check if lists are identical, if yes swap first two elements of listX[1] */
  99. /* last paragraph of subclause 8.2.4.2.4 */
  100. for (i = 0; i < video->refList0Size; i++)
  101. {
  102. if (video->RefPicList0[i] != video->RefPicList1[i])
  103. {
  104. break;
  105. }
  106. }
  107. if (i == video->refList0Size)
  108. {
  109. tmp_s = video->RefPicList1[0];
  110. video->RefPicList1[0] = video->RefPicList1[1];
  111. video->RefPicList1[1] = tmp_s;
  112. }
  113. }
  114. /* set max size */
  115. video->refList0Size = AVC_MIN(video->refList0Size, (int)video->sliceHdr->num_ref_idx_l0_active_minus1 + 1);
  116. video->refList1Size = AVC_MIN(video->refList1Size, (int)video->sliceHdr->num_ref_idx_l1_active_minus1 + 1);
  117. return ;
  118. }
  119. /* see subclause 8.2.4.3 */
  120. OSCL_EXPORT_REF AVCStatus ReOrderList(AVCCommonObj *video)
  121. {
  122. AVCSliceHeader *sliceHdr = video->sliceHdr;
  123. AVCStatus status = AVC_SUCCESS;
  124. int slice_type = video->slice_type;
  125. if (slice_type != AVC_I_SLICE)
  126. {
  127. if (sliceHdr->ref_pic_list_reordering_flag_l0)
  128. {
  129. status = ReorderRefPicList(video, 0);
  130. if (status != AVC_SUCCESS)
  131. return status;
  132. }
  133. if (video->refList0Size == 0)
  134. {
  135. return AVC_FAIL;
  136. }
  137. }
  138. return status;
  139. }
  140. AVCStatus ReorderRefPicList(AVCCommonObj *video, int isL1)
  141. {
  142. AVCSliceHeader *sliceHdr = video->sliceHdr;
  143. AVCStatus status;
  144. int *list_size;
  145. int num_ref_idx_lX_active_minus1;
  146. uint *remapping_of_pic_nums_idc;
  147. int *abs_diff_pic_num_minus1;
  148. int *long_term_pic_idx;
  149. int i;
  150. int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
  151. int refIdxLX = 0;
  152. void* tmp;
  153. if (!isL1) /* list 0 */
  154. {
  155. list_size = &(video->refList0Size);
  156. num_ref_idx_lX_active_minus1 = sliceHdr->num_ref_idx_l0_active_minus1;
  157. remapping_of_pic_nums_idc = sliceHdr->reordering_of_pic_nums_idc_l0;
  158. tmp = (void*)sliceHdr->abs_diff_pic_num_minus1_l0;
  159. abs_diff_pic_num_minus1 = (int*) tmp;
  160. tmp = (void*)sliceHdr->long_term_pic_num_l0;
  161. long_term_pic_idx = (int*) tmp;
  162. }
  163. else
  164. {
  165. list_size = &(video->refList1Size);
  166. num_ref_idx_lX_active_minus1 = sliceHdr->num_ref_idx_l1_active_minus1;
  167. remapping_of_pic_nums_idc = sliceHdr->reordering_of_pic_nums_idc_l1;
  168. tmp = (void*) sliceHdr->abs_diff_pic_num_minus1_l1;
  169. abs_diff_pic_num_minus1 = (int*) tmp;
  170. tmp = (void*) sliceHdr->long_term_pic_num_l1;
  171. long_term_pic_idx = (int*)tmp;
  172. }
  173. maxPicNum = video->MaxPicNum;
  174. currPicNum = video->CurrPicNum;
  175. picNumLXPred = currPicNum; /* initial value */
  176. for (i = 0; remapping_of_pic_nums_idc[i] != 3; i++)
  177. {
  178. if ((remapping_of_pic_nums_idc[i] > 3) || (i >= MAX_REF_PIC_LIST_REORDERING))
  179. {
  180. return AVC_FAIL; /* out of range */
  181. }
  182. /* see subclause 8.2.4.3.1 */
  183. if (remapping_of_pic_nums_idc[i] < 2)
  184. {
  185. if (remapping_of_pic_nums_idc[i] == 0)
  186. {
  187. if (picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) < 0)
  188. picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) + maxPicNum;
  189. else
  190. picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1);
  191. }
  192. else /* (remapping_of_pic_nums_idc[i] == 1) */
  193. {
  194. if (picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) >= maxPicNum)
  195. picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) - maxPicNum;
  196. else
  197. picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1);
  198. }
  199. picNumLXPred = picNumLXNoWrap; /* prediction for the next one */
  200. if (picNumLXNoWrap > currPicNum)
  201. picNumLX = picNumLXNoWrap - maxPicNum;
  202. else
  203. picNumLX = picNumLXNoWrap;
  204. status = ReorderShortTerm(video, picNumLX, &refIdxLX, isL1);
  205. if (status != AVC_SUCCESS)
  206. {
  207. return status;
  208. }
  209. }
  210. else /* (remapping_of_pic_nums_idc[i] == 2), subclause 8.2.4.3.2 */
  211. {
  212. status = ReorderLongTerm(video, long_term_pic_idx[i], &refIdxLX, isL1);
  213. if (status != AVC_SUCCESS)
  214. {
  215. return status;
  216. }
  217. }
  218. }
  219. /* that's a definition */
  220. *list_size = num_ref_idx_lX_active_minus1 + 1;
  221. return AVC_SUCCESS;
  222. }
  223. /* see subclause 8.2.4.3.1 */
  224. AVCStatus ReorderShortTerm(AVCCommonObj *video, int picNumLX, int *refIdxLX, int isL1)
  225. {
  226. int cIdx, nIdx;
  227. int num_ref_idx_lX_active_minus1;
  228. AVCPictureData *picLX, **RefPicListX;
  229. if (!isL1) /* list 0 */
  230. {
  231. RefPicListX = video->RefPicList0;
  232. num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
  233. }
  234. else
  235. {
  236. RefPicListX = video->RefPicList1;
  237. num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
  238. }
  239. picLX = GetShortTermPic(video, picNumLX);
  240. if (picLX == NULL)
  241. {
  242. return AVC_FAIL;
  243. }
  244. /* Note RefPicListX has to access element number num_ref_idx_lX_active */
  245. /* There could be access violation here. */
  246. if (num_ref_idx_lX_active_minus1 + 1 >= MAX_REF_PIC_LIST)
  247. {
  248. return AVC_FAIL;
  249. }
  250. for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
  251. {
  252. RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
  253. }
  254. RefPicListX[(*refIdxLX)++ ] = picLX;
  255. nIdx = *refIdxLX;
  256. for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
  257. {
  258. if (RefPicListX[ cIdx ])
  259. {
  260. if ((RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->PicNum != picNumLX))
  261. {
  262. RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
  263. }
  264. }
  265. }
  266. return AVC_SUCCESS;
  267. }
  268. /* see subclause 8.2.4.3.2 */
  269. AVCStatus ReorderLongTerm(AVCCommonObj *video, int LongTermPicNum, int *refIdxLX, int isL1)
  270. {
  271. AVCPictureData **RefPicListX;
  272. int num_ref_idx_lX_active_minus1;
  273. int cIdx, nIdx;
  274. AVCPictureData *picLX;
  275. if (!isL1) /* list 0 */
  276. {
  277. RefPicListX = video->RefPicList0;
  278. num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l0_active_minus1;
  279. }
  280. else
  281. {
  282. RefPicListX = video->RefPicList1;
  283. num_ref_idx_lX_active_minus1 = video->sliceHdr->num_ref_idx_l1_active_minus1;
  284. }
  285. picLX = GetLongTermPic(video, LongTermPicNum);
  286. if (picLX == NULL)
  287. {
  288. return AVC_FAIL;
  289. }
  290. /* Note RefPicListX has to access element number num_ref_idx_lX_active */
  291. /* There could be access violation here. */
  292. if (num_ref_idx_lX_active_minus1 + 1 >= MAX_REF_PIC_LIST)
  293. {
  294. return AVC_FAIL;
  295. }
  296. for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
  297. RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
  298. RefPicListX[(*refIdxLX)++ ] = picLX;
  299. nIdx = *refIdxLX;
  300. for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++)
  301. {
  302. if ((!RefPicListX[ cIdx ]->isLongTerm) || ((int)RefPicListX[ cIdx ]->LongTermPicNum != LongTermPicNum))
  303. {
  304. RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
  305. }
  306. }
  307. return AVC_SUCCESS;
  308. }
  309. AVCPictureData* GetShortTermPic(AVCCommonObj *video, int picNum)
  310. {
  311. int i;
  312. AVCDecPicBuffer *dpb = video->decPicBuf;
  313. for (i = 0; i < dpb->num_fs; i++)
  314. {
  315. if (dpb->fs[i]->IsReference == 3)
  316. {
  317. if ((dpb->fs[i]->frame.isLongTerm == FALSE) && (dpb->fs[i]->frame.PicNum == picNum))
  318. {
  319. return &(dpb->fs[i]->frame);
  320. }
  321. }
  322. }
  323. return NULL;
  324. }
  325. AVCPictureData* GetLongTermPic(AVCCommonObj *video, int LongtermPicNum)
  326. {
  327. AVCDecPicBuffer *dpb = video->decPicBuf;
  328. int i;
  329. for (i = 0; i < dpb->num_fs; i++)
  330. {
  331. if (dpb->fs[i]->IsReference == 3)
  332. {
  333. if ((dpb->fs[i]->frame.isLongTerm == TRUE) && (dpb->fs[i]->frame.LongTermPicNum == LongtermPicNum))
  334. {
  335. return &(dpb->fs[i]->frame);
  336. }
  337. }
  338. }
  339. return NULL;
  340. }
  341. int is_short_ref(AVCPictureData *s)
  342. {
  343. return ((s->isReference) && !(s->isLongTerm));
  344. }
  345. int is_long_ref(AVCPictureData *s)
  346. {
  347. return ((s->isReference) && (s->isLongTerm));
  348. }
  349. /* sort by PicNum, descending order */
  350. void SortPicByPicNum(AVCPictureData *data[], int num)
  351. {
  352. int i, j;
  353. AVCPictureData *temp;
  354. for (i = 0; i < num - 1; i++)
  355. {
  356. for (j = i + 1; j < num; j++)
  357. {
  358. if (data[j]->PicNum > data[i]->PicNum)
  359. {
  360. temp = data[j];
  361. data[j] = data[i];
  362. data[i] = temp;
  363. }
  364. }
  365. }
  366. return ;
  367. }
  368. /* sort by PicNum, ascending order */
  369. void SortPicByPicNumLongTerm(AVCPictureData *data[], int num)
  370. {
  371. int i, j;
  372. AVCPictureData *temp;
  373. for (i = 0; i < num - 1; i++)
  374. {
  375. for (j = i + 1; j < num; j++)
  376. {
  377. if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
  378. {
  379. temp = data[j];
  380. data[j] = data[i];
  381. data[i] = temp;
  382. }
  383. }
  384. }
  385. return ;
  386. }
  387. /* sort by FrameNumWrap, descending order */
  388. void SortFrameByFrameNumWrap(AVCFrameStore *data[], int num)
  389. {
  390. int i, j;
  391. AVCFrameStore *temp;
  392. for (i = 0; i < num - 1; i++)
  393. {
  394. for (j = i + 1; j < num; j++)
  395. {
  396. if (data[j]->FrameNumWrap > data[i]->FrameNumWrap)
  397. {
  398. temp = data[j];
  399. data[j] = data[i];
  400. data[i] = temp;
  401. }
  402. }
  403. }
  404. return ;
  405. }
  406. /* sort frames by LongTermFrameIdx, ascending order */
  407. void SortFrameByLTFrameIdx(AVCFrameStore *data[], int num)
  408. {
  409. int i, j;
  410. AVCFrameStore *temp;
  411. for (i = 0; i < num - 1; i++)
  412. {
  413. for (j = i + 1; j < num; j++)
  414. {
  415. if (data[j]->LongTermFrameIdx < data[i]->LongTermFrameIdx)
  416. {
  417. temp = data[j];
  418. data[j] = data[i];
  419. data[i] = temp;
  420. }
  421. }
  422. }
  423. return ;
  424. }
  425. /* sort PictureData by POC in descending order */
  426. void SortPicByPOC(AVCPictureData *data[], int num, int descending)
  427. {
  428. int i, j;
  429. AVCPictureData *temp;
  430. if (descending)
  431. {
  432. for (i = 0; i < num - 1; i++)
  433. {
  434. for (j = i + 1; j < num; j++)
  435. {
  436. if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
  437. {
  438. temp = data[j];
  439. data[j] = data[i];
  440. data[i] = temp;
  441. }
  442. }
  443. }
  444. }
  445. else
  446. {
  447. for (i = 0; i < num - 1; i++)
  448. {
  449. for (j = i + 1; j < num; j++)
  450. {
  451. if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)
  452. {
  453. temp = data[j];
  454. data[j] = data[i];
  455. data[i] = temp;
  456. }
  457. }
  458. }
  459. }
  460. return ;
  461. }
  462. /* sort PictureData by LongTermPicNum in ascending order */
  463. void SortPicByLTPicNum(AVCPictureData *data[], int num)
  464. {
  465. int i, j;
  466. AVCPictureData *temp;
  467. for (i = 0; i < num - 1; i++)
  468. {
  469. for (j = i + 1; j < num; j++)
  470. {
  471. if (data[j]->LongTermPicNum < data[i]->LongTermPicNum)
  472. {
  473. temp = data[j];
  474. data[j] = data[i];
  475. data[i] = temp;
  476. }
  477. }
  478. }
  479. return ;
  480. }
  481. /* sort by PicOrderCnt, descending order */
  482. void SortFrameByPOC(AVCFrameStore *data[], int num, int descending)
  483. {
  484. int i, j;
  485. AVCFrameStore *temp;
  486. if (descending)
  487. {
  488. for (i = 0; i < num - 1; i++)
  489. {
  490. for (j = i + 1; j < num; j++)
  491. {
  492. if (data[j]->PicOrderCnt > data[i]->PicOrderCnt)
  493. {
  494. temp = data[j];
  495. data[j] = data[i];
  496. data[i] = temp;
  497. }
  498. }
  499. }
  500. }
  501. else
  502. {
  503. for (i = 0; i < num - 1; i++)
  504. {
  505. for (j = i + 1; j < num; j++)
  506. {
  507. if (data[j]->PicOrderCnt < data[i]->PicOrderCnt)
  508. {
  509. temp = data[j];
  510. data[j] = data[i];
  511. data[i] = temp;
  512. }
  513. }
  514. }
  515. }
  516. return ;
  517. }