FFmpeg
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 #include "threadframe.h"
27 
28 static const uint8_t l0_l1_cand_idx[12][2] = {
29  { 0, 1, },
30  { 1, 0, },
31  { 0, 2, },
32  { 2, 0, },
33  { 1, 2, },
34  { 2, 1, },
35  { 0, 3, },
36  { 3, 0, },
37  { 1, 3, },
38  { 3, 1, },
39  { 2, 3, },
40  { 3, 2, },
41 };
42 
44  int nPbW, int nPbH)
45 {
46  const HEVCContext *const s = lc->parent;
47  int x0b = av_mod_uintp2(x0, s->ps.sps->log2_ctb_size);
48  int y0b = av_mod_uintp2(y0, s->ps.sps->log2_ctb_size);
49 
50  lc->na.cand_up = (lc->ctb_up_flag || y0b);
51  lc->na.cand_left = (lc->ctb_left_flag || x0b);
52  lc->na.cand_up_left = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag;
53  lc->na.cand_up_right_sap =
54  (x0b + nPbW == 1 << s->ps.sps->log2_ctb_size) ?
55  lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
56  lc->na.cand_up_right =
58  && (x0 + nPbW) < lc->end_of_tiles_x;
59  lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left;
60 }
61 
62 /*
63  * 6.4.1 Derivation process for z-scan order block availability
64  */
65 static av_always_inline int z_scan_block_avail(const HEVCContext *s, int xCurr, int yCurr,
66  int xN, int yN)
67 {
68 #define MIN_TB_ADDR_ZS(x, y) \
69  s->ps.pps->min_tb_addr_zs[(y) * (s->ps.sps->tb_mask+2) + (x)]
70 
71  int xCurr_ctb = xCurr >> s->ps.sps->log2_ctb_size;
72  int yCurr_ctb = yCurr >> s->ps.sps->log2_ctb_size;
73  int xN_ctb = xN >> s->ps.sps->log2_ctb_size;
74  int yN_ctb = yN >> s->ps.sps->log2_ctb_size;
75  if( yN_ctb < yCurr_ctb || xN_ctb < xCurr_ctb )
76  return 1;
77  else {
78  int Curr = MIN_TB_ADDR_ZS((xCurr >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask,
79  (yCurr >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask);
80  int N = MIN_TB_ADDR_ZS((xN >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask,
81  (yN >> s->ps.sps->log2_min_tb_size) & s->ps.sps->tb_mask);
82  return N <= Curr;
83  }
84 }
85 
86 //check if the two luma locations belong to the same motion estimation region
87 static av_always_inline int is_diff_mer(const HEVCContext *s, int xN, int yN, int xP, int yP)
88 {
89  uint8_t plevel = s->ps.pps->log2_parallel_merge_level;
90 
91  return xN >> plevel == xP >> plevel &&
92  yN >> plevel == yP >> plevel;
93 }
94 
95 #define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x))
96 #define MATCH(x) (A.x == B.x)
97 
98 // check if the mv's and refidx are the same between A and B
100 {
101  int a_pf = A.pred_flag;
102  int b_pf = B.pred_flag;
103  if (a_pf == b_pf) {
104  if (a_pf == PF_BI) {
105  return MATCH(ref_idx[0]) && MATCH_MV(mv[0]) &&
106  MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
107  } else if (a_pf == PF_L0) {
108  return MATCH(ref_idx[0]) && MATCH_MV(mv[0]);
109  } else if (a_pf == PF_L1) {
110  return MATCH(ref_idx[1]) && MATCH_MV(mv[1]);
111  }
112  }
113  return 0;
114 }
115 
116 static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb)
117 {
118  int tx, scale_factor;
119 
120  td = av_clip_int8(td);
121  tb = av_clip_int8(tb);
122  tx = (0x4000 + abs(td / 2)) / td;
123  scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12);
124  dst->x = av_clip_int16((scale_factor * src->x + 127 +
125  (scale_factor * src->x < 0)) >> 8);
126  dst->y = av_clip_int16((scale_factor * src->y + 127 +
127  (scale_factor * src->y < 0)) >> 8);
128 }
129 
130 static int check_mvset(Mv *mvLXCol, const Mv *mvCol,
131  int colPic, int poc,
132  const RefPicList *refPicList, int X, int refIdxLx,
133  const RefPicList *refPicList_col, int listCol, int refidxCol)
134 {
135  int cur_lt = refPicList[X].isLongTerm[refIdxLx];
136  int col_lt = refPicList_col[listCol].isLongTerm[refidxCol];
137  int col_poc_diff, cur_poc_diff;
138 
139  if (cur_lt != col_lt) {
140  mvLXCol->x = 0;
141  mvLXCol->y = 0;
142  return 0;
143  }
144 
145  col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol];
146  cur_poc_diff = poc - refPicList[X].list[refIdxLx];
147 
148  if (cur_lt || col_poc_diff == cur_poc_diff || !col_poc_diff) {
149  mvLXCol->x = mvCol->x;
150  mvLXCol->y = mvCol->y;
151  } else {
152  mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
153  }
154  return 1;
155 }
156 
157 #define CHECK_MVSET(l) \
158  check_mvset(mvLXCol, temp_col.mv + l, \
159  colPic, s->poc, \
160  refPicList, X, refIdxLx, \
161  refPicList_col, L ## l, temp_col.ref_idx[l])
162 
163 // derive the motion vectors section 8.5.3.1.8
165  int refIdxLx, Mv *mvLXCol, int X,
166  int colPic, const RefPicList *refPicList_col)
167 {
168  const RefPicList *refPicList = s->ref->refPicList;
169 
170  if (temp_col.pred_flag == PF_INTRA)
171  return 0;
172 
173  if (!(temp_col.pred_flag & PF_L0))
174  return CHECK_MVSET(1);
175  else if (temp_col.pred_flag == PF_L0)
176  return CHECK_MVSET(0);
177  else if (temp_col.pred_flag == PF_BI) {
178  int check_diffpicount = 0;
179  int i, j;
180  for (j = 0; j < 2; j++) {
181  for (i = 0; i < refPicList[j].nb_refs; i++) {
182  if (refPicList[j].list[i] > s->poc) {
183  check_diffpicount++;
184  break;
185  }
186  }
187  }
188  if (!check_diffpicount) {
189  if (X==0)
190  return CHECK_MVSET(0);
191  else
192  return CHECK_MVSET(1);
193  } else {
194  if (s->sh.collocated_list == L1)
195  return CHECK_MVSET(0);
196  else
197  return CHECK_MVSET(1);
198  }
199  }
200 
201  return 0;
202 }
203 
204 #define TAB_MVF(x, y) \
205  tab_mvf[(y) * min_pu_width + x]
206 
207 #define TAB_MVF_PU(v) \
208  TAB_MVF(((x ## v) >> s->ps.sps->log2_min_pu_size), \
209  ((y ## v) >> s->ps.sps->log2_min_pu_size))
210 
211 #define DERIVE_TEMPORAL_COLOCATED_MVS \
212  derive_temporal_colocated_mvs(s, temp_col, \
213  refIdxLx, mvLXCol, X, colPic, \
214  ff_hevc_get_ref_list(s, ref, x, y))
215 
216 /*
217  * 8.5.3.1.7 temporal luma motion vector prediction
218  */
219 static int temporal_luma_motion_vector(const HEVCContext *s, int x0, int y0,
220  int nPbW, int nPbH, int refIdxLx,
221  Mv *mvLXCol, int X)
222 {
223  const MvField *tab_mvf;
224  MvField temp_col;
225  int x, y, x_pu, y_pu;
226  int min_pu_width = s->ps.sps->min_pu_width;
227  int availableFlagLXCol = 0;
228  int colPic;
229 
230  const HEVCFrame *ref = s->ref->collocated_ref;
231 
232  if (!ref) {
233  memset(mvLXCol, 0, sizeof(*mvLXCol));
234  return 0;
235  }
236 
237  tab_mvf = ref->tab_mvf;
238  colPic = ref->poc;
239 
240  //bottom right collocated motion vector
241  x = x0 + nPbW;
242  y = y0 + nPbH;
243 
244  if (tab_mvf &&
245  (y0 >> s->ps.sps->log2_ctb_size) == (y >> s->ps.sps->log2_ctb_size) &&
246  y < s->ps.sps->height &&
247  x < s->ps.sps->width) {
248  x &= ~15;
249  y &= ~15;
250  if (s->threads_type == FF_THREAD_FRAME)
251  ff_thread_await_progress(&ref->tf, y, 0);
252  x_pu = x >> s->ps.sps->log2_min_pu_size;
253  y_pu = y >> s->ps.sps->log2_min_pu_size;
254  temp_col = TAB_MVF(x_pu, y_pu);
255  availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
256  }
257 
258  // derive center collocated motion vector
259  if (tab_mvf && !availableFlagLXCol) {
260  x = x0 + (nPbW >> 1);
261  y = y0 + (nPbH >> 1);
262  x &= ~15;
263  y &= ~15;
264  if (s->threads_type == FF_THREAD_FRAME)
265  ff_thread_await_progress(&ref->tf, y, 0);
266  x_pu = x >> s->ps.sps->log2_min_pu_size;
267  y_pu = y >> s->ps.sps->log2_min_pu_size;
268  temp_col = TAB_MVF(x_pu, y_pu);
269  availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
270  }
271  return availableFlagLXCol;
272 }
273 
274 #define AVAILABLE(cand, v) \
275  (cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA))
276 
277 #define PRED_BLOCK_AVAILABLE(v) \
278  z_scan_block_avail(s, x0, y0, x ## v, y ## v)
279 
280 #define COMPARE_MV_REFIDX(a, b) \
281  compare_mv_ref_idx(TAB_MVF_PU(a), TAB_MVF_PU(b))
282 
283 /*
284  * 8.5.3.1.2 Derivation process for spatial merging candidates
285  */
287  int x0, int y0,
288  int nPbW, int nPbH,
289  int log2_cb_size,
290  int singleMCLFlag, int part_idx,
291  int merge_idx,
292  struct MvField mergecandlist[])
293 {
294  const RefPicList *refPicList = s->ref->refPicList;
295  const MvField *tab_mvf = s->ref->tab_mvf;
296 
297  const int min_pu_width = s->ps.sps->min_pu_width;
298 
299  const int cand_bottom_left = lc->na.cand_bottom_left;
300  const int cand_left = lc->na.cand_left;
301  const int cand_up_left = lc->na.cand_up_left;
302  const int cand_up = lc->na.cand_up;
303  const int cand_up_right = lc->na.cand_up_right_sap;
304 
305  const int xA1 = x0 - 1;
306  const int yA1 = y0 + nPbH - 1;
307 
308  const int xB1 = x0 + nPbW - 1;
309  const int yB1 = y0 - 1;
310 
311  const int xB0 = x0 + nPbW;
312  const int yB0 = y0 - 1;
313 
314  const int xA0 = x0 - 1;
315  const int yA0 = y0 + nPbH;
316 
317  const int xB2 = x0 - 1;
318  const int yB2 = y0 - 1;
319 
320  const int nb_refs = (s->sh.slice_type == HEVC_SLICE_P) ?
321  s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
322 
323  int zero_idx = 0;
324 
325  int nb_merge_cand = 0;
326  int nb_orig_merge_cand = 0;
327 
328  int is_available_a0;
329  int is_available_a1;
330  int is_available_b0;
331  int is_available_b1;
332  int is_available_b2;
333 
334 
335  if (!singleMCLFlag && part_idx == 1 &&
336  (lc->cu.part_mode == PART_Nx2N ||
337  lc->cu.part_mode == PART_nLx2N ||
338  lc->cu.part_mode == PART_nRx2N) ||
339  is_diff_mer(s, xA1, yA1, x0, y0)) {
340  is_available_a1 = 0;
341  } else {
342  is_available_a1 = AVAILABLE(cand_left, A1);
343  if (is_available_a1) {
344  mergecandlist[nb_merge_cand] = TAB_MVF_PU(A1);
345  if (merge_idx == 0)
346  return;
347  nb_merge_cand++;
348  }
349  }
350 
351  if (!singleMCLFlag && part_idx == 1 &&
352  (lc->cu.part_mode == PART_2NxN ||
353  lc->cu.part_mode == PART_2NxnU ||
354  lc->cu.part_mode == PART_2NxnD) ||
355  is_diff_mer(s, xB1, yB1, x0, y0)) {
356  is_available_b1 = 0;
357  } else {
358  is_available_b1 = AVAILABLE(cand_up, B1);
359  if (is_available_b1 &&
360  !(is_available_a1 && COMPARE_MV_REFIDX(B1, A1))) {
361  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B1);
362  if (merge_idx == nb_merge_cand)
363  return;
364  nb_merge_cand++;
365  }
366  }
367 
368  // above right spatial merge candidate
369  is_available_b0 = AVAILABLE(cand_up_right, B0) &&
370  xB0 < s->ps.sps->width &&
372  !is_diff_mer(s, xB0, yB0, x0, y0);
373 
374  if (is_available_b0 &&
375  !(is_available_b1 && COMPARE_MV_REFIDX(B0, B1))) {
376  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0);
377  if (merge_idx == nb_merge_cand)
378  return;
379  nb_merge_cand++;
380  }
381 
382  // left bottom spatial merge candidate
383  is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
384  yA0 < s->ps.sps->height &&
385  PRED_BLOCK_AVAILABLE(A0) &&
386  !is_diff_mer(s, xA0, yA0, x0, y0);
387 
388  if (is_available_a0 &&
389  !(is_available_a1 && COMPARE_MV_REFIDX(A0, A1))) {
390  mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0);
391  if (merge_idx == nb_merge_cand)
392  return;
393  nb_merge_cand++;
394  }
395 
396  // above left spatial merge candidate
397  is_available_b2 = AVAILABLE(cand_up_left, B2) &&
398  !is_diff_mer(s, xB2, yB2, x0, y0);
399 
400  if (is_available_b2 &&
401  !(is_available_a1 && COMPARE_MV_REFIDX(B2, A1)) &&
402  !(is_available_b1 && COMPARE_MV_REFIDX(B2, B1)) &&
403  nb_merge_cand != 4) {
404  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2);
405  if (merge_idx == nb_merge_cand)
406  return;
407  nb_merge_cand++;
408  }
409 
410  // temporal motion vector candidate
411  if (s->sh.slice_temporal_mvp_enabled_flag &&
412  nb_merge_cand < s->sh.max_num_merge_cand) {
413  Mv mv_l0_col = { 0 }, mv_l1_col = { 0 };
414  int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
415  0, &mv_l0_col, 0);
416  int available_l1 = (s->sh.slice_type == HEVC_SLICE_B) ?
417  temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
418  0, &mv_l1_col, 1) : 0;
419 
420  if (available_l0 || available_l1) {
421  mergecandlist[nb_merge_cand].pred_flag = available_l0 + (available_l1 << 1);
422  AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx);
423  mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
424  mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
425 
426  if (merge_idx == nb_merge_cand)
427  return;
428  nb_merge_cand++;
429  }
430  }
431 
432  nb_orig_merge_cand = nb_merge_cand;
433 
434  // combined bi-predictive merge candidates (applies for B slices)
435  if (s->sh.slice_type == HEVC_SLICE_B && nb_orig_merge_cand > 1 &&
436  nb_orig_merge_cand < s->sh.max_num_merge_cand) {
437  int comb_idx = 0;
438 
439  for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
440  comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
441  int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
442  int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
443  MvField l0_cand = mergecandlist[l0_cand_idx];
444  MvField l1_cand = mergecandlist[l1_cand_idx];
445 
446  if ((l0_cand.pred_flag & PF_L0) && (l1_cand.pred_flag & PF_L1) &&
447  (refPicList[0].list[l0_cand.ref_idx[0]] !=
448  refPicList[1].list[l1_cand.ref_idx[1]] ||
449  AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {
450  mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0];
451  mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1];
452  mergecandlist[nb_merge_cand].pred_flag = PF_BI;
453  AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);
454  AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);
455  if (merge_idx == nb_merge_cand)
456  return;
457  nb_merge_cand++;
458  }
459  }
460  }
461 
462  // append Zero motion vector candidates
463  while (nb_merge_cand < s->sh.max_num_merge_cand) {
464  mergecandlist[nb_merge_cand].pred_flag = PF_L0 + ((s->sh.slice_type == HEVC_SLICE_B) << 1);
465  AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);
466  AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);
467  mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
468  mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
469 
470  if (merge_idx == nb_merge_cand)
471  return;
472  nb_merge_cand++;
473  zero_idx++;
474  }
475 }
476 
477 /*
478  * 8.5.3.1.1 Derivation process of luma Mvs for merge mode
479  */
480 void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW,
481  int nPbH, int log2_cb_size, int part_idx,
482  int merge_idx, MvField *mv)
483 {
484  const HEVCContext *const s = lc->parent;
485  int singleMCLFlag = 0;
486  int nCS = 1 << log2_cb_size;
487  MvField mergecand_list[MRG_MAX_NUM_CANDS];
488  int nPbW2 = nPbW;
489  int nPbH2 = nPbH;
490 
491  if (s->ps.pps->log2_parallel_merge_level > 2 && nCS == 8) {
492  singleMCLFlag = 1;
493  x0 = lc->cu.x;
494  y0 = lc->cu.y;
495  nPbW = nCS;
496  nPbH = nCS;
497  part_idx = 0;
498  }
499 
500  ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH);
501  derive_spatial_merge_candidates(lc, s, x0, y0, nPbW, nPbH, log2_cb_size,
502  singleMCLFlag, part_idx,
503  merge_idx, mergecand_list);
504 
505  if (mergecand_list[merge_idx].pred_flag == PF_BI &&
506  (nPbW2 + nPbH2) == 12) {
507  mergecand_list[merge_idx].pred_flag = PF_L0;
508  }
509 
510  *mv = mergecand_list[merge_idx];
511 }
512 
514  int min_pu_width, int x, int y,
515  int elist, int ref_idx_curr, int ref_idx)
516 {
517  const RefPicList *refPicList = s->ref->refPicList;
518  const MvField *tab_mvf = s->ref->tab_mvf;
519  int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
520  int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx];
521 
522  if (ref_pic_elist != ref_pic_curr) {
523  int poc_diff = s->poc - ref_pic_elist;
524  if (!poc_diff)
525  poc_diff = 1;
526  mv_scale(mv, mv, poc_diff, s->poc - ref_pic_curr);
527  }
528 }
529 
530 static int mv_mp_mode_mx(const HEVCContext *s, int x, int y, int pred_flag_index,
531  Mv *mv, int ref_idx_curr, int ref_idx)
532 {
533  const MvField *tab_mvf = s->ref->tab_mvf;
534  int min_pu_width = s->ps.sps->min_pu_width;
535 
536  const RefPicList *refPicList = s->ref->refPicList;
537 
538  if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) &&
539  refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
540  *mv = TAB_MVF(x, y).mv[pred_flag_index];
541  return 1;
542  }
543  return 0;
544 }
545 
546 static int mv_mp_mode_mx_lt(const HEVCContext *s, int x, int y, int pred_flag_index,
547  Mv *mv, int ref_idx_curr, int ref_idx)
548 {
549  const MvField *tab_mvf = s->ref->tab_mvf;
550  int min_pu_width = s->ps.sps->min_pu_width;
551 
552  const RefPicList *refPicList = s->ref->refPicList;
553 
554  if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) {
555  int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
556 
557  int colIsLongTerm =
558  refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
559 
560  if (colIsLongTerm == currIsLongTerm) {
561  *mv = TAB_MVF(x, y).mv[pred_flag_index];
562  if (!currIsLongTerm)
563  dist_scale(s, mv, min_pu_width, x, y,
564  pred_flag_index, ref_idx_curr, ref_idx);
565  return 1;
566  }
567  }
568  return 0;
569 }
570 
571 #define MP_MX(v, pred, mx) \
572  mv_mp_mode_mx(s, \
573  (x ## v) >> s->ps.sps->log2_min_pu_size, \
574  (y ## v) >> s->ps.sps->log2_min_pu_size, \
575  pred, &mx, ref_idx_curr, ref_idx)
576 
577 #define MP_MX_LT(v, pred, mx) \
578  mv_mp_mode_mx_lt(s, \
579  (x ## v) >> s->ps.sps->log2_min_pu_size, \
580  (y ## v) >> s->ps.sps->log2_min_pu_size, \
581  pred, &mx, ref_idx_curr, ref_idx)
582 
583 void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW,
584  int nPbH, int log2_cb_size, int part_idx,
585  int merge_idx, MvField *mv,
586  int mvp_lx_flag, int LX)
587 {
588  const HEVCContext *const s = lc->parent;
589  const MvField *const tab_mvf = s->ref->tab_mvf;
590  int isScaledFlag_L0 = 0;
591  int availableFlagLXA0 = 1;
592  int availableFlagLXB0 = 1;
593  int numMVPCandLX = 0;
594  int min_pu_width = s->ps.sps->min_pu_width;
595 
596  int xA0, yA0;
597  int is_available_a0;
598  int xA1, yA1;
599  int is_available_a1;
600  int xB0, yB0;
601  int is_available_b0;
602  int xB1, yB1;
603  int is_available_b1;
604  int xB2, yB2;
605  int is_available_b2;
606 
607  Mv mvpcand_list[2] = { { 0 } };
608  Mv mxA;
609  Mv mxB;
610  int ref_idx_curr;
611  int ref_idx = 0;
612  int pred_flag_index_l0;
613  int pred_flag_index_l1;
614 
615  const int cand_bottom_left = lc->na.cand_bottom_left;
616  const int cand_left = lc->na.cand_left;
617  const int cand_up_left = lc->na.cand_up_left;
618  const int cand_up = lc->na.cand_up;
619  const int cand_up_right = lc->na.cand_up_right_sap;
620  ref_idx_curr = LX;
621  ref_idx = mv->ref_idx[LX];
622  pred_flag_index_l0 = LX;
623  pred_flag_index_l1 = !LX;
624 
625  // left bottom spatial candidate
626  xA0 = x0 - 1;
627  yA0 = y0 + nPbH;
628 
629  is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
630  yA0 < s->ps.sps->height &&
632 
633  //left spatial merge candidate
634  xA1 = x0 - 1;
635  yA1 = y0 + nPbH - 1;
636 
637  is_available_a1 = AVAILABLE(cand_left, A1);
638  if (is_available_a0 || is_available_a1)
639  isScaledFlag_L0 = 1;
640 
641  if (is_available_a0) {
642  if (MP_MX(A0, pred_flag_index_l0, mxA)) {
643  goto b_candidates;
644  }
645  if (MP_MX(A0, pred_flag_index_l1, mxA)) {
646  goto b_candidates;
647  }
648  }
649 
650  if (is_available_a1) {
651  if (MP_MX(A1, pred_flag_index_l0, mxA)) {
652  goto b_candidates;
653  }
654  if (MP_MX(A1, pred_flag_index_l1, mxA)) {
655  goto b_candidates;
656  }
657  }
658 
659  if (is_available_a0) {
660  if (MP_MX_LT(A0, pred_flag_index_l0, mxA)) {
661  goto b_candidates;
662  }
663  if (MP_MX_LT(A0, pred_flag_index_l1, mxA)) {
664  goto b_candidates;
665  }
666  }
667 
668  if (is_available_a1) {
669  if (MP_MX_LT(A1, pred_flag_index_l0, mxA)) {
670  goto b_candidates;
671  }
672  if (MP_MX_LT(A1, pred_flag_index_l1, mxA)) {
673  goto b_candidates;
674  }
675  }
676  availableFlagLXA0 = 0;
677 
678 b_candidates:
679  // B candidates
680  // above right spatial merge candidate
681  xB0 = x0 + nPbW;
682  yB0 = y0 - 1;
683 
684  is_available_b0 = AVAILABLE(cand_up_right, B0) &&
685  xB0 < s->ps.sps->width &&
687 
688  // above spatial merge candidate
689  xB1 = x0 + nPbW - 1;
690  yB1 = y0 - 1;
691  is_available_b1 = AVAILABLE(cand_up, B1);
692 
693  // above left spatial merge candidate
694  xB2 = x0 - 1;
695  yB2 = y0 - 1;
696  is_available_b2 = AVAILABLE(cand_up_left, B2);
697 
698  // above right spatial merge candidate
699  if (is_available_b0) {
700  if (MP_MX(B0, pred_flag_index_l0, mxB)) {
701  goto scalef;
702  }
703  if (MP_MX(B0, pred_flag_index_l1, mxB)) {
704  goto scalef;
705  }
706  }
707 
708  // above spatial merge candidate
709  if (is_available_b1) {
710  if (MP_MX(B1, pred_flag_index_l0, mxB)) {
711  goto scalef;
712  }
713  if (MP_MX(B1, pred_flag_index_l1, mxB)) {
714  goto scalef;
715  }
716  }
717 
718  // above left spatial merge candidate
719  if (is_available_b2) {
720  if (MP_MX(B2, pred_flag_index_l0, mxB)) {
721  goto scalef;
722  }
723  if (MP_MX(B2, pred_flag_index_l1, mxB)) {
724  goto scalef;
725  }
726  }
727  availableFlagLXB0 = 0;
728 
729 scalef:
730  if (!isScaledFlag_L0) {
731  if (availableFlagLXB0) {
732  availableFlagLXA0 = 1;
733  mxA = mxB;
734  }
735  availableFlagLXB0 = 0;
736 
737  // XB0 and L1
738  if (is_available_b0) {
739  availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);
740  if (!availableFlagLXB0)
741  availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);
742  }
743 
744  if (is_available_b1 && !availableFlagLXB0) {
745  availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);
746  if (!availableFlagLXB0)
747  availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);
748  }
749 
750  if (is_available_b2 && !availableFlagLXB0) {
751  availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);
752  if (!availableFlagLXB0)
753  availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);
754  }
755  }
756 
757  if (availableFlagLXA0)
758  mvpcand_list[numMVPCandLX++] = mxA;
759 
760  if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
761  mvpcand_list[numMVPCandLX++] = mxB;
762 
763  //temporal motion vector prediction candidate
764  if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&
765  mvp_lx_flag == numMVPCandLX) {
766  Mv mv_col;
767  int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
768  nPbH, ref_idx,
769  &mv_col, LX);
770  if (available_col)
771  mvpcand_list[numMVPCandLX++] = mv_col;
772  }
773 
774  mv->mv[LX] = mvpcand_list[mvp_lx_flag];
775 }
HEVCLocalContext::na
NeighbourAvailable na
Definition: hevcdec.h:479
A
#define A(x)
Definition: vpx_arith.h:28
L1
F H1 F F H1 F F F F H1<-F-------F-------F v v v H2 H3 H2 ^ ^ ^ F-------F-------F-> H1<-F-------F-------F|||||||||F H1 F|||||||||F H1 Funavailable fullpel samples(outside the picture for example) shall be equalto the closest available fullpel sampleSmaller pel interpolation:--------------------------if diag_mc is set then points which lie on a line between 2 vertically, horizontally or diagonally adjacent halfpel points shall be interpolatedlinearly with rounding to nearest and halfway values rounded up.points which lie on 2 diagonals at the same time should only use the onediagonal not containing the fullpel point F--> O q O<--h1-> O q O<--F v \/v \/v O O O O O O O|/|\|q q q q q|/|\|O O O O O O O ^/\ ^/\ ^ h2--> O q O<--h3-> O q O<--h2 v \/v \/v O O O O O O O|\|/|q q q q q|\|/|O O O O O O O ^/\ ^/\ ^ F--> O q O<--h1-> O q O<--Fthe remaining points shall be bilinearly interpolated from theup to 4 surrounding halfpel and fullpel points, again rounding should be tonearest and halfway values rounded upcompliant Snow decoders MUST support 1-1/8 pel luma and 1/2-1/16 pel chromainterpolation at leastOverlapped block motion compensation:-------------------------------------FIXMELL band prediction:===================Each sample in the LL0 subband is predicted by the median of the left, top andleft+top-topleft samples, samples outside the subband shall be considered tobe 0. To reverse this prediction in the decoder apply the following.for(y=0;y< height;y++){ for(x=0;x< width;x++){ sample[y][x]+=median(sample[y-1][x], sample[y][x-1], sample[y-1][x]+sample[y][x-1]-sample[y-1][x-1]);}}sample[-1][ *]=sample[ *][-1]=0;width, height here are the width and height of the LL0 subband not of the finalvideoDequantization:===============FIXMEWavelet Transform:==================Snow supports 2 wavelet transforms, the symmetric biorthogonal 5/3 integertransform and an integer approximation of the symmetric biorthogonal 9/7daubechies wavelet.2D IDWT(inverse discrete wavelet transform) --------------------------------------------The 2D IDWT applies a 2D filter recursively, each time combining the4 lowest frequency subbands into a single subband until only 1 subbandremains.The 2D filter is done by first applying a 1D filter in the vertical directionand then applying it in the horizontal one. --------------- --------------- --------------- ---------------|LL0|HL0|||||||||||||---+---|HL1||L0|H0|HL1||LL1|HL1|||||LH0|HH0|||||||||||||-------+-------|-> L1 H1 LH1 HH1 LH1 HH1 LH1 HH1 L1
Definition: snow.txt:554
HEVCLocalContext
Definition: hevcdec.h:432
l0_l1_cand_idx
static const uint8_t l0_l1_cand_idx[12][2]
Definition: hevc_mvs.c:28
td
#define td
Definition: regdef.h:70
PRED_BLOCK_AVAILABLE
#define PRED_BLOCK_AVAILABLE(v)
Definition: hevc_mvs.c:277
CHECK_MVSET
#define CHECK_MVSET(l)
Definition: hevc_mvs.c:157
z_scan_block_avail
static av_always_inline int z_scan_block_avail(const HEVCContext *s, int xCurr, int yCurr, int xN, int yN)
Definition: hevc_mvs.c:65
B1
#define B1
Definition: faandct.c:41
av_clip_int8
#define av_clip_int8
Definition: common.h:104
HEVCLocalContext::ctb_up_flag
uint8_t ctb_up_flag
Definition: hevcdec.h:465
mv
static const int8_t mv[256][2]
Definition: 4xm.c:80
PART_2NxnU
@ PART_2NxnU
Definition: hevcdec.h:146
ff_hevc_luma_mv_mvp_mode
void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, 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:583
av_mod_uintp2
#define av_mod_uintp2
Definition: common.h:122
NeighbourAvailable::cand_left
int cand_left
Definition: hevcdec.h:355
NeighbourAvailable::cand_up
int cand_up
Definition: hevcdec.h:356
B0
#define B0
Definition: faandct.c:40
NeighbourAvailable::cand_up_right
int cand_up_right
Definition: hevcdec.h:358
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:344
MvField::mv
Mv mv[2]
Definition: hevcdec.h:348
HEVCLocalContext::ctb_up_left_flag
uint8_t ctb_up_left_flag
Definition: hevcdec.h:467
RefPicList
Definition: hevcdec.h:241
ff_thread_await_progress
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before ff_thread_await_progress() has been called on them. reget_buffer() and buffer age optimizations no longer work. *The contents of buffers must not be written to after ff_thread_report_progress() has been called on them. This includes draw_edges(). Porting codecs to frame threading
PF_INTRA
@ PF_INTRA
Definition: hevcdec.h:165
HEVCLocalContext::end_of_tiles_x
int end_of_tiles_x
Definition: hevcdec.h:468
CodingUnit::x
int x
Definition: hevcdec.h:330
HEVCLocalContext::ctb_up_right_flag
uint8_t ctb_up_right_flag
Definition: hevcdec.h:466
mv_mp_mode_mx
static int mv_mp_mode_mx(const HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
Definition: hevc_mvs.c:530
RefPicList::nb_refs
int nb_refs
Definition: hevcdec.h:245
MRG_MAX_NUM_CANDS
#define MRG_MAX_NUM_CANDS
Definition: hevcdec.h:55
MvField::ref_idx
int8_t ref_idx[2]
Definition: hevcdec.h:349
MATCH_MV
#define MATCH_MV(x)
Definition: hevc_mvs.c:95
HEVCLocalContext::parent
const struct HEVCContext * parent
Definition: hevcdec.h:440
s
#define s(width, name)
Definition: cbs_vp9.c:256
NeighbourAvailable::cand_bottom_left
int cand_bottom_left
Definition: hevcdec.h:354
AV_ZERO32
#define AV_ZERO32(d)
Definition: intreadwrite.h:629
is_diff_mer
static av_always_inline int is_diff_mer(const HEVCContext *s, int xN, int yN, int xP, int yP)
Definition: hevc_mvs.c:87
B
#define B
Definition: huffyuv.h:42
TAB_MVF_PU
#define TAB_MVF_PU(v)
Definition: hevc_mvs.c:207
ff_hevc_set_neighbour_available
void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH)
Definition: hevc_mvs.c:43
NeighbourAvailable::cand_up_right_sap
int cand_up_right_sap
Definition: hevcdec.h:359
temporal_luma_motion_vector
static int temporal_luma_motion_vector(const HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int refIdxLx, Mv *mvLXCol, int X)
Definition: hevc_mvs.c:219
threadframe.h
HEVC_SLICE_B
@ HEVC_SLICE_B
Definition: hevc.h:96
av_clip_int16
#define av_clip_int16
Definition: common.h:110
derive_temporal_colocated_mvs
static int derive_temporal_colocated_mvs(const HEVCContext *s, MvField temp_col, int refIdxLx, Mv *mvLXCol, int X, int colPic, const RefPicList *refPicList_col)
Definition: hevc_mvs.c:164
av_clip_intp2
#define av_clip_intp2
Definition: common.h:116
B2
#define B2
Definition: faandct.c:42
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
compare_mv_ref_idx
static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B)
Definition: hevc_mvs.c:99
abs
#define abs(x)
Definition: cuda_runtime.h:35
PART_Nx2N
@ PART_Nx2N
Definition: hevcdec.h:144
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:343
PF_BI
@ PF_BI
Definition: hevcdec.h:168
mv_scale
static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb)
Definition: hevc_mvs.c:116
PART_nLx2N
@ PART_nLx2N
Definition: hevcdec.h:148
HEVCLocalContext::ctb_left_flag
uint8_t ctb_left_flag
Definition: hevcdec.h:464
TAB_MVF
#define TAB_MVF(x, y)
Definition: hevc_mvs.c:204
hevcdec.h
mv_mp_mode_mx_lt
static int mv_mp_mode_mx_lt(const HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
Definition: hevc_mvs.c:546
PART_2NxnD
@ PART_2NxnD
Definition: hevcdec.h:147
AVAILABLE
#define AVAILABLE(cand, v)
Definition: hevc_mvs.c:274
ff_hevc_luma_mv_merge_mode
void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv)
Definition: hevc_mvs.c:480
MvField
Definition: hevcdec.h:347
COMPARE_MV_REFIDX
#define COMPARE_MV_REFIDX(a, b)
Definition: hevc_mvs.c:280
PF_L1
@ PF_L1
Definition: hevcdec.h:167
N
#define N
Definition: af_mcompand.c:53
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:350
dist_scale
static av_always_inline void dist_scale(const 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:513
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1513
PART_nRx2N
@ PART_nRx2N
Definition: hevcdec.h:149
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
HEVCFrame
Definition: hevcdec.h:401
NeighbourAvailable::cand_up_left
int cand_up_left
Definition: hevcdec.h:357
RefPicList::list
int list[HEVC_MAX_REFS]
Definition: hevcdec.h:243
av_always_inline
#define av_always_inline
Definition: attributes.h:49
HEVC_SLICE_P
@ HEVC_SLICE_P
Definition: hevc.h:97
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
PF_L0
@ PF_L0
Definition: hevcdec.h:166
tb
#define tb
Definition: regdef.h:68
AV_COPY32
#define AV_COPY32(d, s)
Definition: intreadwrite.h:601
hevc.h
AV_RN32A
#define AV_RN32A(p)
Definition: intreadwrite.h:526
MP_MX
#define MP_MX(v, pred, mx)
Definition: hevc_mvs.c:571
HEVCContext
Definition: hevcdec.h:490
MATCH
#define MATCH(x)
Definition: hevc_mvs.c:96
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
MIN_TB_ADDR_ZS
#define MIN_TB_ADDR_ZS(x, y)
CodingUnit::y
int y
Definition: hevcdec.h:331
Mv
Definition: hevcdec.h:342
AV_ZERO16
#define AV_ZERO16(d)
Definition: intreadwrite.h:625
CodingUnit::part_mode
enum PartMode part_mode
PartMode.
Definition: hevcdec.h:334
HEVCLocalContext::cu
CodingUnit cu
Definition: hevcdec.h:477
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
A1
#define A1
Definition: binkdsp.c:31
X
@ X
Definition: vf_addroi.c:26
MP_MX_LT
#define MP_MX_LT(v, pred, mx)
Definition: hevc_mvs.c:577
RefPicList::isLongTerm
int isLongTerm[HEVC_MAX_REFS]
Definition: hevcdec.h:244
HEVCLocalContext::end_of_tiles_y
int end_of_tiles_y
Definition: hevcdec.h:469
derive_spatial_merge_candidates
static void derive_spatial_merge_candidates(HEVCLocalContext *lc, const 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:286
DERIVE_TEMPORAL_COLOCATED_MVS
#define DERIVE_TEMPORAL_COLOCATED_MVS
Definition: hevc_mvs.c:211
PART_2NxN
@ PART_2NxN
Definition: hevcdec.h:143
check_mvset
static int check_mvset(Mv *mvLXCol, const Mv *mvCol, int colPic, int poc, const RefPicList *refPicList, int X, int refIdxLx, const RefPicList *refPicList_col, int listCol, int refidxCol)
Definition: hevc_mvs.c:130