/src/ffmpeg/libavcodec/hevc/mvs.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
43 | | void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0, |
44 | | int nPbW, int nPbH, int log2_ctb_size) |
45 | 208M | { |
46 | 208M | int x0b = av_zero_extend(x0, log2_ctb_size); |
47 | 208M | int y0b = av_zero_extend(y0, log2_ctb_size); |
48 | | |
49 | 208M | lc->na.cand_up = (lc->ctb_up_flag || y0b); |
50 | 208M | lc->na.cand_left = (lc->ctb_left_flag || x0b); |
51 | 208M | lc->na.cand_up_left = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag; |
52 | 208M | lc->na.cand_up_right_sap = |
53 | 208M | (x0b + nPbW == 1 << log2_ctb_size) ? |
54 | 181M | lc->ctb_up_right_flag && !y0b : lc->na.cand_up; |
55 | 208M | lc->na.cand_up_right = |
56 | 208M | lc->na.cand_up_right_sap |
57 | 208M | && (x0 + nPbW) < lc->end_of_tiles_x; |
58 | 208M | lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left; |
59 | 208M | } |
60 | | |
61 | | /* |
62 | | * 6.4.1 Derivation process for z-scan order block availability |
63 | | */ |
64 | | static av_always_inline int |
65 | | z_scan_block_avail(const HEVCPPS *pps, const HEVCSPS *sps, |
66 | | int xCurr, int yCurr, int xN, int yN) |
67 | 6.66M | { |
68 | 6.66M | #define MIN_TB_ADDR_ZS(x, y) \ |
69 | 10.6M | pps->min_tb_addr_zs[(y) * (sps->tb_mask+2) + (x)] |
70 | | |
71 | 6.66M | int xCurr_ctb = xCurr >> sps->log2_ctb_size; |
72 | 6.66M | int yCurr_ctb = yCurr >> sps->log2_ctb_size; |
73 | 6.66M | int xN_ctb = xN >> sps->log2_ctb_size; |
74 | 6.66M | int yN_ctb = yN >> sps->log2_ctb_size; |
75 | 6.66M | if( yN_ctb < yCurr_ctb || xN_ctb < xCurr_ctb ) |
76 | 1.33M | return 1; |
77 | 5.33M | else { |
78 | 5.33M | int Curr = MIN_TB_ADDR_ZS((xCurr >> sps->log2_min_tb_size) & sps->tb_mask, |
79 | 5.33M | (yCurr >> sps->log2_min_tb_size) & sps->tb_mask); |
80 | 5.33M | int N = MIN_TB_ADDR_ZS((xN >> sps->log2_min_tb_size) & sps->tb_mask, |
81 | 5.33M | (yN >> sps->log2_min_tb_size) & sps->tb_mask); |
82 | 5.33M | return N <= Curr; |
83 | 5.33M | } |
84 | 6.66M | } |
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 | 17.6M | { |
89 | 17.6M | uint8_t plevel = pps->log2_parallel_merge_level; |
90 | | |
91 | 17.6M | return xN >> plevel == xP >> plevel && |
92 | 17.6M | yN >> plevel == yP >> plevel; |
93 | 17.6M | } |
94 | | |
95 | 7.38M | #define MATCH_MV(x) (AV_RN32A(&A.x) == AV_RN32A(&B.x)) |
96 | 12.9M | #define MATCH(x) (A.x == B.x) |
97 | | |
98 | | // check if the mv's and refidx are the same between A and B |
99 | | static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B) |
100 | 5.29M | { |
101 | 5.29M | int a_pf = A.pred_flag; |
102 | 5.29M | int b_pf = B.pred_flag; |
103 | 5.29M | if (a_pf == b_pf) { |
104 | 4.24M | if (a_pf == PF_BI) { |
105 | 2.72M | return MATCH(ref_idx[0]) && MATCH_MV(mv[0]) && |
106 | 2.72M | MATCH(ref_idx[1]) && MATCH_MV(mv[1]); |
107 | 2.72M | } else if (a_pf == PF_L0) { |
108 | 1.36M | return MATCH(ref_idx[0]) && MATCH_MV(mv[0]); |
109 | 1.36M | } else if (a_pf == PF_L1) { |
110 | 159k | return MATCH(ref_idx[1]) && MATCH_MV(mv[1]); |
111 | 159k | } |
112 | 4.24M | } |
113 | 1.05M | return 0; |
114 | 5.29M | } |
115 | | |
116 | | static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb) |
117 | 607k | { |
118 | 607k | int tx, scale_factor; |
119 | | |
120 | 607k | td = av_clip_int8(td); |
121 | 607k | tb = av_clip_int8(tb); |
122 | 607k | tx = (0x4000 + abs(td / 2)) / td; |
123 | 607k | scale_factor = av_clip_intp2((tb * tx + 32) >> 6, 12); |
124 | 607k | dst->x = av_clip_int16((scale_factor * src->x + 127 + |
125 | 607k | (scale_factor * src->x < 0)) >> 8); |
126 | 607k | dst->y = av_clip_int16((scale_factor * src->y + 127 + |
127 | 607k | (scale_factor * src->y < 0)) >> 8); |
128 | 607k | } |
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 | 353k | { |
135 | 353k | int cur_lt = refPicList[X].isLongTerm[refIdxLx]; |
136 | 353k | int col_lt = refPicList_col[listCol].isLongTerm[refidxCol]; |
137 | 353k | int col_poc_diff, cur_poc_diff; |
138 | | |
139 | 353k | if (cur_lt != col_lt) { |
140 | 5.43k | mvLXCol->x = 0; |
141 | 5.43k | mvLXCol->y = 0; |
142 | 5.43k | return 0; |
143 | 5.43k | } |
144 | | |
145 | 348k | col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol]; |
146 | 348k | cur_poc_diff = poc - refPicList[X].list[refIdxLx]; |
147 | | |
148 | 348k | if (cur_lt || col_poc_diff == cur_poc_diff || !col_poc_diff) { |
149 | 98.2k | mvLXCol->x = mvCol->x; |
150 | 98.2k | mvLXCol->y = mvCol->y; |
151 | 250k | } else { |
152 | 250k | mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff); |
153 | 250k | } |
154 | 348k | return 1; |
155 | 353k | } |
156 | | |
157 | | #define CHECK_MVSET(l) \ |
158 | 353k | check_mvset(mvLXCol, temp_col.mv + l, \ |
159 | 353k | colPic, s->poc, \ |
160 | 353k | refPicList, X, refIdxLx, \ |
161 | 353k | refPicList_col, L ## l, temp_col.ref_idx[l]) |
162 | | |
163 | | // derive the motion vectors section 8.5.3.1.8 |
164 | | static int derive_temporal_colocated_mvs(const HEVCContext *s, MvField temp_col, |
165 | | int refIdxLx, Mv *mvLXCol, int X, |
166 | | int colPic, const RefPicList *refPicList_col) |
167 | 4.14M | { |
168 | 4.14M | const RefPicList *refPicList = s->cur_frame->refPicList; |
169 | | |
170 | 4.14M | if (temp_col.pred_flag == PF_INTRA) |
171 | 3.78M | return 0; |
172 | | |
173 | 353k | if (!(temp_col.pred_flag & PF_L0)) |
174 | 11.5k | return CHECK_MVSET(1); |
175 | 342k | else if (temp_col.pred_flag == PF_L0) |
176 | 167k | return CHECK_MVSET(0); |
177 | 175k | else if (temp_col.pred_flag == PF_BI) { |
178 | 175k | int check_diffpicount = 0; |
179 | 175k | int i, j; |
180 | 525k | for (j = 0; j < 2; j++) { |
181 | 859k | for (i = 0; i < refPicList[j].nb_refs; i++) { |
182 | 645k | if (refPicList[j].list[i] > s->poc) { |
183 | 136k | check_diffpicount++; |
184 | 136k | break; |
185 | 136k | } |
186 | 645k | } |
187 | 350k | } |
188 | 175k | if (!check_diffpicount) { |
189 | 75.6k | if (X==0) |
190 | 45.7k | return CHECK_MVSET(0); |
191 | 29.8k | else |
192 | 29.8k | return CHECK_MVSET(1); |
193 | 99.6k | } else { |
194 | 99.6k | if (s->sh.collocated_list == L1) |
195 | 74.2k | return CHECK_MVSET(0); |
196 | 25.4k | else |
197 | 25.4k | return CHECK_MVSET(1); |
198 | 99.6k | } |
199 | 175k | } |
200 | | |
201 | 0 | return 0; |
202 | 353k | } |
203 | | |
204 | | #define TAB_MVF(x, y) \ |
205 | 85.5M | tab_mvf[(y) * min_pu_width + x] |
206 | | |
207 | | #define TAB_MVF_PU(v) \ |
208 | 57.8M | TAB_MVF(((x ## v) >> sps->log2_min_pu_size), \ |
209 | 57.8M | ((y ## v) >> sps->log2_min_pu_size)) |
210 | | |
211 | | #define DERIVE_TEMPORAL_COLOCATED_MVS \ |
212 | 4.14M | derive_temporal_colocated_mvs(s, temp_col, \ |
213 | 4.14M | refIdxLx, mvLXCol, X, colPic, \ |
214 | 4.14M | ff_hevc_get_ref_list(s, ref, x, y)) |
215 | | |
216 | | /* |
217 | | * 8.5.3.1.7 temporal luma motion vector prediction |
218 | | */ |
219 | | static int temporal_luma_motion_vector(const HEVCContext *s, const HEVCSPS *sps, |
220 | | int x0, int y0, |
221 | | int nPbW, int nPbH, int refIdxLx, |
222 | | Mv *mvLXCol, int X) |
223 | 2.47M | { |
224 | 2.47M | const MvField *tab_mvf; |
225 | 2.47M | MvField temp_col; |
226 | 2.47M | int x, y, x_pu, y_pu; |
227 | 2.47M | int min_pu_width = sps->min_pu_width; |
228 | 2.47M | int availableFlagLXCol = 0; |
229 | 2.47M | int colPic; |
230 | | |
231 | 2.47M | const HEVCFrame *ref = s->collocated_ref; |
232 | | |
233 | 2.47M | if (!ref) { |
234 | 0 | memset(mvLXCol, 0, sizeof(*mvLXCol)); |
235 | 0 | return 0; |
236 | 0 | } |
237 | | |
238 | 2.47M | tab_mvf = ref->tab_mvf; |
239 | 2.47M | colPic = ref->poc; |
240 | | |
241 | | //bottom right collocated motion vector |
242 | 2.47M | x = x0 + nPbW; |
243 | 2.47M | y = y0 + nPbH; |
244 | | |
245 | 2.47M | if (tab_mvf && |
246 | 2.47M | (y0 >> sps->log2_ctb_size) == (y >> sps->log2_ctb_size) && |
247 | 2.47M | y < sps->height && |
248 | 2.47M | x < sps->width) { |
249 | 1.89M | x &= ~15; |
250 | 1.89M | y &= ~15; |
251 | 1.89M | if (s->avctx->active_thread_type == FF_THREAD_FRAME) |
252 | 0 | ff_progress_frame_await(&ref->tf, y); |
253 | 1.89M | x_pu = x >> sps->log2_min_pu_size; |
254 | 1.89M | y_pu = y >> sps->log2_min_pu_size; |
255 | 1.89M | temp_col = TAB_MVF(x_pu, y_pu); |
256 | 1.89M | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS; |
257 | 1.89M | } |
258 | | |
259 | | // derive center collocated motion vector |
260 | 2.47M | if (tab_mvf && !availableFlagLXCol) { |
261 | 2.24M | x = x0 + (nPbW >> 1); |
262 | 2.24M | y = y0 + (nPbH >> 1); |
263 | 2.24M | x &= ~15; |
264 | 2.24M | y &= ~15; |
265 | 2.24M | if (s->avctx->active_thread_type == FF_THREAD_FRAME) |
266 | 0 | ff_progress_frame_await(&ref->tf, y); |
267 | 2.24M | x_pu = x >> sps->log2_min_pu_size; |
268 | 2.24M | y_pu = y >> sps->log2_min_pu_size; |
269 | 2.24M | temp_col = TAB_MVF(x_pu, y_pu); |
270 | 2.24M | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS; |
271 | 2.24M | } |
272 | 2.47M | return availableFlagLXCol; |
273 | 2.47M | } |
274 | | |
275 | | #define AVAILABLE(cand, v) \ |
276 | 48.9M | (cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA)) |
277 | | |
278 | | #define PRED_BLOCK_AVAILABLE(v) \ |
279 | 17.3M | z_scan_block_avail(pps, sps, x0, y0, x ## v, y ## v) |
280 | | |
281 | | #define COMPARE_MV_REFIDX(a, b) \ |
282 | 5.29M | 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 | | */ |
287 | | static void derive_spatial_merge_candidates(HEVCLocalContext *lc, const HEVCContext *s, |
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 | 11.3M | { |
296 | 11.3M | const RefPicList *refPicList = s->cur_frame->refPicList; |
297 | 11.3M | const MvField *tab_mvf = s->cur_frame->tab_mvf; |
298 | | |
299 | 11.3M | const int min_pu_width = sps->min_pu_width; |
300 | | |
301 | 11.3M | const int cand_bottom_left = lc->na.cand_bottom_left; |
302 | 11.3M | const int cand_left = lc->na.cand_left; |
303 | 11.3M | const int cand_up_left = lc->na.cand_up_left; |
304 | 11.3M | const int cand_up = lc->na.cand_up; |
305 | 11.3M | const int cand_up_right = lc->na.cand_up_right_sap; |
306 | | |
307 | 11.3M | const int xA1 = x0 - 1; |
308 | 11.3M | const int yA1 = y0 + nPbH - 1; |
309 | | |
310 | 11.3M | const int xB1 = x0 + nPbW - 1; |
311 | 11.3M | const int yB1 = y0 - 1; |
312 | | |
313 | 11.3M | const int xB0 = x0 + nPbW; |
314 | 11.3M | const int yB0 = y0 - 1; |
315 | | |
316 | 11.3M | const int xA0 = x0 - 1; |
317 | 11.3M | const int yA0 = y0 + nPbH; |
318 | | |
319 | 11.3M | const int xB2 = x0 - 1; |
320 | 11.3M | const int yB2 = y0 - 1; |
321 | | |
322 | 11.3M | const int nb_refs = (s->sh.slice_type == HEVC_SLICE_P) ? |
323 | 10.5M | s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]); |
324 | | |
325 | 11.3M | int zero_idx = 0; |
326 | | |
327 | 11.3M | int nb_merge_cand = 0; |
328 | 11.3M | int nb_orig_merge_cand = 0; |
329 | | |
330 | 11.3M | int is_available_a0; |
331 | 11.3M | int is_available_a1; |
332 | 11.3M | int is_available_b0; |
333 | 11.3M | int is_available_b1; |
334 | 11.3M | int is_available_b2; |
335 | | |
336 | | |
337 | 11.3M | if (!singleMCLFlag && part_idx == 1 && |
338 | 11.3M | (lc->cu.part_mode == PART_Nx2N || |
339 | 1.03M | lc->cu.part_mode == PART_nLx2N || |
340 | 1.03M | lc->cu.part_mode == PART_nRx2N) || |
341 | 11.3M | is_diff_mer(pps, xA1, yA1, x0, y0)) { |
342 | 822k | is_available_a1 = 0; |
343 | 10.5M | } else { |
344 | 10.5M | is_available_a1 = AVAILABLE(cand_left, A1); |
345 | 10.5M | if (is_available_a1) { |
346 | 9.97M | mergecandlist[nb_merge_cand] = TAB_MVF_PU(A1); |
347 | 9.97M | if (merge_idx == 0) |
348 | 7.30M | return; |
349 | 2.66M | nb_merge_cand++; |
350 | 2.66M | } |
351 | 10.5M | } |
352 | | |
353 | 4.07M | if (!singleMCLFlag && part_idx == 1 && |
354 | 4.07M | (lc->cu.part_mode == PART_2NxN || |
355 | 761k | lc->cu.part_mode == PART_2NxnU || |
356 | 761k | lc->cu.part_mode == PART_2NxnD) || |
357 | 4.07M | is_diff_mer(pps, xB1, yB1, x0, y0)) { |
358 | 314k | is_available_b1 = 0; |
359 | 3.76M | } else { |
360 | 3.76M | is_available_b1 = AVAILABLE(cand_up, B1); |
361 | 3.76M | if (is_available_b1 && |
362 | 3.76M | !(is_available_a1 && COMPARE_MV_REFIDX(B1, A1))) { |
363 | 2.56M | mergecandlist[nb_merge_cand] = TAB_MVF_PU(B1); |
364 | 2.56M | if (merge_idx == nb_merge_cand) |
365 | 1.87M | return; |
366 | 690k | nb_merge_cand++; |
367 | 690k | } |
368 | 3.76M | } |
369 | | |
370 | | // above right spatial merge candidate |
371 | 2.20M | is_available_b0 = AVAILABLE(cand_up_right, B0) && |
372 | 2.20M | xB0 < sps->width && |
373 | 2.20M | PRED_BLOCK_AVAILABLE(B0) && |
374 | 2.20M | !is_diff_mer(pps, xB0, yB0, x0, y0); |
375 | | |
376 | 2.20M | if (is_available_b0 && |
377 | 2.20M | !(is_available_b1 && COMPARE_MV_REFIDX(B0, B1))) { |
378 | 697k | mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0); |
379 | 697k | if (merge_idx == nb_merge_cand) |
380 | 497k | return; |
381 | 200k | nb_merge_cand++; |
382 | 200k | } |
383 | | |
384 | | // left bottom spatial merge candidate |
385 | 1.71M | is_available_a0 = AVAILABLE(cand_bottom_left, A0) && |
386 | 1.71M | yA0 < sps->height && |
387 | 1.71M | PRED_BLOCK_AVAILABLE(A0) && |
388 | 1.71M | !is_diff_mer(pps, xA0, yA0, x0, y0); |
389 | | |
390 | 1.71M | if (is_available_a0 && |
391 | 1.71M | !(is_available_a1 && COMPARE_MV_REFIDX(A0, A1))) { |
392 | 147k | mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0); |
393 | 147k | if (merge_idx == nb_merge_cand) |
394 | 91.4k | return; |
395 | 55.8k | nb_merge_cand++; |
396 | 55.8k | } |
397 | | |
398 | | // above left spatial merge candidate |
399 | 1.61M | is_available_b2 = AVAILABLE(cand_up_left, B2) && |
400 | 1.61M | !is_diff_mer(pps, xB2, yB2, x0, y0); |
401 | | |
402 | 1.61M | if (is_available_b2 && |
403 | 1.61M | !(is_available_a1 && COMPARE_MV_REFIDX(B2, A1)) && |
404 | 1.61M | !(is_available_b1 && COMPARE_MV_REFIDX(B2, B1)) && |
405 | 1.61M | nb_merge_cand != 4) { |
406 | 443k | mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2); |
407 | 443k | if (merge_idx == nb_merge_cand) |
408 | 285k | return; |
409 | 158k | nb_merge_cand++; |
410 | 158k | } |
411 | | |
412 | | // temporal motion vector candidate |
413 | 1.33M | if (s->sh.slice_temporal_mvp_enabled_flag && |
414 | 1.33M | nb_merge_cand < s->sh.max_num_merge_cand) { |
415 | 1.06M | Mv mv_l0_col = { 0 }, mv_l1_col = { 0 }; |
416 | 1.06M | int available_l0 = temporal_luma_motion_vector(s, sps, x0, y0, nPbW, nPbH, |
417 | 1.06M | 0, &mv_l0_col, 0); |
418 | 1.06M | int available_l1 = (s->sh.slice_type == HEVC_SLICE_B) ? |
419 | 981k | temporal_luma_motion_vector(s, sps, x0, y0, nPbW, nPbH, |
420 | 981k | 0, &mv_l1_col, 1) : 0; |
421 | | |
422 | 1.06M | if (available_l0 || available_l1) { |
423 | 174k | mergecandlist[nb_merge_cand].pred_flag = available_l0 + (available_l1 << 1); |
424 | 174k | AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx); |
425 | 174k | mergecandlist[nb_merge_cand].mv[0] = mv_l0_col; |
426 | 174k | mergecandlist[nb_merge_cand].mv[1] = mv_l1_col; |
427 | | |
428 | 174k | if (merge_idx == nb_merge_cand) |
429 | 122k | return; |
430 | 52.3k | nb_merge_cand++; |
431 | 52.3k | } |
432 | 1.06M | } |
433 | | |
434 | 1.21M | nb_orig_merge_cand = nb_merge_cand; |
435 | | |
436 | | // combined bi-predictive merge candidates (applies for B slices) |
437 | 1.21M | if (s->sh.slice_type == HEVC_SLICE_B && nb_orig_merge_cand > 1 && |
438 | 1.21M | nb_orig_merge_cand < s->sh.max_num_merge_cand) { |
439 | 378k | int comb_idx = 0; |
440 | | |
441 | 977k | for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand && |
442 | 977k | comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) { |
443 | 814k | int l0_cand_idx = l0_l1_cand_idx[comb_idx][0]; |
444 | 814k | int l1_cand_idx = l0_l1_cand_idx[comb_idx][1]; |
445 | 814k | MvField l0_cand = mergecandlist[l0_cand_idx]; |
446 | 814k | MvField l1_cand = mergecandlist[l1_cand_idx]; |
447 | | |
448 | 814k | if ((l0_cand.pred_flag & PF_L0) && (l1_cand.pred_flag & PF_L1) && |
449 | 814k | (refPicList[0].list[l0_cand.ref_idx[0]] != |
450 | 498k | refPicList[1].list[l1_cand.ref_idx[1]] || |
451 | 498k | AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) { |
452 | 359k | mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0]; |
453 | 359k | mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1]; |
454 | 359k | mergecandlist[nb_merge_cand].pred_flag = PF_BI; |
455 | 359k | AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]); |
456 | 359k | AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]); |
457 | 359k | if (merge_idx == nb_merge_cand) |
458 | 216k | return; |
459 | 143k | nb_merge_cand++; |
460 | 143k | } |
461 | 814k | } |
462 | 378k | } |
463 | | |
464 | | // append Zero motion vector candidates |
465 | 1.45M | while (nb_merge_cand < s->sh.max_num_merge_cand) { |
466 | 1.45M | mergecandlist[nb_merge_cand].pred_flag = PF_L0 + ((s->sh.slice_type == HEVC_SLICE_B) << 1); |
467 | 1.45M | AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0); |
468 | 1.45M | AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1); |
469 | 1.45M | mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0; |
470 | 1.45M | mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0; |
471 | | |
472 | 1.45M | if (merge_idx == nb_merge_cand) |
473 | 994k | return; |
474 | 457k | nb_merge_cand++; |
475 | 457k | zero_idx++; |
476 | 457k | } |
477 | 994k | } |
478 | | |
479 | | /* |
480 | | * 8.5.3.1.1 Derivation process of luma Mvs for merge mode |
481 | | */ |
482 | | void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, const HEVCPPS *pps, |
483 | | int x0, int y0, int nPbW, |
484 | | int nPbH, int log2_cb_size, int part_idx, |
485 | | int merge_idx, MvField *mv) |
486 | 11.3M | { |
487 | 11.3M | const HEVCSPS *const sps = pps->sps; |
488 | 11.3M | const HEVCContext *const s = lc->parent; |
489 | 11.3M | int singleMCLFlag = 0; |
490 | 11.3M | int nCS = 1 << log2_cb_size; |
491 | 11.3M | MvField mergecand_list[MRG_MAX_NUM_CANDS]; |
492 | 11.3M | int nPbW2 = nPbW; |
493 | 11.3M | int nPbH2 = nPbH; |
494 | | |
495 | 11.3M | if (pps->log2_parallel_merge_level > 2 && nCS == 8) { |
496 | 416k | singleMCLFlag = 1; |
497 | 416k | x0 = lc->cu.x; |
498 | 416k | y0 = lc->cu.y; |
499 | 416k | nPbW = nCS; |
500 | 416k | nPbH = nCS; |
501 | 416k | part_idx = 0; |
502 | 416k | } |
503 | | |
504 | 11.3M | ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH, sps->log2_ctb_size); |
505 | 11.3M | derive_spatial_merge_candidates(lc, s, pps, sps, x0, y0, nPbW, nPbH, log2_cb_size, |
506 | 11.3M | singleMCLFlag, part_idx, |
507 | 11.3M | merge_idx, mergecand_list); |
508 | | |
509 | 11.3M | if (mergecand_list[merge_idx].pred_flag == PF_BI && |
510 | 11.3M | (nPbW2 + nPbH2) == 12) { |
511 | 346k | mergecand_list[merge_idx].pred_flag = PF_L0; |
512 | 346k | } |
513 | | |
514 | 11.3M | *mv = mergecand_list[merge_idx]; |
515 | 11.3M | } |
516 | | |
517 | | static av_always_inline void dist_scale(const HEVCContext *s, Mv *mv, |
518 | | int min_pu_width, int x, int y, |
519 | | int elist, int ref_idx_curr, int ref_idx) |
520 | 494k | { |
521 | 494k | const RefPicList *refPicList = s->cur_frame->refPicList; |
522 | 494k | const MvField *tab_mvf = s->cur_frame->tab_mvf; |
523 | 494k | int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]]; |
524 | 494k | int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx]; |
525 | | |
526 | 494k | if (ref_pic_elist != ref_pic_curr) { |
527 | 357k | int poc_diff = s->poc - ref_pic_elist; |
528 | 357k | if (!poc_diff) |
529 | 313 | poc_diff = 1; |
530 | 357k | mv_scale(mv, mv, poc_diff, s->poc - ref_pic_curr); |
531 | 357k | } |
532 | 494k | } |
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 | 8.44M | { |
538 | 8.44M | const MvField *tab_mvf = s->cur_frame->tab_mvf; |
539 | 8.44M | int min_pu_width = sps->min_pu_width; |
540 | | |
541 | 8.44M | const RefPicList *refPicList = s->cur_frame->refPicList; |
542 | | |
543 | 8.44M | if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) && |
544 | 8.44M | refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) { |
545 | 5.72M | *mv = TAB_MVF(x, y).mv[pred_flag_index]; |
546 | 5.72M | return 1; |
547 | 5.72M | } |
548 | 2.71M | return 0; |
549 | 8.44M | } |
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 | 588k | { |
555 | 588k | const MvField *tab_mvf = s->cur_frame->tab_mvf; |
556 | 588k | int min_pu_width = sps->min_pu_width; |
557 | | |
558 | 588k | const RefPicList *refPicList = s->cur_frame->refPicList; |
559 | | |
560 | 588k | if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) { |
561 | 502k | int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx]; |
562 | | |
563 | 502k | int colIsLongTerm = |
564 | 502k | refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])]; |
565 | | |
566 | 502k | if (colIsLongTerm == currIsLongTerm) { |
567 | 498k | *mv = TAB_MVF(x, y).mv[pred_flag_index]; |
568 | 498k | if (!currIsLongTerm) |
569 | 494k | dist_scale(s, mv, min_pu_width, x, y, |
570 | 494k | pred_flag_index, ref_idx_curr, ref_idx); |
571 | 498k | return 1; |
572 | 498k | } |
573 | 502k | } |
574 | 90.2k | return 0; |
575 | 588k | } |
576 | | |
577 | | #define MP_MX(v, pred, mx) \ |
578 | 8.44M | mv_mp_mode_mx(s, sps, \ |
579 | 8.44M | (x ## v) >> sps->log2_min_pu_size, \ |
580 | 8.44M | (y ## v) >> sps->log2_min_pu_size, \ |
581 | 8.44M | pred, &mx, ref_idx_curr, ref_idx) |
582 | | |
583 | | #define MP_MX_LT(v, pred, mx) \ |
584 | 588k | mv_mp_mode_mx_lt(s, sps, \ |
585 | 588k | (x ## v) >> sps->log2_min_pu_size, \ |
586 | 588k | (y ## v) >> sps->log2_min_pu_size, \ |
587 | 588k | pred, &mx, ref_idx_curr, ref_idx) |
588 | | |
589 | | void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, const HEVCPPS *pps, |
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 | 3.36M | { |
595 | 3.36M | const HEVCSPS *const sps = pps->sps; |
596 | 3.36M | const HEVCContext *const s = lc->parent; |
597 | 3.36M | const MvField *const tab_mvf = s->cur_frame->tab_mvf; |
598 | 3.36M | int isScaledFlag_L0 = 0; |
599 | 3.36M | int availableFlagLXA0 = 1; |
600 | 3.36M | int availableFlagLXB0 = 1; |
601 | 3.36M | int numMVPCandLX = 0; |
602 | 3.36M | int min_pu_width = sps->min_pu_width; |
603 | | |
604 | 3.36M | int xA0, yA0; |
605 | 3.36M | int is_available_a0; |
606 | 3.36M | int xA1, yA1; |
607 | 3.36M | int is_available_a1; |
608 | 3.36M | int xB0, yB0; |
609 | 3.36M | int is_available_b0; |
610 | 3.36M | int xB1, yB1; |
611 | 3.36M | int is_available_b1; |
612 | 3.36M | int xB2, yB2; |
613 | 3.36M | int is_available_b2; |
614 | | |
615 | 3.36M | Mv mvpcand_list[2] = { { 0 } }; |
616 | 3.36M | Mv mxA; |
617 | 3.36M | Mv mxB; |
618 | 3.36M | int ref_idx_curr; |
619 | 3.36M | int ref_idx = 0; |
620 | 3.36M | int pred_flag_index_l0; |
621 | 3.36M | int pred_flag_index_l1; |
622 | | |
623 | 3.36M | const int cand_bottom_left = lc->na.cand_bottom_left; |
624 | 3.36M | const int cand_left = lc->na.cand_left; |
625 | 3.36M | const int cand_up_left = lc->na.cand_up_left; |
626 | 3.36M | const int cand_up = lc->na.cand_up; |
627 | 3.36M | const int cand_up_right = lc->na.cand_up_right_sap; |
628 | 3.36M | ref_idx_curr = LX; |
629 | 3.36M | ref_idx = mv->ref_idx[LX]; |
630 | 3.36M | pred_flag_index_l0 = LX; |
631 | 3.36M | pred_flag_index_l1 = !LX; |
632 | | |
633 | | // left bottom spatial candidate |
634 | 3.36M | xA0 = x0 - 1; |
635 | 3.36M | yA0 = y0 + nPbH; |
636 | | |
637 | 3.36M | is_available_a0 = AVAILABLE(cand_bottom_left, A0) && |
638 | 3.36M | yA0 < sps->height && |
639 | 3.36M | PRED_BLOCK_AVAILABLE(A0); |
640 | | |
641 | | //left spatial merge candidate |
642 | 3.36M | xA1 = x0 - 1; |
643 | 3.36M | yA1 = y0 + nPbH - 1; |
644 | | |
645 | 3.36M | is_available_a1 = AVAILABLE(cand_left, A1); |
646 | 3.36M | if (is_available_a0 || is_available_a1) |
647 | 3.16M | isScaledFlag_L0 = 1; |
648 | | |
649 | 3.36M | if (is_available_a0) { |
650 | 1.01M | if (MP_MX(A0, pred_flag_index_l0, mxA)) { |
651 | 841k | goto b_candidates; |
652 | 841k | } |
653 | 169k | if (MP_MX(A0, pred_flag_index_l1, mxA)) { |
654 | 52.1k | goto b_candidates; |
655 | 52.1k | } |
656 | 169k | } |
657 | | |
658 | 2.46M | if (is_available_a1) { |
659 | 2.26M | if (MP_MX(A1, pred_flag_index_l0, mxA)) { |
660 | 1.82M | goto b_candidates; |
661 | 1.82M | } |
662 | 443k | if (MP_MX(A1, pred_flag_index_l1, mxA)) { |
663 | 110k | goto b_candidates; |
664 | 110k | } |
665 | 443k | } |
666 | | |
667 | 533k | if (is_available_a0) { |
668 | 88.7k | if (MP_MX_LT(A0, pred_flag_index_l0, mxA)) { |
669 | 71.0k | goto b_candidates; |
670 | 71.0k | } |
671 | 17.6k | if (MP_MX_LT(A0, pred_flag_index_l1, mxA)) { |
672 | 17.2k | goto b_candidates; |
673 | 17.2k | } |
674 | 17.6k | } |
675 | | |
676 | 445k | if (is_available_a1) { |
677 | 247k | if (MP_MX_LT(A1, pred_flag_index_l0, mxA)) { |
678 | 191k | goto b_candidates; |
679 | 191k | } |
680 | 55.8k | if (MP_MX_LT(A1, pred_flag_index_l1, mxA)) { |
681 | 54.0k | goto b_candidates; |
682 | 54.0k | } |
683 | 55.8k | } |
684 | 200k | availableFlagLXA0 = 0; |
685 | | |
686 | 3.36M | b_candidates: |
687 | | // B candidates |
688 | | // above right spatial merge candidate |
689 | 3.36M | xB0 = x0 + nPbW; |
690 | 3.36M | yB0 = y0 - 1; |
691 | | |
692 | 3.36M | is_available_b0 = AVAILABLE(cand_up_right, B0) && |
693 | 3.36M | xB0 < sps->width && |
694 | 3.36M | PRED_BLOCK_AVAILABLE(B0); |
695 | | |
696 | | // above spatial merge candidate |
697 | 3.36M | xB1 = x0 + nPbW - 1; |
698 | 3.36M | yB1 = y0 - 1; |
699 | 3.36M | is_available_b1 = AVAILABLE(cand_up, B1); |
700 | | |
701 | | // above left spatial merge candidate |
702 | 3.36M | xB2 = x0 - 1; |
703 | 3.36M | yB2 = y0 - 1; |
704 | 3.36M | is_available_b2 = AVAILABLE(cand_up_left, B2); |
705 | | |
706 | | // above right spatial merge candidate |
707 | 3.36M | if (is_available_b0) { |
708 | 1.97M | if (MP_MX(B0, pred_flag_index_l0, mxB)) { |
709 | 1.64M | goto scalef; |
710 | 1.64M | } |
711 | 330k | if (MP_MX(B0, pred_flag_index_l1, mxB)) { |
712 | 101k | goto scalef; |
713 | 101k | } |
714 | 330k | } |
715 | | |
716 | | // above spatial merge candidate |
717 | 1.61M | if (is_available_b1) { |
718 | 1.34M | if (MP_MX(B1, pred_flag_index_l0, mxB)) { |
719 | 978k | goto scalef; |
720 | 978k | } |
721 | 366k | if (MP_MX(B1, pred_flag_index_l1, mxB)) { |
722 | 67.9k | goto scalef; |
723 | 67.9k | } |
724 | 366k | } |
725 | | |
726 | | // above left spatial merge candidate |
727 | 564k | if (is_available_b2) { |
728 | 313k | if (MP_MX(B2, pred_flag_index_l0, mxB)) { |
729 | 92.4k | goto scalef; |
730 | 92.4k | } |
731 | 220k | if (MP_MX(B2, pred_flag_index_l1, mxB)) { |
732 | 14.9k | goto scalef; |
733 | 14.9k | } |
734 | 220k | } |
735 | 457k | availableFlagLXB0 = 0; |
736 | | |
737 | 3.36M | scalef: |
738 | 3.36M | if (!isScaledFlag_L0) { |
739 | 198k | if (availableFlagLXB0) { |
740 | 148k | availableFlagLXA0 = 1; |
741 | 148k | mxA = mxB; |
742 | 148k | } |
743 | 198k | availableFlagLXB0 = 0; |
744 | | |
745 | | // XB0 and L1 |
746 | 198k | if (is_available_b0) { |
747 | 108k | availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB); |
748 | 108k | if (!availableFlagLXB0) |
749 | 9.12k | availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB); |
750 | 108k | } |
751 | | |
752 | 198k | if (is_available_b1 && !availableFlagLXB0) { |
753 | 51.1k | availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB); |
754 | 51.1k | if (!availableFlagLXB0) |
755 | 4.69k | availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB); |
756 | 51.1k | } |
757 | | |
758 | 198k | if (is_available_b2 && !availableFlagLXB0) { |
759 | 5.75k | availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB); |
760 | 5.75k | if (!availableFlagLXB0) |
761 | 454 | availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB); |
762 | 5.75k | } |
763 | 198k | } |
764 | | |
765 | 3.36M | if (availableFlagLXA0) |
766 | 3.30M | mvpcand_list[numMVPCandLX++] = mxA; |
767 | | |
768 | 3.36M | if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y)) |
769 | 1.55M | mvpcand_list[numMVPCandLX++] = mxB; |
770 | | |
771 | | //temporal motion vector prediction candidate |
772 | 3.36M | if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag && |
773 | 3.36M | mvp_lx_flag == numMVPCandLX) { |
774 | 429k | Mv mv_col; |
775 | 429k | int available_col = temporal_luma_motion_vector(s, sps, x0, y0, nPbW, |
776 | 429k | nPbH, ref_idx, |
777 | 429k | &mv_col, LX); |
778 | 429k | if (available_col) |
779 | 49.1k | mvpcand_list[numMVPCandLX++] = mv_col; |
780 | 429k | } |
781 | | |
782 | 3.36M | mv->mv[LX] = mvpcand_list[mvp_lx_flag]; |
783 | 3.36M | } |