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