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 
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 {
88  uint8_t plevel = s->ps.pps->log2_parallel_merge_level;
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 
229  HEVCFrame *ref = s->ref->collocated_ref;
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
410  if (s->sh.slice_temporal_mvp_enabled_flag &&
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  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 }
HEVCLocalContext::na
NeighbourAvailable na
Definition: hevcdec.h:456
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:424
l0_l1_cand_idx
static const uint8_t l0_l1_cand_idx[12][2]
Definition: hevc_mvs.c:27
td
#define td
Definition: regdef.h:70
PRED_BLOCK_AVAILABLE
#define PRED_BLOCK_AVAILABLE(v)
Definition: hevc_mvs.c:276
CHECK_MVSET
#define CHECK_MVSET(l)
Definition: hevc_mvs.c:156
z_scan_block_avail
static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr, int xN, int yN)
Definition: hevc_mvs.c:64
B1
#define B1
Definition: faandct.c:41
HEVCLocalContext::ctb_up_flag
uint8_t ctb_up_flag
Definition: hevcdec.h:442
mv
static const int8_t mv[256][2]
Definition: 4xm.c:77
PART_2NxnU
@ PART_2NxnU
Definition: hevcdec.h:148
NeighbourAvailable::cand_left
int cand_left
Definition: hevcdec.h:352
NeighbourAvailable::cand_up
int cand_up
Definition: hevcdec.h:353
B0
#define B0
Definition: faandct.c:40
check_mvset
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
NeighbourAvailable::cand_up_right
int cand_up_right
Definition: hevcdec.h:355
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:341
MvField::mv
Mv mv[2]
Definition: hevcdec.h:345
is_diff_mer
static av_always_inline int is_diff_mer(HEVCContext *s, int xN, int yN, int xP, int yP)
Definition: hevc_mvs.c:86
HEVCLocalContext::ctb_up_left_flag
uint8_t ctb_up_left_flag
Definition: hevcdec.h:444
RefPicList
Definition: hevcdec.h:238
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:167
temporal_luma_motion_vector
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
HEVCLocalContext::end_of_tiles_x
int end_of_tiles_x
Definition: hevcdec.h:445
A
#define A(x)
Definition: vp56_arith.h:28
CodingUnit::x
int x
Definition: hevcdec.h:327
HEVCLocalContext::ctb_up_right_flag
uint8_t ctb_up_right_flag
Definition: hevcdec.h:443
X
@ X
Definition: vf_addroi.c:26
RefPicList::nb_refs
int nb_refs
Definition: hevcdec.h:242
ff_hevc_luma_mv_mvp_mode
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
MRG_MAX_NUM_CANDS
#define MRG_MAX_NUM_CANDS
Definition: hevcdec.h:57
MvField::ref_idx
int8_t ref_idx[2]
Definition: hevcdec.h:346
MATCH_MV
#define MATCH_MV(x)
Definition: hevc_mvs.c:94
s
#define s(width, name)
Definition: cbs_vp9.c:257
NeighbourAvailable::cand_bottom_left
int cand_bottom_left
Definition: hevcdec.h:351
AV_ZERO32
#define AV_ZERO32(d)
Definition: intreadwrite.h:629
TAB_MVF_PU
#define TAB_MVF_PU(v)
Definition: hevc_mvs.c:206
ff_hevc_luma_mv_merge_mode
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
NeighbourAvailable::cand_up_right_sap
int cand_up_right_sap
Definition: hevcdec.h:356
HEVC_SLICE_B
@ HEVC_SLICE_B
Definition: hevc.h:96
src
#define src
Definition: vp8dsp.c:254
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:98
abs
#define abs(x)
Definition: cuda_runtime.h:35
PART_Nx2N
@ PART_Nx2N
Definition: hevcdec.h:146
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:340
PF_BI
@ PF_BI
Definition: hevcdec.h:170
PART_nLx2N
@ PART_nLx2N
Definition: hevcdec.h:150
HEVCLocalContext::ctb_left_flag
uint8_t ctb_left_flag
Definition: hevcdec.h:441
TAB_MVF
#define TAB_MVF(x, y)
Definition: hevc_mvs.c:203
hevcdec.h
ff_hevc_set_neighbour_available
void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, int nPbW, int nPbH)
Definition: hevc_mvs.c:42
PART_2NxnD
@ PART_2NxnD
Definition: hevcdec.h:149
AVAILABLE
#define AVAILABLE(cand, v)
Definition: hevc_mvs.c:273
MvField
Definition: hevcdec.h:344
COMPARE_MV_REFIDX
#define COMPARE_MV_REFIDX(a, b)
Definition: hevc_mvs.c:279
PF_L1
@ PF_L1
Definition: hevcdec.h:169
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
N
#define N
Definition: af_mcompand.c:54
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:347
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1796
PART_nRx2N
@ PART_nRx2N
Definition: hevcdec.h:151
derive_spatial_merge_candidates
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
HEVCFrame
Definition: hevcdec.h:395
NeighbourAvailable::cand_up_left
int cand_up_left
Definition: hevcdec.h:354
RefPicList::list
int list[HEVC_MAX_REFS]
Definition: hevcdec.h:240
av_always_inline
#define av_always_inline
Definition: attributes.h:49
HEVC_SLICE_P
@ HEVC_SLICE_P
Definition: hevc.h:97
PF_L0
@ PF_L0
Definition: hevcdec.h:168
uint8_t
uint8_t
Definition: audio_convert.c:194
tb
#define tb
Definition: regdef.h:68
AV_COPY32
#define AV_COPY32(d, s)
Definition: intreadwrite.h:601
mv_scale
static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb)
Definition: hevc_mvs.c:115
hevc.h
dist_scale
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
AV_RN32A
#define AV_RN32A(p)
Definition: intreadwrite.h:526
MP_MX
#define MP_MX(v, pred, mx)
Definition: hevc_mvs.c:570
B
#define B
Definition: huffyuvdsp.h:32
mv_mp_mode_mx
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
HEVCContext
Definition: hevcdec.h:467
MATCH
#define MATCH(x)
Definition: hevc_mvs.c:95
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
MIN_TB_ADDR_ZS
#define MIN_TB_ADDR_ZS(x, y)
CodingUnit::y
int y
Definition: hevcdec.h:328
Mv
Definition: hevcdec.h:339
derive_temporal_colocated_mvs
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
AV_ZERO16
#define AV_ZERO16(d)
Definition: intreadwrite.h:625
CodingUnit::part_mode
enum PartMode part_mode
PartMode.
Definition: hevcdec.h:331
HEVCLocalContext::cu
CodingUnit cu
Definition: hevcdec.h:454
mv_mp_mode_mx_lt
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
A1
#define A1
Definition: binkdsp.c:31
MP_MX_LT
#define MP_MX_LT(v, pred, mx)
Definition: hevc_mvs.c:576
RefPicList::isLongTerm
int isLongTerm[HEVC_MAX_REFS]
Definition: hevcdec.h:241
HEVCLocalContext::end_of_tiles_y
int end_of_tiles_y
Definition: hevcdec.h:446
DERIVE_TEMPORAL_COLOCATED_MVS
#define DERIVE_TEMPORAL_COLOCATED_MVS
Definition: hevc_mvs.c:210
PART_2NxN
@ PART_2NxN
Definition: hevcdec.h:145