FFmpeg
Loading...
Searching...
No Matches
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"
27
28static 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;
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 */
64static 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
87static 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
116static 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
130static 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(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)
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)
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
534static 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
551static 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
686b_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
737scalef:
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}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define N
Definition af_mcompand.c:54
#define A(x)
Definition vpx_arith.h:28
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition avcodec.h:1590
#define A1
Definition binkdsp.c:30
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
#define s(width, name)
Definition cbs_vp9.c:198
#define av_clip_intp2
Definition common.h:121
#define av_clip_int8
Definition common.h:109
#define av_clip_int16
Definition common.h:115
#define av_zero_extend
Definition common.h:151
#define abs(x)
void ff_progress_frame_await(const ProgressFrame *f, int n)
Wait for earlier decoding threads to finish reference frames.
Definition decode.c:1984
uint64_t pps
Definition dovi_rpuenc.c:36
#define X
Definition f_ebur128.c:157
#define B2
Definition faandct.c:43
#define B1
Definition faandct.c:42
#define B0
Definition faandct.c:41
#define MATCH(x)
Definition mvs.c:96
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
static av_always_inline int is_diff_mer(const HEVCPPS *pps, int xN, int yN, int xP, int yP)
Definition mvs.c:87
static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb)
Definition mvs.c:116
#define AVAILABLE(cand, v)
Definition mvs.c:275
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
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
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
#define COMPARE_MV_REFIDX(a, b)
Definition mvs.c:281
#define MIN_TB_ADDR_ZS(x, y)
void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH, int log2_ctb_size)
Definition mvs.c:43
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
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
static const uint8_t l0_l1_cand_idx[12][2]
Definition mvs.c:28
#define DERIVE_TEMPORAL_COLOCATED_MVS
Definition mvs.c:211
#define MATCH_MV(x)
Definition mvs.c:95
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
#define PRED_BLOCK_AVAILABLE(v)
Definition mvs.c:278
static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B)
Definition mvs.c:99
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
#define CHECK_MVSET(l)
Definition mvs.c:157
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
#define TAB_MVF(x, y)
Definition mvs.c:204
#define MP_MX(v, pred, mx)
Definition mvs.c:577
#define MP_MX_LT(v, pred, mx)
Definition mvs.c:583
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
#define TAB_MVF_PU(v)
Definition mvs.c:207
#define L1
Definition hevcdec.h:57
@ PART_Nx2N
Definition hevcdec.h:97
@ PART_2NxnD
Definition hevcdec.h:100
@ PART_nLx2N
Definition hevcdec.h:101
@ PART_2NxN
Definition hevcdec.h:96
@ PART_2NxnU
Definition hevcdec.h:99
@ PART_nRx2N
Definition hevcdec.h:102
@ PF_L1
Definition hevcdec.h:120
@ PF_BI
Definition hevcdec.h:121
@ PF_L0
Definition hevcdec.h:119
@ PF_INTRA
Definition hevcdec.h:118
#define MRG_MAX_NUM_CANDS
Definition hevcdec.h:54
#define B
Definition huffyuv.h:42
#define AV_ZERO32(d)
#define AV_ZERO16(d)
#define AV_RN32A(p)
#define AV_COPY32(d, s)
static const int8_t mv[256][2]
Definition 4xm.c:81
@ HEVC_SLICE_P
Definition hevc.h:97
@ HEVC_SLICE_B
Definition hevc.h:96
#define av_always_inline
Definition attributes.h:72
#define FFMIN(a, b)
Definition macros.h:49
enum PartMode part_mode
PartMode.
Definition hevcdec.h:295
uint8_t ctb_left_flag
Definition hevcdec.h:422
uint8_t ctb_up_left_flag
Definition hevcdec.h:425
const struct HEVCContext * parent
Definition hevcdec.h:399
NeighbourAvailable na
Definition hevcdec.h:437
uint8_t ctb_up_flag
Definition hevcdec.h:423
CodingUnit cu
Definition hevcdec.h:435
uint8_t ctb_up_right_flag
Definition hevcdec.h:424
Definition ps.h:371
Definition ps.h:252
int8_t ref_idx[2]
refIdxL0, refIdxL1
Definition hevcdec.h:310
int8_t pred_flag
Definition hevcdec.h:311
Mv mv[2]
mvL0, vvL1
Definition hevcdec.h:309
Definition hevcdec.h:303
int16_t x
horizontal component of motion vector
Definition hevcdec.h:304
int16_t y
vertical component of motion vector
Definition hevcdec.h:305
int isLongTerm[HEVC_MAX_REFS]
Definition hevcdec.h:197
int nb_refs
Definition hevcdec.h:198
int list[HEVC_MAX_REFS]
Definition hevcdec.h:196
#define src
Definition vp8dsp.c:248
static int ref[MAX_W *MAX_W]
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
@ A0
Definition mvs.c:528