Libav
hevc_mvs.c
Go to the documentation of this file.
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 Libav.
8  *
9  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "hevc.h"
25 
26 static const uint8_t l0_l1_cand_idx[12][2] = {
27  { 0, 1, },
28  { 1, 0, },
29  { 0, 2, },
30  { 2, 0, },
31  { 1, 2, },
32  { 2, 1, },
33  { 0, 3, },
34  { 3, 0, },
35  { 1, 3, },
36  { 3, 1, },
37  { 2, 3, },
38  { 3, 2, },
39 };
40 
42  int nPbW, int nPbH)
43 {
44  HEVCLocalContext *lc = &s->HEVClc;
45  int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
46  int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
47 
48  lc->na.cand_up = (lc->ctb_up_flag || y0b);
49  lc->na.cand_left = (lc->ctb_left_flag || x0b);
50  lc->na.cand_up_left = (!x0b && !y0b) ? lc->ctb_up_left_flag : lc->na.cand_left && lc->na.cand_up;
51  lc->na.cand_up_right_sap =
52  ((x0b + nPbW) == (1 << s->sps->log2_ctb_size)) ?
53  lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
54  lc->na.cand_up_right =
55  ((x0b + nPbW) == (1 << s->sps->log2_ctb_size) ?
56  lc->ctb_up_right_flag && !y0b : lc->na.cand_up )
57  && (x0 + nPbW) < lc->end_of_tiles_x;
58  lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left;
59 }
60 
61 /*
62  * 6.4.1 Derivation process for z-scan order block availability
63  */
64 static int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr,
65  int xN, int yN)
66 {
67 #define MIN_TB_ADDR_ZS(x, y) \
68  s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)]
69  int Curr = MIN_TB_ADDR_ZS(xCurr >> s->sps->log2_min_tb_size,
70  yCurr >> s->sps->log2_min_tb_size);
71  int N;
72 
73  if (xN < 0 || yN < 0 ||
74  xN >= s->sps->width ||
75  yN >= s->sps->height)
76  return 0;
77 
78  N = MIN_TB_ADDR_ZS(xN >> s->sps->log2_min_tb_size,
79  yN >> s->sps->log2_min_tb_size);
80 
81  return N <= Curr;
82 }
83 
84 static int same_prediction_block(HEVCLocalContext *lc, int log2_cb_size,
85  int x0, int y0, int nPbW, int nPbH,
86  int xA1, int yA1, int partIdx)
87 {
88  return !(nPbW << 1 == 1 << log2_cb_size &&
89  nPbH << 1 == 1 << log2_cb_size && partIdx == 1 &&
90  lc->cu.x + nPbW > xA1 &&
91  lc->cu.y + nPbH <= yA1);
92 }
93 
94 /*
95  * 6.4.2 Derivation process for prediction block availability
96  */
97 static int check_prediction_block_available(HEVCContext *s, int log2_cb_size,
98  int x0, int y0, int nPbW, int nPbH,
99  int xA1, int yA1, int partIdx)
100 {
101  HEVCLocalContext *lc = &s->HEVClc;
102 
103  if (lc->cu.x < xA1 && lc->cu.y < yA1 &&
104  (lc->cu.x + (1 << log2_cb_size)) > xA1 &&
105  (lc->cu.y + (1 << log2_cb_size)) > yA1)
106  return same_prediction_block(lc, log2_cb_size, x0, y0,
107  nPbW, nPbH, xA1, yA1, partIdx);
108  else
109  return z_scan_block_avail(s, x0, y0, xA1, yA1);
110 }
111 
112 //check if the two luma locations belong to the same mostion estimation region
113 static int isDiffMER(HEVCContext *s, int xN, int yN, int xP, int yP)
114 {
116 
117  return xN >> plevel == xP >> plevel &&
118  yN >> plevel == yP >> plevel;
119 }
120 
121 #define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x))
122 #define MATCH(x) (A.x == B.x)
123 
124 // check if the mv's and refidx are the same between A and B
125 static int compareMVrefidx(struct MvField A, struct MvField B)
126 {
127  if (A.pred_flag[0] && A.pred_flag[1] && B.pred_flag[0] && B.pred_flag[1])
128  return MATCH(ref_idx[0]) && MATCH_MV(mv[0]) &&
129  MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
130 
131  if (A.pred_flag[0] && !A.pred_flag[1] && B.pred_flag[0] && !B.pred_flag[1])
132  return MATCH(ref_idx[0]) && MATCH_MV(mv[0]);
133 
134  if (!A.pred_flag[0] && A.pred_flag[1] && !B.pred_flag[0] && B.pred_flag[1])
135  return MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
136 
137  return 0;
138 }
139 
140 static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb)
141 {
142  int tx, scale_factor;
143 
144  td = av_clip_int8_c(td);
145  tb = av_clip_int8_c(tb);
146  tx = (0x4000 + abs(td / 2)) / td;
147  scale_factor = av_clip_c((tb * tx + 32) >> 6, -4096, 4095);
148  dst->x = av_clip_int16_c((scale_factor * src->x + 127 +
149  (scale_factor * src->x < 0)) >> 8);
150  dst->y = av_clip_int16_c((scale_factor * src->y + 127 +
151  (scale_factor * src->y < 0)) >> 8);
152 }
153 
154 static int check_mvset(Mv *mvLXCol, Mv *mvCol,
155  int colPic, int poc,
156  RefPicList *refPicList, int X, int refIdxLx,
157  RefPicList *refPicList_col, int listCol, int refidxCol)
158 {
159  int cur_lt = refPicList[X].isLongTerm[refIdxLx];
160  int col_lt = refPicList_col[listCol].isLongTerm[refidxCol];
161  int col_poc_diff, cur_poc_diff;
162 
163  if (cur_lt != col_lt) {
164  mvLXCol->x = 0;
165  mvLXCol->y = 0;
166  return 0;
167  }
168 
169  col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol];
170  cur_poc_diff = poc - refPicList[X].list[refIdxLx];
171 
172  if (!col_poc_diff)
173  col_poc_diff = 1; // error resilience
174 
175  if (cur_lt || col_poc_diff == cur_poc_diff) {
176  mvLXCol->x = mvCol->x;
177  mvLXCol->y = mvCol->y;
178  } else {
179  mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
180  }
181  return 1;
182 }
183 
184 #define CHECK_MVSET(l) \
185  check_mvset(mvLXCol, temp_col.mv + l, \
186  colPic, s->poc, \
187  refPicList, X, refIdxLx, \
188  refPicList_col, L ## l, temp_col.ref_idx[l])
189 
190 // derive the motion vectors section 8.5.3.1.8
192  int refIdxLx, Mv *mvLXCol, int X,
193  int colPic, RefPicList *refPicList_col)
194 {
195  RefPicList *refPicList = s->ref->refPicList;
196 
197  if (temp_col.is_intra) {
198  mvLXCol->x = 0;
199  mvLXCol->y = 0;
200  return 0;
201  }
202 
203  if (temp_col.pred_flag[0] == 0)
204  return CHECK_MVSET(1);
205  else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 0)
206  return CHECK_MVSET(0);
207  else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 1) {
208  int check_diffpicount = 0;
209  int i = 0;
210  for (i = 0; i < refPicList[0].nb_refs; i++) {
211  if (refPicList[0].list[i] > s->poc)
212  check_diffpicount++;
213  }
214  for (i = 0; i < refPicList[1].nb_refs; i++) {
215  if (refPicList[1].list[i] > s->poc)
216  check_diffpicount++;
217  }
218  if (check_diffpicount == 0 && X == 0)
219  return CHECK_MVSET(0);
220  else if (check_diffpicount == 0 && X == 1)
221  return CHECK_MVSET(1);
222  else {
223  if (s->sh.collocated_list == L1)
224  return CHECK_MVSET(0);
225  else
226  return CHECK_MVSET(1);
227  }
228  }
229 
230  return 0;
231 }
232 
233 #define TAB_MVF(x, y) \
234  tab_mvf[(y) * min_pu_width + x]
235 
236 #define TAB_MVF_PU(v) \
237  TAB_MVF(x ## v ## _pu, y ## v ## _pu)
238 
239 #define DERIVE_TEMPORAL_COLOCATED_MVS \
240  derive_temporal_colocated_mvs(s, temp_col, \
241  refIdxLx, mvLXCol, X, colPic, \
242  ff_hevc_get_ref_list(s, ref, x, y))
243 
244 /*
245  * 8.5.3.1.7 temporal luma motion vector prediction
246  */
247 static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0,
248  int nPbW, int nPbH, int refIdxLx,
249  Mv *mvLXCol, int X)
250 {
251  MvField *tab_mvf;
252  MvField temp_col;
253  int x, y, x_pu, y_pu;
254  int min_pu_width = s->sps->min_pu_width;
255  int availableFlagLXCol = 0;
256  int colPic;
257 
258  HEVCFrame *ref = s->ref->collocated_ref;
259 
260  if (!ref) {
261  memset(mvLXCol, 0, sizeof(*mvLXCol));
262  return 0;
263  }
264 
265  tab_mvf = ref->tab_mvf;
266  colPic = ref->poc;
267 
268  //bottom right collocated motion vector
269  x = x0 + nPbW;
270  y = y0 + nPbH;
271 
272  if (tab_mvf &&
273  (y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) &&
274  y < s->sps->height &&
275  x < s->sps->width) {
276  x &= ~15;
277  y &= ~15;
278  ff_thread_await_progress(&ref->tf, y, 0);
279  x_pu = x >> s->sps->log2_min_pu_size;
280  y_pu = y >> s->sps->log2_min_pu_size;
281  temp_col = TAB_MVF(x_pu, y_pu);
282  availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
283  }
284 
285  // derive center collocated motion vector
286  if (tab_mvf && !availableFlagLXCol) {
287  x = x0 + (nPbW >> 1);
288  y = y0 + (nPbH >> 1);
289  x &= ~15;
290  y &= ~15;
291  ff_thread_await_progress(&ref->tf, y, 0);
292  x_pu = x >> s->sps->log2_min_pu_size;
293  y_pu = y >> s->sps->log2_min_pu_size;
294  temp_col = TAB_MVF(x_pu, y_pu);
295  availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
296  }
297  return availableFlagLXCol;
298 }
299 
300 #define AVAILABLE(cand, v) \
301  (cand && !TAB_MVF_PU(v).is_intra)
302 
303 #define PRED_BLOCK_AVAILABLE(v) \
304  check_prediction_block_available(s, log2_cb_size, \
305  x0, y0, nPbW, nPbH, \
306  x ## v, y ## v, part_idx)
307 
308 #define COMPARE_MV_REFIDX(a, b) \
309  compareMVrefidx(TAB_MVF_PU(a), TAB_MVF_PU(b))
310 
311 /*
312  * 8.5.3.1.2 Derivation process for spatial merging candidates
313  */
314 static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
315  int nPbW, int nPbH,
316  int log2_cb_size,
317  int singleMCLFlag, int part_idx,
318  int merge_idx,
319  struct MvField mergecandlist[])
320 {
321  HEVCLocalContext *lc = &s->HEVClc;
322  RefPicList *refPicList = s->ref->refPicList;
323  MvField *tab_mvf = s->ref->tab_mvf;
324 
325  const int min_pu_width = s->sps->min_pu_width;
326 
327  const int cand_bottom_left = lc->na.cand_bottom_left;
328  const int cand_left = lc->na.cand_left;
329  const int cand_up_left = lc->na.cand_up_left;
330  const int cand_up = lc->na.cand_up;
331  const int cand_up_right = lc->na.cand_up_right_sap;
332 
333  const int xA1 = x0 - 1;
334  const int yA1 = y0 + nPbH - 1;
335  const int xA1_pu = xA1 >> s->sps->log2_min_pu_size;
336  const int yA1_pu = yA1 >> s->sps->log2_min_pu_size;
337 
338  const int xB1 = x0 + nPbW - 1;
339  const int yB1 = y0 - 1;
340  const int xB1_pu = xB1 >> s->sps->log2_min_pu_size;
341  const int yB1_pu = yB1 >> s->sps->log2_min_pu_size;
342 
343  const int xB0 = x0 + nPbW;
344  const int yB0 = y0 - 1;
345  const int xB0_pu = xB0 >> s->sps->log2_min_pu_size;
346  const int yB0_pu = yB0 >> s->sps->log2_min_pu_size;
347 
348  const int xA0 = x0 - 1;
349  const int yA0 = y0 + nPbH;
350  const int xA0_pu = xA0 >> s->sps->log2_min_pu_size;
351  const int yA0_pu = yA0 >> s->sps->log2_min_pu_size;
352 
353  const int xB2 = x0 - 1;
354  const int yB2 = y0 - 1;
355  const int xB2_pu = xB2 >> s->sps->log2_min_pu_size;
356  const int yB2_pu = yB2 >> s->sps->log2_min_pu_size;
357 
358  const int nb_refs = (s->sh.slice_type == P_SLICE) ?
359  s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
360  int check_MER = 1;
361  int check_MER_1 = 1;
362 
363  int zero_idx = 0;
364 
365  int nb_merge_cand = 0;
366  int nb_orig_merge_cand = 0;
367 
368  int is_available_a0;
369  int is_available_a1;
370  int is_available_b0;
371  int is_available_b1;
372  int is_available_b2;
373  int check_B0;
374  int check_A0;
375 
376  //first left spatial merge candidate
377  is_available_a1 = AVAILABLE(cand_left, A1);
378 
379  if (!singleMCLFlag && part_idx == 1 &&
380  (lc->cu.part_mode == PART_Nx2N ||
381  lc->cu.part_mode == PART_nLx2N ||
382  lc->cu.part_mode == PART_nRx2N) ||
383  isDiffMER(s, xA1, yA1, x0, y0)) {
384  is_available_a1 = 0;
385  }
386 
387  if (is_available_a1) {
388  mergecandlist[0] = TAB_MVF_PU(A1);
389  if (merge_idx == 0)
390  return;
391  nb_merge_cand++;
392  }
393 
394  // above spatial merge candidate
395  is_available_b1 = AVAILABLE(cand_up, B1);
396 
397  if (!singleMCLFlag && part_idx == 1 &&
398  (lc->cu.part_mode == PART_2NxN ||
399  lc->cu.part_mode == PART_2NxnU ||
400  lc->cu.part_mode == PART_2NxnD) ||
401  isDiffMER(s, xB1, yB1, x0, y0)) {
402  is_available_b1 = 0;
403  }
404 
405  if (is_available_a1 && is_available_b1)
406  check_MER = !COMPARE_MV_REFIDX(B1, A1);
407 
408  if (is_available_b1 && check_MER)
409  mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1);
410 
411  // above right spatial merge candidate
412  check_MER = 1;
413  check_B0 = PRED_BLOCK_AVAILABLE(B0);
414 
415  is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0);
416 
417  if (isDiffMER(s, xB0, yB0, x0, y0))
418  is_available_b0 = 0;
419 
420  if (is_available_b1 && is_available_b0)
421  check_MER = !COMPARE_MV_REFIDX(B0, B1);
422 
423  if (is_available_b0 && check_MER) {
424  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0);
425  if (merge_idx == nb_merge_cand)
426  return;
427  nb_merge_cand++;
428  }
429 
430  // left bottom spatial merge candidate
431  check_MER = 1;
432  check_A0 = PRED_BLOCK_AVAILABLE(A0);
433 
434  is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0);
435 
436  if (isDiffMER(s, xA0, yA0, x0, y0))
437  is_available_a0 = 0;
438 
439  if (is_available_a1 && is_available_a0)
440  check_MER = !COMPARE_MV_REFIDX(A0, A1);
441 
442  if (is_available_a0 && check_MER) {
443  mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0);
444  if (merge_idx == nb_merge_cand)
445  return;
446  nb_merge_cand++;
447  }
448 
449  // above left spatial merge candidate
450  check_MER = 1;
451 
452  is_available_b2 = AVAILABLE(cand_up_left, B2);
453 
454  if (isDiffMER(s, xB2, yB2, x0, y0))
455  is_available_b2 = 0;
456 
457  if (is_available_a1 && is_available_b2)
458  check_MER = !COMPARE_MV_REFIDX(B2, A1);
459 
460  if (is_available_b1 && is_available_b2)
461  check_MER_1 = !COMPARE_MV_REFIDX(B2, B1);
462 
463  if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4) {
464  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2);
465  if (merge_idx == nb_merge_cand)
466  return;
467  nb_merge_cand++;
468  }
469 
470  // temporal motion vector candidate
472  nb_merge_cand < s->sh.max_num_merge_cand) {
473  Mv mv_l0_col, mv_l1_col;
474  int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
475  0, &mv_l0_col, 0);
476  int available_l1 = (s->sh.slice_type == B_SLICE) ?
477  temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
478  0, &mv_l1_col, 1) : 0;
479 
480  if (available_l0 || available_l1) {
481  mergecandlist[nb_merge_cand].is_intra = 0;
482  mergecandlist[nb_merge_cand].pred_flag[0] = available_l0;
483  mergecandlist[nb_merge_cand].pred_flag[1] = available_l1;
484  AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx);
485  mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
486  mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
487 
488  if (merge_idx == nb_merge_cand)
489  return;
490  nb_merge_cand++;
491  }
492  }
493 
494  nb_orig_merge_cand = nb_merge_cand;
495 
496  // combined bi-predictive merge candidates (applies for B slices)
497  if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&
498  nb_orig_merge_cand < s->sh.max_num_merge_cand) {
499  int comb_idx;
500 
501  for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
502  comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
503  int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
504  int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
505  MvField l0_cand = mergecandlist[l0_cand_idx];
506  MvField l1_cand = mergecandlist[l1_cand_idx];
507 
508  if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] &&
509  (refPicList[0].list[l0_cand.ref_idx[0]] !=
510  refPicList[1].list[l1_cand.ref_idx[1]] ||
511  AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {
512  mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0];
513  mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1];
514  mergecandlist[nb_merge_cand].pred_flag[0] = 1;
515  mergecandlist[nb_merge_cand].pred_flag[1] = 1;
516  AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);
517  AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);
518  mergecandlist[nb_merge_cand].is_intra = 0;
519  if (merge_idx == nb_merge_cand)
520  return;
521  nb_merge_cand++;
522  }
523  }
524  }
525 
526  // append Zero motion vector candidates
527  while (nb_merge_cand < s->sh.max_num_merge_cand) {
528  mergecandlist[nb_merge_cand].pred_flag[0] = 1;
529  mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE;
530  AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);
531  AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);
532  mergecandlist[nb_merge_cand].is_intra = 0;
533  mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
534  mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
535 
536  if (merge_idx == nb_merge_cand)
537  return;
538  nb_merge_cand++;
539  zero_idx++;
540  }
541 }
542 
543 /*
544  * 8.5.3.1.1 Derivation process of luma Mvs for merge mode
545  */
546 void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW,
547  int nPbH, int log2_cb_size, int part_idx,
548  int merge_idx, MvField *mv)
549 {
550  int singleMCLFlag = 0;
551  int nCS = 1 << log2_cb_size;
552  LOCAL_ALIGNED(4, MvField, mergecand_list, [MRG_MAX_NUM_CANDS]);
553  int nPbW2 = nPbW;
554  int nPbH2 = nPbH;
555  HEVCLocalContext *lc = &s->HEVClc;
556 
557  if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) {
558  singleMCLFlag = 1;
559  x0 = lc->cu.x;
560  y0 = lc->cu.y;
561  nPbW = nCS;
562  nPbH = nCS;
563  part_idx = 0;
564  }
565 
566  ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
567  derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size,
568  singleMCLFlag, part_idx,
569  merge_idx, mergecand_list);
570 
571  if (mergecand_list[merge_idx].pred_flag[0] == 1 &&
572  mergecand_list[merge_idx].pred_flag[1] == 1 &&
573  (nPbW2 + nPbH2) == 12) {
574  mergecand_list[merge_idx].ref_idx[1] = -1;
575  mergecand_list[merge_idx].pred_flag[1] = 0;
576  }
577 
578  *mv = mergecand_list[merge_idx];
579 }
580 
582  int min_pu_width, int x, int y,
583  int elist, int ref_idx_curr, int ref_idx)
584 {
585  RefPicList *refPicList = s->ref->refPicList;
586  MvField *tab_mvf = s->ref->tab_mvf;
587  int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
588  int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx];
589 
590  if (ref_pic_elist != ref_pic_curr) {
591  int poc_diff = s->poc - ref_pic_elist;
592  if (!poc_diff)
593  poc_diff = 1;
594  mv_scale(mv, mv, poc_diff, s->poc - ref_pic_curr);
595  }
596 }
597 
598 static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index,
599  Mv *mv, int ref_idx_curr, int ref_idx)
600 {
601  MvField *tab_mvf = s->ref->tab_mvf;
602  int min_pu_width = s->sps->min_pu_width;
603 
604  RefPicList *refPicList = s->ref->refPicList;
605 
606  if (TAB_MVF(x, y).pred_flag[pred_flag_index] == 1 &&
607  refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
608  *mv = TAB_MVF(x, y).mv[pred_flag_index];
609  return 1;
610  }
611  return 0;
612 }
613 
614 static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index,
615  Mv *mv, int ref_idx_curr, int ref_idx)
616 {
617  MvField *tab_mvf = s->ref->tab_mvf;
618  int min_pu_width = s->sps->min_pu_width;
619 
620  RefPicList *refPicList = s->ref->refPicList;
621  int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
622 
623  int colIsLongTerm =
624  refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
625 
626  if (TAB_MVF(x, y).pred_flag[pred_flag_index] &&
627  colIsLongTerm == currIsLongTerm) {
628  *mv = TAB_MVF(x, y).mv[pred_flag_index];
629  if (!currIsLongTerm)
630  dist_scale(s, mv, min_pu_width, x, y,
631  pred_flag_index, ref_idx_curr, ref_idx);
632  return 1;
633  }
634  return 0;
635 }
636 
637 #define MP_MX(v, pred, mx) \
638  mv_mp_mode_mx(s, x ## v ## _pu, y ## v ## _pu, pred, \
639  &mx, ref_idx_curr, ref_idx)
640 
641 #define MP_MX_LT(v, pred, mx) \
642  mv_mp_mode_mx_lt(s, x ## v ## _pu, y ## v ## _pu, pred, \
643  &mx, ref_idx_curr, ref_idx)
644 
645 void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
646  int nPbH, int log2_cb_size, int part_idx,
647  int merge_idx, MvField *mv,
648  int mvp_lx_flag, int LX)
649 {
650  HEVCLocalContext *lc = &s->HEVClc;
651  MvField *tab_mvf = s->ref->tab_mvf;
652  int isScaledFlag_L0 = 0;
653  int availableFlagLXA0 = 0;
654  int availableFlagLXB0 = 0;
655  int numMVPCandLX = 0;
656  int min_pu_width = s->sps->min_pu_width;
657 
658  int xA0, yA0;
659  int xA0_pu, yA0_pu;
660  int is_available_a0;
661 
662  int xA1, yA1;
663  int xA1_pu, yA1_pu;
664  int is_available_a1;
665 
666  int xB0, yB0;
667  int xB0_pu, yB0_pu;
668  int is_available_b0;
669 
670  int xB1, yB1;
671  int xB1_pu = 0, yB1_pu = 0;
672  int is_available_b1 = 0;
673 
674  int xB2, yB2;
675  int xB2_pu = 0, yB2_pu = 0;
676  int is_available_b2 = 0;
677  Mv mvpcand_list[2] = { { 0 } };
678  Mv mxA = { 0 };
679  Mv mxB = { 0 };
680  int ref_idx_curr = 0;
681  int ref_idx = 0;
682  int pred_flag_index_l0;
683  int pred_flag_index_l1;
684  int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
685  int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
686 
687  int cand_up = (lc->ctb_up_flag || y0b);
688  int cand_left = (lc->ctb_left_flag || x0b);
689  int cand_up_left =
690  (!x0b && !y0b) ? lc->ctb_up_left_flag : cand_left && cand_up;
691  int cand_up_right =
692  (x0b + nPbW == (1 << s->sps->log2_ctb_size) ||
693  x0 + nPbW >= lc->end_of_tiles_x) ? lc->ctb_up_right_flag && !y0b
694  : cand_up;
695  int cand_bottom_left = (y0 + nPbH >= lc->end_of_tiles_y) ? 0 : cand_left;
696 
697  ref_idx_curr = LX;
698  ref_idx = mv->ref_idx[LX];
699  pred_flag_index_l0 = LX;
700  pred_flag_index_l1 = !LX;
701 
702  // left bottom spatial candidate
703  xA0 = x0 - 1;
704  yA0 = y0 + nPbH;
705  xA0_pu = xA0 >> s->sps->log2_min_pu_size;
706  yA0_pu = yA0 >> s->sps->log2_min_pu_size;
707 
708  is_available_a0 = PRED_BLOCK_AVAILABLE(A0) && AVAILABLE(cand_bottom_left, A0);
709 
710  //left spatial merge candidate
711  xA1 = x0 - 1;
712  yA1 = y0 + nPbH - 1;
713  xA1_pu = xA1 >> s->sps->log2_min_pu_size;
714  yA1_pu = yA1 >> s->sps->log2_min_pu_size;
715 
716  is_available_a1 = AVAILABLE(cand_left, A1);
717  if (is_available_a0 || is_available_a1)
718  isScaledFlag_L0 = 1;
719 
720  if (is_available_a0) {
721  availableFlagLXA0 = MP_MX(A0, pred_flag_index_l0, mxA);
722  if (!availableFlagLXA0)
723  availableFlagLXA0 = MP_MX(A0, pred_flag_index_l1, mxA);
724  }
725 
726  if (is_available_a1 && !availableFlagLXA0) {
727  availableFlagLXA0 = MP_MX(A1, pred_flag_index_l0, mxA);
728  if (!availableFlagLXA0)
729  availableFlagLXA0 = MP_MX(A1, pred_flag_index_l1, mxA);
730  }
731 
732  if (is_available_a0 && !availableFlagLXA0) {
733  availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l0, mxA);
734  if (!availableFlagLXA0)
735  availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l1, mxA);
736  }
737 
738  if (is_available_a1 && !availableFlagLXA0) {
739  availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l0, mxA);
740  if (!availableFlagLXA0)
741  availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l1, mxA);
742  }
743 
744  if (availableFlagLXA0 && !mvp_lx_flag) {
745  mv->mv[LX] = mxA;
746  return;
747  }
748 
749  // B candidates
750  // above right spatial merge candidate
751  xB0 = x0 + nPbW;
752  yB0 = y0 - 1;
753  xB0_pu = xB0 >> s->sps->log2_min_pu_size;
754  yB0_pu = yB0 >> s->sps->log2_min_pu_size;
755 
756  is_available_b0 = PRED_BLOCK_AVAILABLE(B0) && AVAILABLE(cand_up_right, B0);
757 
758  if (is_available_b0) {
759  availableFlagLXB0 = MP_MX(B0, pred_flag_index_l0, mxB);
760  if (!availableFlagLXB0)
761  availableFlagLXB0 = MP_MX(B0, pred_flag_index_l1, mxB);
762  }
763 
764  if (!availableFlagLXB0) {
765  // above spatial merge candidate
766  xB1 = x0 + nPbW - 1;
767  yB1 = y0 - 1;
768  xB1_pu = xB1 >> s->sps->log2_min_pu_size;
769  yB1_pu = yB1 >> s->sps->log2_min_pu_size;
770 
771  is_available_b1 = AVAILABLE(cand_up, B1);
772 
773  if (is_available_b1) {
774  availableFlagLXB0 = MP_MX(B1, pred_flag_index_l0, mxB);
775  if (!availableFlagLXB0)
776  availableFlagLXB0 = MP_MX(B1, pred_flag_index_l1, mxB);
777  }
778  }
779 
780  if (!availableFlagLXB0) {
781  // above left spatial merge candidate
782  xB2 = x0 - 1;
783  yB2 = y0 - 1;
784  xB2_pu = xB2 >> s->sps->log2_min_pu_size;
785  yB2_pu = yB2 >> s->sps->log2_min_pu_size;
786  is_available_b2 = AVAILABLE(cand_up_left, B2);
787 
788  if (is_available_b2) {
789  availableFlagLXB0 = MP_MX(B2, pred_flag_index_l0, mxB);
790  if (!availableFlagLXB0)
791  availableFlagLXB0 = MP_MX(B2, pred_flag_index_l1, mxB);
792  }
793  }
794 
795  if (isScaledFlag_L0 == 0) {
796  if (availableFlagLXB0) {
797  availableFlagLXA0 = 1;
798  mxA = mxB;
799  }
800  availableFlagLXB0 = 0;
801 
802  // XB0 and L1
803  if (is_available_b0) {
804  availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);
805  if (!availableFlagLXB0)
806  availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);
807  }
808 
809  if (is_available_b1 && !availableFlagLXB0) {
810  availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);
811  if (!availableFlagLXB0)
812  availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);
813  }
814 
815  if (is_available_b2 && !availableFlagLXB0) {
816  availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);
817  if (!availableFlagLXB0)
818  availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);
819  }
820  }
821 
822  if (availableFlagLXA0)
823  mvpcand_list[numMVPCandLX++] = mxA;
824 
825  if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
826  mvpcand_list[numMVPCandLX++] = mxB;
827 
828  //temporal motion vector prediction candidate
829  if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&
830  mvp_lx_flag == numMVPCandLX) {
831  Mv mv_col;
832  int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
833  nPbH, ref_idx,
834  &mv_col, LX);
835  if (available_col)
836  mvpcand_list[numMVPCandLX++] = mv_col;
837  }
838 
839  // insert zero motion vectors when the number of available candidates are less than 2
840  while (numMVPCandLX < 2)
841  mvpcand_list[numMVPCandLX++] = (Mv){ 0, 0 };
842 
843  mv->mv[LX].x = mvpcand_list[mvp_lx_flag].x;
844  mv->mv[LX].y = mvpcand_list[mvp_lx_flag].y;
845 }
uint8_t ctb_up_flag
Definition: hevc.h:730
NeighbourAvailable na
Definition: hevc.h:741
static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb)
Definition: hevc_mvs.c:140
HEVCFrame * ref
Definition: hevc.h:786
Definition: hevc.h:623
#define TAB_MVF(x, y)
Definition: hevc_mvs.c:233
#define A1
Definition: binkdsp.c:31
#define MP_MX(v, pred, mx)
Definition: hevc_mvs.c:637
int16_t x
horizontal component of motion vector
Definition: hevc.h:619
static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int refIdxLx, Mv *mvLXCol, int X)
Definition: hevc_mvs.c:247
MvField * tab_mvf
Definition: hevc.h:668
static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
Definition: hevc_mvs.c:598
static int compareMVrefidx(struct MvField A, struct MvField B)
Definition: hevc_mvs.c:125
static av_always_inline av_const int8_t av_clip_int8_c(int a)
Clip a signed integer value into the -128,127 range.
Definition: common.h:116
int isLongTerm[MAX_REFS]
Definition: hevc.h:278
int x
Definition: hevc.h:602
static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int singleMCLFlag, int part_idx, int merge_idx, struct MvField mergecandlist[])
Definition: hevc_mvs.c:314
void ff_thread_await_progress(ThreadFrame *f, int n, int field)
Wait for earlier decoding threads to finish reference pictures.
int cand_up_right
Definition: hevc.h:635
static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col, int refIdxLx, Mv *mvLXCol, int X, int colPic, RefPicList *refPicList_col)
Definition: hevc_mvs.c:191
int list[MAX_REFS]
Definition: hevc.h:277
int width
Definition: hevc.h:446
#define AV_COPY32(d, s)
Definition: intreadwrite.h:506
#define B1
Definition: faandct.c:41
int log2_parallel_merge_level
log2_parallel_merge_level_minus2 + 2
Definition: hevc.h:510
#define AV_RN32A(p)
Definition: intreadwrite.h:446
static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
Definition: hevc_mvs.c:614
int nb_refs
Definition: hevc.h:279
#define MRG_MAX_NUM_CANDS
Definition: hevc.h:65
int end_of_tiles_x
Definition: hevc.h:734
uint8_t
uint8_t ctb_up_right_flag
Definition: hevc.h:731
int cand_up_right_sap
Definition: hevc.h:636
#define DERIVE_TEMPORAL_COLOCATED_MVS
Definition: hevc_mvs.c:239
int cand_up_left
Definition: hevc.h:634
#define AVAILABLE(cand, v)
Definition: hevc_mvs.c:300
ThreadFrame tf
Definition: hevc.h:667
uint8_t ctb_up_left_flag
Definition: hevc.h:732
#define B
Definition: huffyuv.h:49
#define B2
Definition: faandct.c:42
#define MIN_TB_ADDR_ZS(x, y)
const HEVCSPS * sps
Definition: hevc.h:769
RefPicList * refPicList
Definition: hevc.h:669
HEVCLocalContext HEVClc
Definition: hevc.h:756
static av_always_inline av_const int av_clip_c(int a, int amin, int amax)
Clip a signed integer value into the amin-amax range.
Definition: common.h:93
unsigned int log2_ctb_size
Definition: hevc.h:439
#define MP_MX_LT(v, pred, mx)
Definition: hevc_mvs.c:641
static int check_mvset(Mv *mvLXCol, Mv *mvCol, int colPic, int poc, RefPicList *refPicList, int X, int refIdxLx, RefPicList *refPicList_col, int listCol, int refidxCol)
Definition: hevc_mvs.c:154
#define MATCH_MV(x)
Definition: hevc_mvs.c:121
uint8_t slice_temporal_mvp_enabled_flag
Definition: hevc.h:553
const HEVCPPS * pps
Definition: hevc.h:770
uint8_t is_intra
Definition: hevc.h:627
#define COMPARE_MV_REFIDX(a, b)
Definition: hevc_mvs.c:308
#define FFMIN(a, b)
Definition: common.h:57
static const uint8_t l0_l1_cand_idx[12][2]
Definition: hevc_mvs.c:26
struct HEVCFrame * collocated_ref
Definition: hevc.h:673
int height
Definition: hevc.h:447
Definition: hevc.h:132
static const int8_t mv[256][2]
Definition: 4xm.c:75
static av_always_inline void dist_scale(HEVCContext *s, Mv *mv, int min_pu_width, int x, int y, int elist, int ref_idx_curr, int ref_idx)
Definition: hevc_mvs.c:581
unsigned int log2_min_pu_size
Definition: hevc.h:440
int8_t pred_flag[2]
Definition: hevc.h:626
static int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr, int xN, int yN)
Definition: hevc_mvs.c:64
static int isDiffMER(HEVCContext *s, int xN, int yN, int xP, int yP)
Definition: hevc_mvs.c:113
int16_t y
vertical component of motion vector
Definition: hevc.h:620
uint8_t ctb_left_flag
Definition: hevc.h:729
int y
Definition: hevc.h:603
#define TAB_MVF_PU(v)
Definition: hevc_mvs.c:236
int poc
Definition: hevc.h:672
static int check_prediction_block_available(HEVCContext *s, int log2_cb_size, int x0, int y0, int nPbW, int nPbH, int xA1, int yA1, int partIdx)
Definition: hevc_mvs.c:97
unsigned int max_num_merge_cand
5 - 5_minus_max_num_merge_cand
Definition: hevc.h:574
unsigned int log2_min_tb_size
Definition: hevc.h:437
void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv)
Definition: hevc_mvs.c:546
int poc
Definition: hevc.h:788
enum PartMode part_mode
PartMode.
Definition: hevc.h:606
#define CHECK_MVSET(l)
Definition: hevc_mvs.c:184
Definition: hevc.h:618
Definition: vf_drawbox.c:37
static av_always_inline av_const int16_t av_clip_int16_c(int a)
Clip a signed integer value into the -32768,32767 range.
Definition: common.h:138
void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv, int mvp_lx_flag, int LX)
Definition: hevc_mvs.c:645
Mv mv[2]
Definition: hevc.h:624
int8_t ref_idx[2]
Definition: hevc.h:625
#define LOCAL_ALIGNED(a, t, v,...)
Definition: internal.h:103
unsigned int nb_refs[2]
Definition: hevc.h:555
int cand_bottom_left
Definition: hevc.h:631
uint8_t collocated_list
Definition: hevc.h:563
#define AV_ZERO16(d)
Definition: intreadwrite.h:530
void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, int nPbW, int nPbH)
Definition: hevc_mvs.c:41
CodingUnit cu
Definition: hevc.h:739
int min_pu_width
Definition: hevc.h:455
#define AV_ZERO32(d)
Definition: intreadwrite.h:534
Definition: hevc.h:131
#define PRED_BLOCK_AVAILABLE(v)
Definition: hevc_mvs.c:303
#define av_always_inline
Definition: attributes.h:40
#define MATCH(x)
Definition: hevc_mvs.c:122
enum SliceType slice_type
Definition: hevc.h:536
#define L1
Definition: hevc.h:68
SliceHeader sh
Definition: hevc.h:781
static int same_prediction_block(HEVCLocalContext *lc, int log2_cb_size, int x0, int y0, int nPbW, int nPbH, int xA1, int yA1, int partIdx)
Definition: hevc_mvs.c:84
#define B0
Definition: faandct.c:40
int end_of_tiles_y
Definition: hevc.h:735