You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

776 lines
26KB

  1. /*
  2. * HEVC video decoder
  3. *
  4. * Copyright (C) 2012 - 2013 Guillaume Martres
  5. * Copyright (C) 2013 Anand Meher Kotra
  6. *
  7. * This file is part of FFmpeg.
  8. *
  9. * FFmpeg is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * FFmpeg is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with FFmpeg; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include "hevc.h"
  24. static const uint8_t l0_l1_cand_idx[12][2] = {
  25. { 0, 1, },
  26. { 1, 0, },
  27. { 0, 2, },
  28. { 2, 0, },
  29. { 1, 2, },
  30. { 2, 1, },
  31. { 0, 3, },
  32. { 3, 0, },
  33. { 1, 3, },
  34. { 3, 1, },
  35. { 2, 3, },
  36. { 3, 2, },
  37. };
  38. void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
  39. int nPbW, int nPbH)
  40. {
  41. HEVCLocalContext *lc = s->HEVClc;
  42. int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
  43. int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
  44. lc->na.cand_up = (lc->ctb_up_flag || y0b);
  45. lc->na.cand_left = (lc->ctb_left_flag || x0b);
  46. lc->na.cand_up_left = (!x0b && !y0b) ? lc->ctb_up_left_flag : lc->na.cand_left && lc->na.cand_up;
  47. lc->na.cand_up_right_sap =
  48. ((x0b + nPbW) == (1 << s->sps->log2_ctb_size)) ?
  49. lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
  50. lc->na.cand_up_right =
  51. lc->na.cand_up_right_sap
  52. && (x0 + nPbW) < lc->end_of_tiles_x;
  53. lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left;
  54. }
  55. /*
  56. * 6.4.1 Derivation process for z-scan order block availability
  57. */
  58. static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr,
  59. int xN, int yN)
  60. {
  61. #define MIN_TB_ADDR_ZS(x, y) \
  62. s->pps->min_tb_addr_zs[(y) * (s->sps->tb_mask+2) + (x)]
  63. int xCurr_ctb = xCurr >> s->sps->log2_ctb_size;
  64. int yCurr_ctb = yCurr >> s->sps->log2_ctb_size;
  65. int xN_ctb = xN >> s->sps->log2_ctb_size;
  66. int yN_ctb = yN >> s->sps->log2_ctb_size;
  67. if( yN_ctb < yCurr_ctb || xN_ctb < xCurr_ctb )
  68. return 1;
  69. else {
  70. int Curr = MIN_TB_ADDR_ZS((xCurr >> s->sps->log2_min_tb_size) & s->sps->tb_mask,
  71. (yCurr >> s->sps->log2_min_tb_size) & s->sps->tb_mask);
  72. int N = MIN_TB_ADDR_ZS((xN >> s->sps->log2_min_tb_size) & s->sps->tb_mask,
  73. (yN >> s->sps->log2_min_tb_size) & s->sps->tb_mask);
  74. return N <= Curr;
  75. }
  76. }
  77. //check if the two luma locations belong to the same mostion estimation region
  78. static av_always_inline int is_diff_mer(HEVCContext *s, int xN, int yN, int xP, int yP)
  79. {
  80. uint8_t plevel = s->pps->log2_parallel_merge_level;
  81. return xN >> plevel == xP >> plevel &&
  82. yN >> plevel == yP >> plevel;
  83. }
  84. #define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x))
  85. #define MATCH(x) (A.x == B.x)
  86. // check if the mv's and refidx are the same between A and B
  87. static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B)
  88. {
  89. int a_pf = A.pred_flag;
  90. int b_pf = B.pred_flag;
  91. if (a_pf == b_pf) {
  92. if (a_pf == PF_BI) {
  93. return MATCH(ref_idx[0]) && MATCH_MV(mv[0]) &&
  94. MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
  95. } else if (a_pf == PF_L0) {
  96. return MATCH(ref_idx[0]) && MATCH_MV(mv[0]);
  97. } else if (a_pf == PF_L1) {
  98. return MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
  99. }
  100. }
  101. return 0;
  102. }
  103. static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb)
  104. {
  105. int tx, scale_factor;
  106. td = av_clip_int8(td);
  107. tb = av_clip_int8(tb);
  108. tx = (0x4000 + abs(td / 2)) / td;
  109. scale_factor = av_clip((tb * tx + 32) >> 6, -4096, 4095);
  110. dst->x = av_clip_int16((scale_factor * src->x + 127 +
  111. (scale_factor * src->x < 0)) >> 8);
  112. dst->y = av_clip_int16((scale_factor * src->y + 127 +
  113. (scale_factor * src->y < 0)) >> 8);
  114. }
  115. static int check_mvset(Mv *mvLXCol, Mv *mvCol,
  116. int colPic, int poc,
  117. RefPicList *refPicList, int X, int refIdxLx,
  118. RefPicList *refPicList_col, int listCol, int refidxCol)
  119. {
  120. int cur_lt = refPicList[X].isLongTerm[refIdxLx];
  121. int col_lt = refPicList_col[listCol].isLongTerm[refidxCol];
  122. int col_poc_diff, cur_poc_diff;
  123. if (cur_lt != col_lt) {
  124. mvLXCol->x = 0;
  125. mvLXCol->y = 0;
  126. return 0;
  127. }
  128. col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol];
  129. cur_poc_diff = poc - refPicList[X].list[refIdxLx];
  130. if (cur_lt || col_poc_diff == cur_poc_diff || !col_poc_diff) {
  131. mvLXCol->x = mvCol->x;
  132. mvLXCol->y = mvCol->y;
  133. } else {
  134. mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
  135. }
  136. return 1;
  137. }
  138. #define CHECK_MVSET(l) \
  139. check_mvset(mvLXCol, temp_col.mv + l, \
  140. colPic, s->poc, \
  141. refPicList, X, refIdxLx, \
  142. refPicList_col, L ## l, temp_col.ref_idx[l])
  143. // derive the motion vectors section 8.5.3.1.8
  144. static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col,
  145. int refIdxLx, Mv *mvLXCol, int X,
  146. int colPic, RefPicList *refPicList_col)
  147. {
  148. RefPicList *refPicList = s->ref->refPicList;
  149. if (temp_col.pred_flag == PF_INTRA)
  150. return 0;
  151. if (!(temp_col.pred_flag & PF_L0))
  152. return CHECK_MVSET(1);
  153. else if (temp_col.pred_flag == PF_L0)
  154. return CHECK_MVSET(0);
  155. else if (temp_col.pred_flag == PF_BI) {
  156. int check_diffpicount = 0;
  157. int i, j;
  158. for (j = 0; j < 2; j++) {
  159. for (i = 0; i < refPicList[j].nb_refs; i++) {
  160. if (refPicList[j].list[i] > s->poc) {
  161. check_diffpicount++;
  162. break;
  163. }
  164. }
  165. }
  166. if (!check_diffpicount) {
  167. if (X==0)
  168. return CHECK_MVSET(0);
  169. else
  170. return CHECK_MVSET(1);
  171. } else {
  172. if (s->sh.collocated_list == L1)
  173. return CHECK_MVSET(0);
  174. else
  175. return CHECK_MVSET(1);
  176. }
  177. }
  178. return 0;
  179. }
  180. #define TAB_MVF(x, y) \
  181. tab_mvf[(y) * min_pu_width + x]
  182. #define TAB_MVF_PU(v) \
  183. TAB_MVF(((x ## v) >> s->sps->log2_min_pu_size), \
  184. ((y ## v) >> s->sps->log2_min_pu_size))
  185. #define DERIVE_TEMPORAL_COLOCATED_MVS \
  186. derive_temporal_colocated_mvs(s, temp_col, \
  187. refIdxLx, mvLXCol, X, colPic, \
  188. ff_hevc_get_ref_list(s, ref, x, y))
  189. /*
  190. * 8.5.3.1.7 temporal luma motion vector prediction
  191. */
  192. static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0,
  193. int nPbW, int nPbH, int refIdxLx,
  194. Mv *mvLXCol, int X)
  195. {
  196. MvField *tab_mvf;
  197. MvField temp_col;
  198. int x, y, x_pu, y_pu;
  199. int min_pu_width = s->sps->min_pu_width;
  200. int availableFlagLXCol = 0;
  201. int colPic;
  202. HEVCFrame *ref = s->ref->collocated_ref;
  203. if (!ref)
  204. return 0;
  205. tab_mvf = ref->tab_mvf;
  206. colPic = ref->poc;
  207. //bottom right collocated motion vector
  208. x = x0 + nPbW;
  209. y = y0 + nPbH;
  210. if (tab_mvf &&
  211. (y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) &&
  212. y < s->sps->height &&
  213. x < s->sps->width) {
  214. x &= ~15;
  215. y &= ~15;
  216. if (s->threads_type == FF_THREAD_FRAME)
  217. ff_thread_await_progress(&ref->tf, y, 0);
  218. x_pu = x >> s->sps->log2_min_pu_size;
  219. y_pu = y >> s->sps->log2_min_pu_size;
  220. temp_col = TAB_MVF(x_pu, y_pu);
  221. availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
  222. }
  223. // derive center collocated motion vector
  224. if (tab_mvf && !availableFlagLXCol) {
  225. x = x0 + (nPbW >> 1);
  226. y = y0 + (nPbH >> 1);
  227. x &= ~15;
  228. y &= ~15;
  229. if (s->threads_type == FF_THREAD_FRAME)
  230. ff_thread_await_progress(&ref->tf, y, 0);
  231. x_pu = x >> s->sps->log2_min_pu_size;
  232. y_pu = y >> s->sps->log2_min_pu_size;
  233. temp_col = TAB_MVF(x_pu, y_pu);
  234. availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
  235. }
  236. return availableFlagLXCol;
  237. }
  238. #define AVAILABLE(cand, v) \
  239. (cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA))
  240. #define PRED_BLOCK_AVAILABLE(v) \
  241. z_scan_block_avail(s, x0, y0, x ## v, y ## v)
  242. #define COMPARE_MV_REFIDX(a, b) \
  243. compare_mv_ref_idx(TAB_MVF_PU(a), TAB_MVF_PU(b))
  244. /*
  245. * 8.5.3.1.2 Derivation process for spatial merging candidates
  246. */
  247. static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
  248. int nPbW, int nPbH,
  249. int log2_cb_size,
  250. int singleMCLFlag, int part_idx,
  251. int merge_idx,
  252. struct MvField mergecandlist[])
  253. {
  254. HEVCLocalContext *lc = s->HEVClc;
  255. RefPicList *refPicList = s->ref->refPicList;
  256. MvField *tab_mvf = s->ref->tab_mvf;
  257. const int min_pu_width = s->sps->min_pu_width;
  258. const int cand_bottom_left = lc->na.cand_bottom_left;
  259. const int cand_left = lc->na.cand_left;
  260. const int cand_up_left = lc->na.cand_up_left;
  261. const int cand_up = lc->na.cand_up;
  262. const int cand_up_right = lc->na.cand_up_right_sap;
  263. const int xA1 = x0 - 1;
  264. const int yA1 = y0 + nPbH - 1;
  265. const int xB1 = x0 + nPbW - 1;
  266. const int yB1 = y0 - 1;
  267. const int xB0 = x0 + nPbW;
  268. const int yB0 = y0 - 1;
  269. const int xA0 = x0 - 1;
  270. const int yA0 = y0 + nPbH;
  271. const int xB2 = x0 - 1;
  272. const int yB2 = y0 - 1;
  273. const int nb_refs = (s->sh.slice_type == P_SLICE) ?
  274. s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
  275. int zero_idx = 0;
  276. int nb_merge_cand = 0;
  277. int nb_orig_merge_cand = 0;
  278. int is_available_a0;
  279. int is_available_a1;
  280. int is_available_b0;
  281. int is_available_b1;
  282. int is_available_b2;
  283. if (!singleMCLFlag && part_idx == 1 &&
  284. (lc->cu.part_mode == PART_Nx2N ||
  285. lc->cu.part_mode == PART_nLx2N ||
  286. lc->cu.part_mode == PART_nRx2N) ||
  287. is_diff_mer(s, xA1, yA1, x0, y0)) {
  288. is_available_a1 = 0;
  289. } else {
  290. is_available_a1 = AVAILABLE(cand_left, A1);
  291. if (is_available_a1) {
  292. mergecandlist[nb_merge_cand] = TAB_MVF_PU(A1);
  293. if (merge_idx == 0)
  294. return;
  295. nb_merge_cand++;
  296. }
  297. }
  298. if (!singleMCLFlag && part_idx == 1 &&
  299. (lc->cu.part_mode == PART_2NxN ||
  300. lc->cu.part_mode == PART_2NxnU ||
  301. lc->cu.part_mode == PART_2NxnD) ||
  302. is_diff_mer(s, xB1, yB1, x0, y0)) {
  303. is_available_b1 = 0;
  304. } else {
  305. is_available_b1 = AVAILABLE(cand_up, B1);
  306. if (is_available_b1 &&
  307. !(is_available_a1 && COMPARE_MV_REFIDX(B1, A1))) {
  308. mergecandlist[nb_merge_cand] = TAB_MVF_PU(B1);
  309. if (merge_idx == nb_merge_cand)
  310. return;
  311. nb_merge_cand++;
  312. }
  313. }
  314. // above right spatial merge candidate
  315. is_available_b0 = AVAILABLE(cand_up_right, B0) &&
  316. xB0 < s->sps->width &&
  317. PRED_BLOCK_AVAILABLE(B0) &&
  318. !is_diff_mer(s, xB0, yB0, x0, y0);
  319. if (is_available_b0 &&
  320. !(is_available_b1 && COMPARE_MV_REFIDX(B0, B1))) {
  321. mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0);
  322. if (merge_idx == nb_merge_cand)
  323. return;
  324. nb_merge_cand++;
  325. }
  326. // left bottom spatial merge candidate
  327. is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
  328. yA0 < s->sps->height &&
  329. PRED_BLOCK_AVAILABLE(A0) &&
  330. !is_diff_mer(s, xA0, yA0, x0, y0);
  331. if (is_available_a0 &&
  332. !(is_available_a1 && COMPARE_MV_REFIDX(A0, A1))) {
  333. mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0);
  334. if (merge_idx == nb_merge_cand)
  335. return;
  336. nb_merge_cand++;
  337. }
  338. // above left spatial merge candidate
  339. is_available_b2 = AVAILABLE(cand_up_left, B2) &&
  340. !is_diff_mer(s, xB2, yB2, x0, y0);
  341. if (is_available_b2 &&
  342. !(is_available_a1 && COMPARE_MV_REFIDX(B2, A1)) &&
  343. !(is_available_b1 && COMPARE_MV_REFIDX(B2, B1)) &&
  344. nb_merge_cand != 4) {
  345. mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2);
  346. if (merge_idx == nb_merge_cand)
  347. return;
  348. nb_merge_cand++;
  349. }
  350. // temporal motion vector candidate
  351. if (s->sh.slice_temporal_mvp_enabled_flag &&
  352. nb_merge_cand < s->sh.max_num_merge_cand) {
  353. Mv mv_l0_col, mv_l1_col;
  354. int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
  355. 0, &mv_l0_col, 0);
  356. int available_l1 = (s->sh.slice_type == B_SLICE) ?
  357. temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
  358. 0, &mv_l1_col, 1) : 0;
  359. if (available_l0 || available_l1) {
  360. mergecandlist[nb_merge_cand].pred_flag = available_l0 + (available_l1 << 1);
  361. if (available_l0) {
  362. mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
  363. mergecandlist[nb_merge_cand].ref_idx[0] = 0;
  364. }
  365. if (available_l1) {
  366. mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
  367. mergecandlist[nb_merge_cand].ref_idx[1] = 0;
  368. }
  369. if (merge_idx == nb_merge_cand)
  370. return;
  371. nb_merge_cand++;
  372. }
  373. }
  374. nb_orig_merge_cand = nb_merge_cand;
  375. // combined bi-predictive merge candidates (applies for B slices)
  376. if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&
  377. nb_orig_merge_cand < s->sh.max_num_merge_cand) {
  378. int comb_idx = 0;
  379. for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
  380. comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
  381. int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
  382. int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
  383. MvField l0_cand = mergecandlist[l0_cand_idx];
  384. MvField l1_cand = mergecandlist[l1_cand_idx];
  385. if ((l0_cand.pred_flag & PF_L0) && (l1_cand.pred_flag & PF_L1) &&
  386. (refPicList[0].list[l0_cand.ref_idx[0]] !=
  387. refPicList[1].list[l1_cand.ref_idx[1]] ||
  388. AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {
  389. mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0];
  390. mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1];
  391. mergecandlist[nb_merge_cand].pred_flag = PF_BI;
  392. AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);
  393. AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);
  394. if (merge_idx == nb_merge_cand)
  395. return;
  396. nb_merge_cand++;
  397. }
  398. }
  399. }
  400. // append Zero motion vector candidates
  401. while (nb_merge_cand < s->sh.max_num_merge_cand) {
  402. mergecandlist[nb_merge_cand].pred_flag = PF_L0 + ((s->sh.slice_type == B_SLICE) << 1);
  403. AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);
  404. AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);
  405. mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
  406. mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
  407. if (merge_idx == nb_merge_cand)
  408. return;
  409. nb_merge_cand++;
  410. zero_idx++;
  411. }
  412. }
  413. /*
  414. * 8.5.3.1.1 Derivation process of luma Mvs for merge mode
  415. */
  416. void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW,
  417. int nPbH, int log2_cb_size, int part_idx,
  418. int merge_idx, MvField *mv)
  419. {
  420. int singleMCLFlag = 0;
  421. int nCS = 1 << log2_cb_size;
  422. LOCAL_ALIGNED(4, MvField, mergecand_list, [MRG_MAX_NUM_CANDS]);
  423. int nPbW2 = nPbW;
  424. int nPbH2 = nPbH;
  425. HEVCLocalContext *lc = s->HEVClc;
  426. if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) {
  427. singleMCLFlag = 1;
  428. x0 = lc->cu.x;
  429. y0 = lc->cu.y;
  430. nPbW = nCS;
  431. nPbH = nCS;
  432. part_idx = 0;
  433. }
  434. ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
  435. derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size,
  436. singleMCLFlag, part_idx,
  437. merge_idx, mergecand_list);
  438. if (mergecand_list[merge_idx].pred_flag == PF_BI &&
  439. (nPbW2 + nPbH2) == 12) {
  440. mergecand_list[merge_idx].pred_flag = PF_L0;
  441. }
  442. *mv = mergecand_list[merge_idx];
  443. }
  444. static av_always_inline void dist_scale(HEVCContext *s, Mv *mv,
  445. int min_pu_width, int x, int y,
  446. int elist, int ref_idx_curr, int ref_idx)
  447. {
  448. RefPicList *refPicList = s->ref->refPicList;
  449. MvField *tab_mvf = s->ref->tab_mvf;
  450. int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
  451. int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx];
  452. if (ref_pic_elist != ref_pic_curr) {
  453. int poc_diff = s->poc - ref_pic_elist;
  454. if (!poc_diff)
  455. poc_diff = 1;
  456. mv_scale(mv, mv, poc_diff, s->poc - ref_pic_curr);
  457. }
  458. }
  459. static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index,
  460. Mv *mv, int ref_idx_curr, int ref_idx)
  461. {
  462. MvField *tab_mvf = s->ref->tab_mvf;
  463. int min_pu_width = s->sps->min_pu_width;
  464. RefPicList *refPicList = s->ref->refPicList;
  465. if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) &&
  466. refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
  467. *mv = TAB_MVF(x, y).mv[pred_flag_index];
  468. return 1;
  469. }
  470. return 0;
  471. }
  472. static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index,
  473. Mv *mv, int ref_idx_curr, int ref_idx)
  474. {
  475. MvField *tab_mvf = s->ref->tab_mvf;
  476. int min_pu_width = s->sps->min_pu_width;
  477. RefPicList *refPicList = s->ref->refPicList;
  478. if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) {
  479. int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
  480. int colIsLongTerm =
  481. refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
  482. if (colIsLongTerm == currIsLongTerm) {
  483. *mv = TAB_MVF(x, y).mv[pred_flag_index];
  484. if (!currIsLongTerm)
  485. dist_scale(s, mv, min_pu_width, x, y,
  486. pred_flag_index, ref_idx_curr, ref_idx);
  487. return 1;
  488. }
  489. }
  490. return 0;
  491. }
  492. #define MP_MX(v, pred, mx) \
  493. mv_mp_mode_mx(s, \
  494. (x ## v) >> s->sps->log2_min_pu_size, \
  495. (y ## v) >> s->sps->log2_min_pu_size, \
  496. pred, &mx, ref_idx_curr, ref_idx)
  497. #define MP_MX_LT(v, pred, mx) \
  498. mv_mp_mode_mx_lt(s, \
  499. (x ## v) >> s->sps->log2_min_pu_size, \
  500. (y ## v) >> s->sps->log2_min_pu_size, \
  501. pred, &mx, ref_idx_curr, ref_idx)
  502. void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
  503. int nPbH, int log2_cb_size, int part_idx,
  504. int merge_idx, MvField *mv,
  505. int mvp_lx_flag, int LX)
  506. {
  507. HEVCLocalContext *lc = s->HEVClc;
  508. MvField *tab_mvf = s->ref->tab_mvf;
  509. int isScaledFlag_L0 = 0;
  510. int availableFlagLXA0 = 1;
  511. int availableFlagLXB0 = 1;
  512. int numMVPCandLX = 0;
  513. int min_pu_width = s->sps->min_pu_width;
  514. int xA0, yA0;
  515. int is_available_a0;
  516. int xA1, yA1;
  517. int is_available_a1;
  518. int xB0, yB0;
  519. int is_available_b0;
  520. int xB1, yB1;
  521. int is_available_b1;
  522. int xB2, yB2;
  523. int is_available_b2;
  524. Mv mvpcand_list[2] = { { 0 } };
  525. Mv mxA;
  526. Mv mxB;
  527. int ref_idx_curr;
  528. int ref_idx = 0;
  529. int pred_flag_index_l0;
  530. int pred_flag_index_l1;
  531. const int cand_bottom_left = lc->na.cand_bottom_left;
  532. const int cand_left = lc->na.cand_left;
  533. const int cand_up_left = lc->na.cand_up_left;
  534. const int cand_up = lc->na.cand_up;
  535. const int cand_up_right = lc->na.cand_up_right_sap;
  536. ref_idx_curr = LX;
  537. ref_idx = mv->ref_idx[LX];
  538. pred_flag_index_l0 = LX;
  539. pred_flag_index_l1 = !LX;
  540. // left bottom spatial candidate
  541. xA0 = x0 - 1;
  542. yA0 = y0 + nPbH;
  543. is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
  544. yA0 < s->sps->height &&
  545. PRED_BLOCK_AVAILABLE(A0);
  546. //left spatial merge candidate
  547. xA1 = x0 - 1;
  548. yA1 = y0 + nPbH - 1;
  549. is_available_a1 = AVAILABLE(cand_left, A1);
  550. if (is_available_a0 || is_available_a1)
  551. isScaledFlag_L0 = 1;
  552. if (is_available_a0) {
  553. if (MP_MX(A0, pred_flag_index_l0, mxA)) {
  554. goto b_candidates;
  555. }
  556. if (MP_MX(A0, pred_flag_index_l1, mxA)) {
  557. goto b_candidates;
  558. }
  559. }
  560. if (is_available_a1) {
  561. if (MP_MX(A1, pred_flag_index_l0, mxA)) {
  562. goto b_candidates;
  563. }
  564. if (MP_MX(A1, pred_flag_index_l1, mxA)) {
  565. goto b_candidates;
  566. }
  567. }
  568. if (is_available_a0) {
  569. if (MP_MX_LT(A0, pred_flag_index_l0, mxA)) {
  570. goto b_candidates;
  571. }
  572. if (MP_MX_LT(A0, pred_flag_index_l1, mxA)) {
  573. goto b_candidates;
  574. }
  575. }
  576. if (is_available_a1) {
  577. if (MP_MX_LT(A1, pred_flag_index_l0, mxA)) {
  578. goto b_candidates;
  579. }
  580. if (MP_MX_LT(A1, pred_flag_index_l1, mxA)) {
  581. goto b_candidates;
  582. }
  583. }
  584. availableFlagLXA0 = 0;
  585. b_candidates:
  586. // B candidates
  587. // above right spatial merge candidate
  588. xB0 = x0 + nPbW;
  589. yB0 = y0 - 1;
  590. is_available_b0 = AVAILABLE(cand_up_right, B0) &&
  591. xB0 < s->sps->width &&
  592. PRED_BLOCK_AVAILABLE(B0);
  593. // above spatial merge candidate
  594. xB1 = x0 + nPbW - 1;
  595. yB1 = y0 - 1;
  596. is_available_b1 = AVAILABLE(cand_up, B1);
  597. // above left spatial merge candidate
  598. xB2 = x0 - 1;
  599. yB2 = y0 - 1;
  600. is_available_b2 = AVAILABLE(cand_up_left, B2);
  601. // above right spatial merge candidate
  602. if (is_available_b0) {
  603. if (MP_MX(B0, pred_flag_index_l0, mxB)) {
  604. goto scalef;
  605. }
  606. if (MP_MX(B0, pred_flag_index_l1, mxB)) {
  607. goto scalef;
  608. }
  609. }
  610. // above spatial merge candidate
  611. if (is_available_b1) {
  612. if (MP_MX(B1, pred_flag_index_l0, mxB)) {
  613. goto scalef;
  614. }
  615. if (MP_MX(B1, pred_flag_index_l1, mxB)) {
  616. goto scalef;
  617. }
  618. }
  619. // above left spatial merge candidate
  620. if (is_available_b2) {
  621. if (MP_MX(B2, pred_flag_index_l0, mxB)) {
  622. goto scalef;
  623. }
  624. if (MP_MX(B2, pred_flag_index_l1, mxB)) {
  625. goto scalef;
  626. }
  627. }
  628. availableFlagLXB0 = 0;
  629. scalef:
  630. if (!isScaledFlag_L0) {
  631. if (availableFlagLXB0) {
  632. availableFlagLXA0 = 1;
  633. mxA = mxB;
  634. }
  635. availableFlagLXB0 = 0;
  636. // XB0 and L1
  637. if (is_available_b0) {
  638. availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);
  639. if (!availableFlagLXB0)
  640. availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);
  641. }
  642. if (is_available_b1 && !availableFlagLXB0) {
  643. availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);
  644. if (!availableFlagLXB0)
  645. availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);
  646. }
  647. if (is_available_b2 && !availableFlagLXB0) {
  648. availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);
  649. if (!availableFlagLXB0)
  650. availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);
  651. }
  652. }
  653. if (availableFlagLXA0)
  654. mvpcand_list[numMVPCandLX++] = mxA;
  655. if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
  656. mvpcand_list[numMVPCandLX++] = mxB;
  657. //temporal motion vector prediction candidate
  658. if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&
  659. mvp_lx_flag == numMVPCandLX) {
  660. Mv mv_col;
  661. int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
  662. nPbH, ref_idx,
  663. &mv_col, LX);
  664. if (available_col)
  665. mvpcand_list[numMVPCandLX++] = mv_col;
  666. }
  667. mv->mv[LX] = mvpcand_list[mvp_lx_flag];
  668. }