FFmpeg
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 "progressframe.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, int log2_ctb_size)
45 {
46  int x0b = av_zero_extend(x0, log2_ctb_size);
47  int y0b = av_zero_extend(y0, 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->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag;
52  lc->na.cand_up_right_sap =
53  (x0b + nPbW == 1 << 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
66  int xCurr, int yCurr, int xN, int yN)
67 {
68 #define MIN_TB_ADDR_ZS(x, y) \
69  pps->min_tb_addr_zs[(y) * (sps->tb_mask+2) + (x)]
70 
71  int xCurr_ctb = xCurr >> sps->log2_ctb_size;
72  int yCurr_ctb = yCurr >> sps->log2_ctb_size;
73  int xN_ctb = xN >> sps->log2_ctb_size;
74  int yN_ctb = yN >> 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 >> sps->log2_min_tb_size) & sps->tb_mask,
79  (yCurr >> sps->log2_min_tb_size) & sps->tb_mask);
80  int N = MIN_TB_ADDR_ZS((xN >> sps->log2_min_tb_size) & sps->tb_mask,
81  (yN >> sps->log2_min_tb_size) & 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 HEVCPPS *pps, int xN, int yN, int xP, int yP)
88 {
89  uint8_t plevel = 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->cur_frame->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) >> sps->log2_min_pu_size), \
209  ((y ## v) >> 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  */
220  int x0, int y0,
221  int nPbW, int nPbH, int refIdxLx,
222  Mv *mvLXCol, int X)
223 {
224  const MvField *tab_mvf;
225  MvField temp_col;
226  int x, y, x_pu, y_pu;
227  int min_pu_width = sps->min_pu_width;
228  int availableFlagLXCol = 0;
229  int colPic;
230 
231  const HEVCFrame *ref = s->collocated_ref;
232 
233  if (!ref) {
234  memset(mvLXCol, 0, sizeof(*mvLXCol));
235  return 0;
236  }
237 
238  tab_mvf = ref->tab_mvf;
239  colPic = ref->poc;
240 
241  //bottom right collocated motion vector
242  x = x0 + nPbW;
243  y = y0 + nPbH;
244 
245  if (tab_mvf &&
246  (y0 >> sps->log2_ctb_size) == (y >> sps->log2_ctb_size) &&
247  y < sps->height &&
248  x < sps->width) {
249  x &= ~15;
250  y &= ~15;
251  if (s->avctx->active_thread_type == FF_THREAD_FRAME)
252  ff_progress_frame_await(&ref->tf, y);
253  x_pu = x >> sps->log2_min_pu_size;
254  y_pu = y >> sps->log2_min_pu_size;
255  temp_col = TAB_MVF(x_pu, y_pu);
256  availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
257  }
258 
259  // derive center collocated motion vector
260  if (tab_mvf && !availableFlagLXCol) {
261  x = x0 + (nPbW >> 1);
262  y = y0 + (nPbH >> 1);
263  x &= ~15;
264  y &= ~15;
265  if (s->avctx->active_thread_type == FF_THREAD_FRAME)
266  ff_progress_frame_await(&ref->tf, y);
267  x_pu = x >> sps->log2_min_pu_size;
268  y_pu = y >> sps->log2_min_pu_size;
269  temp_col = TAB_MVF(x_pu, y_pu);
270  availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
271  }
272  return availableFlagLXCol;
273 }
274 
275 #define AVAILABLE(cand, v) \
276  (cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA))
277 
278 #define PRED_BLOCK_AVAILABLE(v) \
279  z_scan_block_avail(pps, sps, x0, y0, x ## v, y ## v)
280 
281 #define COMPARE_MV_REFIDX(a, b) \
282  compare_mv_ref_idx(TAB_MVF_PU(a), TAB_MVF_PU(b))
283 
284 /*
285  * 8.5.3.1.2 Derivation process for spatial merging candidates
286  */
288  const HEVCPPS *pps, const HEVCSPS *sps,
289  int x0, int y0,
290  int nPbW, int nPbH,
291  int log2_cb_size,
292  int singleMCLFlag, int part_idx,
293  int merge_idx,
294  struct MvField mergecandlist[])
295 {
296  const RefPicList *refPicList = s->cur_frame->refPicList;
297  const MvField *tab_mvf = s->cur_frame->tab_mvf;
298 
299  const int min_pu_width = sps->min_pu_width;
300 
301  const int cand_bottom_left = lc->na.cand_bottom_left;
302  const int cand_left = lc->na.cand_left;
303  const int cand_up_left = lc->na.cand_up_left;
304  const int cand_up = lc->na.cand_up;
305  const int cand_up_right = lc->na.cand_up_right_sap;
306 
307  const int xA1 = x0 - 1;
308  const int yA1 = y0 + nPbH - 1;
309 
310  const int xB1 = x0 + nPbW - 1;
311  const int yB1 = y0 - 1;
312 
313  const int xB0 = x0 + nPbW;
314  const int yB0 = y0 - 1;
315 
316  const int xA0 = x0 - 1;
317  const int yA0 = y0 + nPbH;
318 
319  const int xB2 = x0 - 1;
320  const int yB2 = y0 - 1;
321 
322  const int nb_refs = (s->sh.slice_type == HEVC_SLICE_P) ?
323  s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
324 
325  int zero_idx = 0;
326 
327  int nb_merge_cand = 0;
328  int nb_orig_merge_cand = 0;
329 
330  int is_available_a0;
331  int is_available_a1;
332  int is_available_b0;
333  int is_available_b1;
334  int is_available_b2;
335 
336 
337  if (!singleMCLFlag && part_idx == 1 &&
338  (lc->cu.part_mode == PART_Nx2N ||
339  lc->cu.part_mode == PART_nLx2N ||
340  lc->cu.part_mode == PART_nRx2N) ||
341  is_diff_mer(pps, xA1, yA1, x0, y0)) {
342  is_available_a1 = 0;
343  } else {
344  is_available_a1 = AVAILABLE(cand_left, A1);
345  if (is_available_a1) {
346  mergecandlist[nb_merge_cand] = TAB_MVF_PU(A1);
347  if (merge_idx == 0)
348  return;
349  nb_merge_cand++;
350  }
351  }
352 
353  if (!singleMCLFlag && part_idx == 1 &&
354  (lc->cu.part_mode == PART_2NxN ||
355  lc->cu.part_mode == PART_2NxnU ||
356  lc->cu.part_mode == PART_2NxnD) ||
357  is_diff_mer(pps, xB1, yB1, x0, y0)) {
358  is_available_b1 = 0;
359  } else {
360  is_available_b1 = AVAILABLE(cand_up, B1);
361  if (is_available_b1 &&
362  !(is_available_a1 && COMPARE_MV_REFIDX(B1, A1))) {
363  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B1);
364  if (merge_idx == nb_merge_cand)
365  return;
366  nb_merge_cand++;
367  }
368  }
369 
370  // above right spatial merge candidate
371  is_available_b0 = AVAILABLE(cand_up_right, B0) &&
372  xB0 < sps->width &&
374  !is_diff_mer(pps, xB0, yB0, x0, y0);
375 
376  if (is_available_b0 &&
377  !(is_available_b1 && COMPARE_MV_REFIDX(B0, B1))) {
378  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0);
379  if (merge_idx == nb_merge_cand)
380  return;
381  nb_merge_cand++;
382  }
383 
384  // left bottom spatial merge candidate
385  is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
386  yA0 < sps->height &&
388  !is_diff_mer(pps, xA0, yA0, x0, y0);
389 
390  if (is_available_a0 &&
391  !(is_available_a1 && COMPARE_MV_REFIDX(A0, A1))) {
392  mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0);
393  if (merge_idx == nb_merge_cand)
394  return;
395  nb_merge_cand++;
396  }
397 
398  // above left spatial merge candidate
399  is_available_b2 = AVAILABLE(cand_up_left, B2) &&
400  !is_diff_mer(pps, xB2, yB2, x0, y0);
401 
402  if (is_available_b2 &&
403  !(is_available_a1 && COMPARE_MV_REFIDX(B2, A1)) &&
404  !(is_available_b1 && COMPARE_MV_REFIDX(B2, B1)) &&
405  nb_merge_cand != 4) {
406  mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2);
407  if (merge_idx == nb_merge_cand)
408  return;
409  nb_merge_cand++;
410  }
411 
412  // temporal motion vector candidate
413  if (s->sh.slice_temporal_mvp_enabled_flag &&
414  nb_merge_cand < s->sh.max_num_merge_cand) {
415  Mv mv_l0_col = { 0 }, mv_l1_col = { 0 };
416  int available_l0 = temporal_luma_motion_vector(s, sps, x0, y0, nPbW, nPbH,
417  0, &mv_l0_col, 0);
418  int available_l1 = (s->sh.slice_type == HEVC_SLICE_B) ?
419  temporal_luma_motion_vector(s, sps, x0, y0, nPbW, nPbH,
420  0, &mv_l1_col, 1) : 0;
421 
422  if (available_l0 || available_l1) {
423  mergecandlist[nb_merge_cand].pred_flag = available_l0 + (available_l1 << 1);
424  AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx);
425  mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
426  mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
427 
428  if (merge_idx == nb_merge_cand)
429  return;
430  nb_merge_cand++;
431  }
432  }
433 
434  nb_orig_merge_cand = nb_merge_cand;
435 
436  // combined bi-predictive merge candidates (applies for B slices)
437  if (s->sh.slice_type == HEVC_SLICE_B && nb_orig_merge_cand > 1 &&
438  nb_orig_merge_cand < s->sh.max_num_merge_cand) {
439  int comb_idx = 0;
440 
441  for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
442  comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
443  int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
444  int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
445  MvField l0_cand = mergecandlist[l0_cand_idx];
446  MvField l1_cand = mergecandlist[l1_cand_idx];
447 
448  if ((l0_cand.pred_flag & PF_L0) && (l1_cand.pred_flag & PF_L1) &&
449  (refPicList[0].list[l0_cand.ref_idx[0]] !=
450  refPicList[1].list[l1_cand.ref_idx[1]] ||
451  AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {
452  mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0];
453  mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1];
454  mergecandlist[nb_merge_cand].pred_flag = PF_BI;
455  AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);
456  AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);
457  if (merge_idx == nb_merge_cand)
458  return;
459  nb_merge_cand++;
460  }
461  }
462  }
463 
464  // append Zero motion vector candidates
465  while (nb_merge_cand < s->sh.max_num_merge_cand) {
466  mergecandlist[nb_merge_cand].pred_flag = PF_L0 + ((s->sh.slice_type == HEVC_SLICE_B) << 1);
467  AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);
468  AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);
469  mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
470  mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
471 
472  if (merge_idx == nb_merge_cand)
473  return;
474  nb_merge_cand++;
475  zero_idx++;
476  }
477 }
478 
479 /*
480  * 8.5.3.1.1 Derivation process of luma Mvs for merge mode
481  */
483  int x0, int y0, int nPbW,
484  int nPbH, int log2_cb_size, int part_idx,
485  int merge_idx, MvField *mv)
486 {
487  const HEVCSPS *const sps = pps->sps;
488  const HEVCContext *const s = lc->parent;
489  int singleMCLFlag = 0;
490  int nCS = 1 << log2_cb_size;
491  MvField mergecand_list[MRG_MAX_NUM_CANDS];
492  int nPbW2 = nPbW;
493  int nPbH2 = nPbH;
494 
495  if (pps->log2_parallel_merge_level > 2 && nCS == 8) {
496  singleMCLFlag = 1;
497  x0 = lc->cu.x;
498  y0 = lc->cu.y;
499  nPbW = nCS;
500  nPbH = nCS;
501  part_idx = 0;
502  }
503 
504  ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH, sps->log2_ctb_size);
505  derive_spatial_merge_candidates(lc, s, pps, sps, x0, y0, nPbW, nPbH, log2_cb_size,
506  singleMCLFlag, part_idx,
507  merge_idx, mergecand_list);
508 
509  if (mergecand_list[merge_idx].pred_flag == PF_BI &&
510  (nPbW2 + nPbH2) == 12) {
511  mergecand_list[merge_idx].pred_flag = PF_L0;
512  }
513 
514  *mv = mergecand_list[merge_idx];
515 }
516 
518  int min_pu_width, int x, int y,
519  int elist, int ref_idx_curr, int ref_idx)
520 {
521  const RefPicList *refPicList = s->cur_frame->refPicList;
522  const MvField *tab_mvf = s->cur_frame->tab_mvf;
523  int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
524  int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx];
525 
526  if (ref_pic_elist != ref_pic_curr) {
527  int poc_diff = s->poc - ref_pic_elist;
528  if (!poc_diff)
529  poc_diff = 1;
530  mv_scale(mv, mv, poc_diff, s->poc - ref_pic_curr);
531  }
532 }
533 
534 static int mv_mp_mode_mx(const HEVCContext *s, const HEVCSPS *sps,
535  int x, int y, int pred_flag_index,
536  Mv *mv, int ref_idx_curr, int ref_idx)
537 {
538  const MvField *tab_mvf = s->cur_frame->tab_mvf;
539  int min_pu_width = sps->min_pu_width;
540 
541  const RefPicList *refPicList = s->cur_frame->refPicList;
542 
543  if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) &&
544  refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
545  *mv = TAB_MVF(x, y).mv[pred_flag_index];
546  return 1;
547  }
548  return 0;
549 }
550 
551 static int mv_mp_mode_mx_lt(const HEVCContext *s, const HEVCSPS *sps,
552  int x, int y, int pred_flag_index,
553  Mv *mv, int ref_idx_curr, int ref_idx)
554 {
555  const MvField *tab_mvf = s->cur_frame->tab_mvf;
556  int min_pu_width = sps->min_pu_width;
557 
558  const RefPicList *refPicList = s->cur_frame->refPicList;
559 
560  if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) {
561  int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
562 
563  int colIsLongTerm =
564  refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
565 
566  if (colIsLongTerm == currIsLongTerm) {
567  *mv = TAB_MVF(x, y).mv[pred_flag_index];
568  if (!currIsLongTerm)
569  dist_scale(s, mv, min_pu_width, x, y,
570  pred_flag_index, ref_idx_curr, ref_idx);
571  return 1;
572  }
573  }
574  return 0;
575 }
576 
577 #define MP_MX(v, pred, mx) \
578  mv_mp_mode_mx(s, sps, \
579  (x ## v) >> sps->log2_min_pu_size, \
580  (y ## v) >> sps->log2_min_pu_size, \
581  pred, &mx, ref_idx_curr, ref_idx)
582 
583 #define MP_MX_LT(v, pred, mx) \
584  mv_mp_mode_mx_lt(s, sps, \
585  (x ## v) >> sps->log2_min_pu_size, \
586  (y ## v) >> sps->log2_min_pu_size, \
587  pred, &mx, ref_idx_curr, ref_idx)
588 
590  int x0, int y0, int nPbW,
591  int nPbH, int log2_cb_size, int part_idx,
592  int merge_idx, MvField *mv,
593  int mvp_lx_flag, int LX)
594 {
595  const HEVCSPS *const sps = pps->sps;
596  const HEVCContext *const s = lc->parent;
597  const MvField *const tab_mvf = s->cur_frame->tab_mvf;
598  int isScaledFlag_L0 = 0;
599  int availableFlagLXA0 = 1;
600  int availableFlagLXB0 = 1;
601  int numMVPCandLX = 0;
602  int min_pu_width = sps->min_pu_width;
603 
604  int xA0, yA0;
605  int is_available_a0;
606  int xA1, yA1;
607  int is_available_a1;
608  int xB0, yB0;
609  int is_available_b0;
610  int xB1, yB1;
611  int is_available_b1;
612  int xB2, yB2;
613  int is_available_b2;
614 
615  Mv mvpcand_list[2] = { { 0 } };
616  Mv mxA;
617  Mv mxB;
618  int ref_idx_curr;
619  int ref_idx = 0;
620  int pred_flag_index_l0;
621  int pred_flag_index_l1;
622 
623  const int cand_bottom_left = lc->na.cand_bottom_left;
624  const int cand_left = lc->na.cand_left;
625  const int cand_up_left = lc->na.cand_up_left;
626  const int cand_up = lc->na.cand_up;
627  const int cand_up_right = lc->na.cand_up_right_sap;
628  ref_idx_curr = LX;
629  ref_idx = mv->ref_idx[LX];
630  pred_flag_index_l0 = LX;
631  pred_flag_index_l1 = !LX;
632 
633  // left bottom spatial candidate
634  xA0 = x0 - 1;
635  yA0 = y0 + nPbH;
636 
637  is_available_a0 = AVAILABLE(cand_bottom_left, A0) &&
638  yA0 < sps->height &&
640 
641  //left spatial merge candidate
642  xA1 = x0 - 1;
643  yA1 = y0 + nPbH - 1;
644 
645  is_available_a1 = AVAILABLE(cand_left, A1);
646  if (is_available_a0 || is_available_a1)
647  isScaledFlag_L0 = 1;
648 
649  if (is_available_a0) {
650  if (MP_MX(A0, pred_flag_index_l0, mxA)) {
651  goto b_candidates;
652  }
653  if (MP_MX(A0, pred_flag_index_l1, mxA)) {
654  goto b_candidates;
655  }
656  }
657 
658  if (is_available_a1) {
659  if (MP_MX(A1, pred_flag_index_l0, mxA)) {
660  goto b_candidates;
661  }
662  if (MP_MX(A1, pred_flag_index_l1, mxA)) {
663  goto b_candidates;
664  }
665  }
666 
667  if (is_available_a0) {
668  if (MP_MX_LT(A0, pred_flag_index_l0, mxA)) {
669  goto b_candidates;
670  }
671  if (MP_MX_LT(A0, pred_flag_index_l1, mxA)) {
672  goto b_candidates;
673  }
674  }
675 
676  if (is_available_a1) {
677  if (MP_MX_LT(A1, pred_flag_index_l0, mxA)) {
678  goto b_candidates;
679  }
680  if (MP_MX_LT(A1, pred_flag_index_l1, mxA)) {
681  goto b_candidates;
682  }
683  }
684  availableFlagLXA0 = 0;
685 
686 b_candidates:
687  // B candidates
688  // above right spatial merge candidate
689  xB0 = x0 + nPbW;
690  yB0 = y0 - 1;
691 
692  is_available_b0 = AVAILABLE(cand_up_right, B0) &&
693  xB0 < sps->width &&
695 
696  // above spatial merge candidate
697  xB1 = x0 + nPbW - 1;
698  yB1 = y0 - 1;
699  is_available_b1 = AVAILABLE(cand_up, B1);
700 
701  // above left spatial merge candidate
702  xB2 = x0 - 1;
703  yB2 = y0 - 1;
704  is_available_b2 = AVAILABLE(cand_up_left, B2);
705 
706  // above right spatial merge candidate
707  if (is_available_b0) {
708  if (MP_MX(B0, pred_flag_index_l0, mxB)) {
709  goto scalef;
710  }
711  if (MP_MX(B0, pred_flag_index_l1, mxB)) {
712  goto scalef;
713  }
714  }
715 
716  // above spatial merge candidate
717  if (is_available_b1) {
718  if (MP_MX(B1, pred_flag_index_l0, mxB)) {
719  goto scalef;
720  }
721  if (MP_MX(B1, pred_flag_index_l1, mxB)) {
722  goto scalef;
723  }
724  }
725 
726  // above left spatial merge candidate
727  if (is_available_b2) {
728  if (MP_MX(B2, pred_flag_index_l0, mxB)) {
729  goto scalef;
730  }
731  if (MP_MX(B2, pred_flag_index_l1, mxB)) {
732  goto scalef;
733  }
734  }
735  availableFlagLXB0 = 0;
736 
737 scalef:
738  if (!isScaledFlag_L0) {
739  if (availableFlagLXB0) {
740  availableFlagLXA0 = 1;
741  mxA = mxB;
742  }
743  availableFlagLXB0 = 0;
744 
745  // XB0 and L1
746  if (is_available_b0) {
747  availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);
748  if (!availableFlagLXB0)
749  availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);
750  }
751 
752  if (is_available_b1 && !availableFlagLXB0) {
753  availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);
754  if (!availableFlagLXB0)
755  availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);
756  }
757 
758  if (is_available_b2 && !availableFlagLXB0) {
759  availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);
760  if (!availableFlagLXB0)
761  availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);
762  }
763  }
764 
765  if (availableFlagLXA0)
766  mvpcand_list[numMVPCandLX++] = mxA;
767 
768  if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
769  mvpcand_list[numMVPCandLX++] = mxB;
770 
771  //temporal motion vector prediction candidate
772  if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag &&
773  mvp_lx_flag == numMVPCandLX) {
774  Mv mv_col;
775  int available_col = temporal_luma_motion_vector(s, sps, x0, y0, nPbW,
776  nPbH, ref_idx,
777  &mv_col, LX);
778  if (available_col)
779  mvpcand_list[numMVPCandLX++] = mv_col;
780  }
781 
782  mv->mv[LX] = mvpcand_list[mvp_lx_flag];
783 }
HEVCLocalContext::na
NeighbourAvailable na
Definition: hevcdec.h:435
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:389
ff_hevc_luma_mv_mvp_mode
void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, const HEVCPPS *pps, 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: mvs.c:589
TAB_MVF_PU
#define TAB_MVF_PU(v)
Definition: mvs.c:207
MP_MX_LT
#define MP_MX_LT(v, pred, mx)
Definition: mvs.c:583
av_clip_int8
#define av_clip_int8
Definition: common.h:109
HEVCLocalContext::ctb_up_flag
uint8_t ctb_up_flag
Definition: hevcdec.h:421
mv
static const int8_t mv[256][2]
Definition: 4xm.c:81
CHECK_MVSET
#define CHECK_MVSET(l)
Definition: mvs.c:157
MATCH_MV
#define MATCH_MV(x)
Definition: mvs.c:95
PART_2NxnU
@ PART_2NxnU
Definition: hevcdec.h:95
NeighbourAvailable::cand_left
int cand_left
Definition: hevcdec.h:311
NeighbourAvailable::cand_up
int cand_up
Definition: hevcdec.h:312
NeighbourAvailable::cand_up_right
int cand_up_right
Definition: hevcdec.h:314
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:300
l0_l1_cand_idx
static const uint8_t l0_l1_cand_idx[12][2]
Definition: mvs.c:28
HEVCLocalContext::ctb_up_left_flag
uint8_t ctb_up_left_flag
Definition: hevcdec.h:423
RefPicList
Definition: hevcdec.h:190
PF_INTRA
@ PF_INTRA
Definition: hevcdec.h:114
B1
@ B1
Definition: mvs.c:528
HEVCLocalContext::end_of_tiles_x
int end_of_tiles_x
Definition: hevcdec.h:424
CodingUnit::x
int x
Definition: hevcdec.h:286
HEVCLocalContext::ctb_up_right_flag
uint8_t ctb_up_right_flag
Definition: hevcdec.h:422
derive_spatial_merge_candidates
static void derive_spatial_merge_candidates(HEVCLocalContext *lc, const HEVCContext *s, const HEVCPPS *pps, const HEVCSPS *sps, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int singleMCLFlag, int part_idx, int merge_idx, struct MvField mergecandlist[])
Definition: mvs.c:287
RefPicList::nb_refs
int nb_refs
Definition: hevcdec.h:194
progressframe.h
MRG_MAX_NUM_CANDS
#define MRG_MAX_NUM_CANDS
Definition: hevcdec.h:56
MATCH
#define MATCH(x)
Definition: mvs.c:96
HEVC_SLICE_B
@ HEVC_SLICE_B
Definition: hevc.h:96
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: mvs.c:130
mv_mp_mode_mx
static int mv_mp_mode_mx(const HEVCContext *s, const HEVCSPS *sps, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
Definition: mvs.c:534
z_scan_block_avail
static av_always_inline int z_scan_block_avail(const HEVCPPS *pps, const HEVCSPS *sps, int xCurr, int yCurr, int xN, int yN)
Definition: mvs.c:65
width
#define width
ff_hevc_luma_mv_merge_mode
void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, const HEVCPPS *pps, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv)
Definition: mvs.c:482
HEVCLocalContext::parent
const struct HEVCContext * parent
Definition: hevcdec.h:397
s
#define s(width, name)
Definition: cbs_vp9.c:198
NeighbourAvailable::cand_bottom_left
int cand_bottom_left
Definition: hevcdec.h:310
X
@ X
Definition: vf_addroi.c:27
AV_ZERO32
#define AV_ZERO32(d)
Definition: intreadwrite.h:621
B
#define B
Definition: huffyuv.h:42
ff_progress_frame_await
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_progress_frame_await() 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_progress_frame_report() has been called on them. This includes draw_edges(). Porting codecs to frame threading
hevc.h
NeighbourAvailable::cand_up_right_sap
int cand_up_right_sap
Definition: hevcdec.h:315
compare_mv_ref_idx
static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B)
Definition: mvs.c:99
av_clip_int16
#define av_clip_int16
Definition: common.h:115
av_clip_intp2
#define av_clip_intp2
Definition: common.h:121
mv_mp_mode_mx_lt
static int mv_mp_mode_mx_lt(const HEVCContext *s, const HEVCSPS *sps, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx)
Definition: mvs.c:551
B2
@ B2
Definition: mvs.c:529
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
abs
#define abs(x)
Definition: cuda_runtime.h:35
PART_Nx2N
@ PART_Nx2N
Definition: hevcdec.h:93
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:299
PF_BI
@ PF_BI
Definition: hevcdec.h:117
PART_nLx2N
@ PART_nLx2N
Definition: hevcdec.h:97
PRED_BLOCK_AVAILABLE
#define PRED_BLOCK_AVAILABLE(v)
Definition: mvs.c:278
HEVCLocalContext::ctb_left_flag
uint8_t ctb_left_flag
Definition: hevcdec.h:420
A1
@ A1
Definition: mvs.c:525
hevcdec.h
PART_2NxnD
@ PART_2NxnD
Definition: hevcdec.h:96
MvField
Definition: hevcdec.h:303
PF_L1
@ PF_L1
Definition: hevcdec.h:116
height
#define height
A0
@ A0
Definition: mvs.c:524
N
#define N
Definition: af_mcompand.c:54
av_zero_extend
#define av_zero_extend
Definition: common.h:151
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:306
AVAILABLE
#define AVAILABLE(cand, v)
Definition: mvs.c:275
ff_hevc_set_neighbour_available
void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH, int log2_ctb_size)
Definition: mvs.c:43
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1594
PART_nRx2N
@ PART_nRx2N
Definition: hevcdec.h:98
mv_scale
static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb)
Definition: mvs.c:116
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
HEVCFrame
Definition: hevcdec.h:357
NeighbourAvailable::cand_up_left
int cand_up_left
Definition: hevcdec.h:313
MIN_TB_ADDR_ZS
#define MIN_TB_ADDR_ZS(x, y)
RefPicList::list
int list[HEVC_MAX_REFS]
Definition: hevcdec.h:192
TAB_MVF
#define TAB_MVF(x, y)
Definition: mvs.c:204
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
PF_L0
@ PF_L0
Definition: hevcdec.h:115
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: mvs.c:517
MP_MX
#define MP_MX(v, pred, mx)
Definition: mvs.c:577
AV_COPY32
#define AV_COPY32(d, s)
Definition: intreadwrite.h:593
B0
@ B0
Definition: mvs.c:527
AV_RN32A
#define AV_RN32A(p)
Definition: intreadwrite.h:520
temporal_luma_motion_vector
static int temporal_luma_motion_vector(const HEVCContext *s, const HEVCSPS *sps, int x0, int y0, int nPbW, int nPbH, int refIdxLx, Mv *mvLXCol, int X)
Definition: mvs.c:219
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
HEVCContext
Definition: hevcdec.h:450
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
pps
uint64_t pps
Definition: dovi_rpuenc.c:35
CodingUnit::y
int y
Definition: hevcdec.h:287
COMPARE_MV_REFIDX
#define COMPARE_MV_REFIDX(a, b)
Definition: mvs.c:281
is_diff_mer
static av_always_inline int is_diff_mer(const HEVCPPS *pps, int xN, int yN, int xP, int yP)
Definition: mvs.c:87
MvField::mv
Mv mv[2]
mvL0, vvL1
Definition: hevcdec.h:304
Mv
Definition: hevcdec.h:298
MvField::ref_idx
int8_t ref_idx[2]
refIdxL0, refIdxL1
Definition: hevcdec.h:305
HEVCSPS
Definition: ps.h:190
HEVCPPS
Definition: ps.h:309
AV_ZERO16
#define AV_ZERO16(d)
Definition: intreadwrite.h:617
CodingUnit::part_mode
enum PartMode part_mode
PartMode.
Definition: hevcdec.h:290
HEVCLocalContext::cu
CodingUnit cu
Definition: hevcdec.h:433
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
DERIVE_TEMPORAL_COLOCATED_MVS
#define DERIVE_TEMPORAL_COLOCATED_MVS
Definition: mvs.c:211
RefPicList::isLongTerm
int isLongTerm[HEVC_MAX_REFS]
Definition: hevcdec.h:193
HEVCLocalContext::end_of_tiles_y
int end_of_tiles_y
Definition: hevcdec.h:425
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: mvs.c:164
PART_2NxN
@ PART_2NxN
Definition: hevcdec.h:92
HEVC_SLICE_P
@ HEVC_SLICE_P
Definition: hevc.h:97