Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6148 | serge | 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 | |||
26 | static const uint8_t l0_l1_cand_idx[12][2] = { |
||
27 | { 0, 1, }, |
||
28 | { 1, 0, }, |
||
29 | { 0, 2, }, |
||
30 | { 2, 0, }, |
||
31 | { 1, 2, }, |
||
32 | { 2, 1, }, |
||
33 | { 0, 3, }, |
||
34 | { 3, 0, }, |
||
35 | { 1, 3, }, |
||
36 | { 3, 1, }, |
||
37 | { 2, 3, }, |
||
38 | { 3, 2, }, |
||
39 | }; |
||
40 | |||
41 | void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, int nPbW, int nPbH) |
||
42 | { |
||
43 | HEVCLocalContext *lc = s->HEVClc; |
||
44 | int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1); |
||
45 | int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1); |
||
46 | |||
47 | lc->na.cand_up = (lc->ctb_up_flag || y0b); |
||
48 | lc->na.cand_left = (lc->ctb_left_flag || x0b); |
||
49 | lc->na.cand_up_left = (!x0b && !y0b) ? lc->ctb_up_left_flag : lc->na.cand_left && lc->na.cand_up; |
||
50 | lc->na.cand_up_right_sap = |
||
51 | ((x0b + nPbW) == (1 << s->sps->log2_ctb_size)) ? |
||
52 | lc->ctb_up_right_flag && !y0b : lc->na.cand_up; |
||
53 | lc->na.cand_up_right = |
||
54 | ((x0b + nPbW) == (1 << s->sps->log2_ctb_size) ? |
||
55 | lc->ctb_up_right_flag && !y0b : lc->na.cand_up ) |
||
56 | && (x0 + nPbW) < lc->end_of_tiles_x; |
||
57 | lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left; |
||
58 | } |
||
59 | |||
60 | /* |
||
61 | * 6.4.1 Derivation process for z-scan order block availability |
||
62 | */ |
||
63 | static int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr, |
||
64 | int xN, int yN) |
||
65 | { |
||
66 | #define MIN_TB_ADDR_ZS(x, y) \ |
||
67 | s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)] |
||
68 | int Curr = MIN_TB_ADDR_ZS(xCurr >> s->sps->log2_min_tb_size, |
||
69 | yCurr >> s->sps->log2_min_tb_size); |
||
70 | int N; |
||
71 | |||
72 | if ((xN < 0) || (yN < 0) || |
||
73 | (xN >= s->sps->width) || |
||
74 | (yN >= s->sps->height)) |
||
75 | return 0; |
||
76 | |||
77 | N = MIN_TB_ADDR_ZS(xN >> s->sps->log2_min_tb_size, |
||
78 | yN >> s->sps->log2_min_tb_size); |
||
79 | |||
80 | return N <= Curr; |
||
81 | } |
||
82 | |||
83 | |||
84 | static int same_prediction_block(HEVCLocalContext *lc, int log2_cb_size, |
||
85 | int x0, int y0, int nPbW, int nPbH, |
||
86 | int xA1, int yA1, int partIdx) |
||
87 | { |
||
88 | return !(nPbW << 1 == 1 << log2_cb_size && |
||
89 | nPbH << 1 == 1 << log2_cb_size && partIdx == 1 && |
||
90 | lc->cu.x + nPbW > xA1 && |
||
91 | lc->cu.y + nPbH <= yA1); |
||
92 | } |
||
93 | |||
94 | /* |
||
95 | * 6.4.2 Derivation process for prediction block availability |
||
96 | */ |
||
97 | static int check_prediction_block_available(HEVCContext *s, int log2_cb_size, |
||
98 | int x0, int y0, int nPbW, int nPbH, |
||
99 | int xA1, int yA1, int partIdx) |
||
100 | { |
||
101 | HEVCLocalContext *lc = s->HEVClc; |
||
102 | |||
103 | if (lc->cu.x < xA1 && lc->cu.y < yA1 && |
||
104 | (lc->cu.x + (1 << log2_cb_size)) > xA1 && |
||
105 | (lc->cu.y + (1 << log2_cb_size)) > yA1) |
||
106 | return same_prediction_block(lc, log2_cb_size, x0, y0, |
||
107 | nPbW, nPbH, xA1, yA1, partIdx); |
||
108 | else |
||
109 | return z_scan_block_avail(s, x0, y0, xA1, yA1); |
||
110 | } |
||
111 | |||
112 | //check if the two luma locations belong to the same mostion estimation region |
||
113 | static int isDiffMER(HEVCContext *s, int xN, int yN, int xP, int yP) |
||
114 | { |
||
115 | uint8_t plevel = s->pps->log2_parallel_merge_level; |
||
116 | |||
117 | return xN >> plevel == xP >> plevel && |
||
118 | yN >> plevel == yP >> plevel; |
||
119 | } |
||
120 | |||
121 | #define MATCH(x) (A.x == B.x) |
||
122 | |||
123 | // check if the mv's and refidx are the same between A and B |
||
124 | static int compareMVrefidx(struct MvField A, struct MvField B) |
||
125 | { |
||
126 | if (A.pred_flag[0] && A.pred_flag[1] && B.pred_flag[0] && B.pred_flag[1]) |
||
127 | return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y) && |
||
128 | MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y); |
||
129 | |||
130 | if (A.pred_flag[0] && !A.pred_flag[1] && B.pred_flag[0] && !B.pred_flag[1]) |
||
131 | return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y); |
||
132 | |||
133 | if (!A.pred_flag[0] && A.pred_flag[1] && !B.pred_flag[0] && B.pred_flag[1]) |
||
134 | return MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y); |
||
135 | |||
136 | return 0; |
||
137 | } |
||
138 | |||
139 | static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb) |
||
140 | { |
||
141 | int tx, scale_factor; |
||
142 | |||
143 | td = av_clip_int8_c(td); |
||
144 | tb = av_clip_int8_c(tb); |
||
145 | tx = (0x4000 + abs(td / 2)) / td; |
||
146 | scale_factor = av_clip_c((tb * tx + 32) >> 6, -4096, 4095); |
||
147 | dst->x = av_clip_int16_c((scale_factor * src->x + 127 + |
||
148 | (scale_factor * src->x < 0)) >> 8); |
||
149 | dst->y = av_clip_int16_c((scale_factor * src->y + 127 + |
||
150 | (scale_factor * src->y < 0)) >> 8); |
||
151 | } |
||
152 | |||
153 | static int check_mvset(Mv *mvLXCol, Mv *mvCol, |
||
154 | int colPic, int poc, |
||
155 | RefPicList *refPicList, int X, int refIdxLx, |
||
156 | RefPicList *refPicList_col, int listCol, int refidxCol) |
||
157 | { |
||
158 | int cur_lt = refPicList[X].isLongTerm[refIdxLx]; |
||
159 | int col_lt = refPicList_col[listCol].isLongTerm[refidxCol]; |
||
160 | int col_poc_diff, cur_poc_diff; |
||
161 | |||
162 | if (cur_lt != col_lt) { |
||
163 | mvLXCol->x = 0; |
||
164 | mvLXCol->y = 0; |
||
165 | return 0; |
||
166 | } |
||
167 | |||
168 | col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol]; |
||
169 | cur_poc_diff = poc - refPicList[X].list[refIdxLx]; |
||
170 | |||
171 | if (!col_poc_diff) |
||
172 | col_poc_diff = 1; // error resilience |
||
173 | |||
174 | if (cur_lt || col_poc_diff == cur_poc_diff) { |
||
175 | mvLXCol->x = mvCol->x; |
||
176 | mvLXCol->y = mvCol->y; |
||
177 | } else { |
||
178 | mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff); |
||
179 | } |
||
180 | return 1; |
||
181 | } |
||
182 | |||
183 | #define CHECK_MVSET(l) \ |
||
184 | check_mvset(mvLXCol, temp_col.mv + l, \ |
||
185 | colPic, s->poc, \ |
||
186 | refPicList, X, refIdxLx, \ |
||
187 | refPicList_col, L##l, temp_col.ref_idx[l]) |
||
188 | |||
189 | // derive the motion vectors section 8.5.3.1.8 |
||
190 | static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col, |
||
191 | int refIdxLx, Mv* mvLXCol, int X, |
||
192 | int colPic, RefPicList* refPicList_col) |
||
193 | { |
||
194 | RefPicList *refPicList = s->ref->refPicList; |
||
195 | |||
196 | if (temp_col.is_intra) { |
||
197 | mvLXCol->x = 0; |
||
198 | mvLXCol->y = 0; |
||
199 | return 0; |
||
200 | } |
||
201 | |||
202 | if (temp_col.pred_flag[0] == 0) |
||
203 | return CHECK_MVSET(1); |
||
204 | else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 0) |
||
205 | return CHECK_MVSET(0); |
||
206 | else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 1) { |
||
207 | int check_diffpicount = 0; |
||
208 | int i = 0; |
||
209 | for (i = 0; i < refPicList[0].nb_refs; i++) { |
||
210 | if (refPicList[0].list[i] > s->poc) |
||
211 | check_diffpicount++; |
||
212 | } |
||
213 | for (i = 0; i < refPicList[1].nb_refs; i++) { |
||
214 | if (refPicList[1].list[i] > s->poc) |
||
215 | check_diffpicount++; |
||
216 | } |
||
217 | if (check_diffpicount == 0 && X == 0) |
||
218 | return CHECK_MVSET(0); |
||
219 | else if (check_diffpicount == 0 && X == 1) |
||
220 | return CHECK_MVSET(1); |
||
221 | else { |
||
222 | if (s->sh.collocated_list == L1) |
||
223 | return CHECK_MVSET(0); |
||
224 | else |
||
225 | return CHECK_MVSET(1); |
||
226 | } |
||
227 | } |
||
228 | |||
229 | return 0; |
||
230 | } |
||
231 | |||
232 | #define TAB_MVF(x, y) \ |
||
233 | tab_mvf[(y) * min_pu_width + x] |
||
234 | |||
235 | #define TAB_MVF_PU(v) \ |
||
236 | TAB_MVF(x##v##_pu, y##v##_pu) |
||
237 | |||
238 | #define DERIVE_TEMPORAL_COLOCATED_MVS \ |
||
239 | derive_temporal_colocated_mvs(s, temp_col, \ |
||
240 | refIdxLx, mvLXCol, X, colPic, \ |
||
241 | ff_hevc_get_ref_list(s, ref, x, y)) |
||
242 | |||
243 | /* |
||
244 | * 8.5.3.1.7 temporal luma motion vector prediction |
||
245 | */ |
||
246 | static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0, |
||
247 | int nPbW, int nPbH, int refIdxLx, |
||
248 | Mv* mvLXCol, int X) |
||
249 | { |
||
250 | MvField *tab_mvf; |
||
251 | MvField temp_col; |
||
252 | int x, y; |
||
253 | int x_pu, y_pu; |
||
254 | int min_pu_width = s->sps->min_pu_width; |
||
255 | int availableFlagLXCol = 0; |
||
256 | int colPic; |
||
257 | |||
258 | HEVCFrame *ref = s->ref->collocated_ref; |
||
259 | |||
260 | if (!ref) |
||
261 | return 0; |
||
262 | |||
263 | tab_mvf = ref->tab_mvf; |
||
264 | colPic = ref->poc; |
||
265 | |||
266 | //bottom right collocated motion vector |
||
267 | x = x0 + nPbW; |
||
268 | y = y0 + nPbH; |
||
269 | |||
270 | if (s->threads_type == FF_THREAD_FRAME ) |
||
271 | ff_thread_await_progress(&ref->tf, y, 0); |
||
272 | if (tab_mvf && |
||
273 | (y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) && |
||
274 | y < s->sps->height && |
||
275 | x < s->sps->width) { |
||
276 | x = ((x >> 4) << 4); |
||
277 | y = ((y >> 4) << 4); |
||
278 | x_pu = x >> s->sps->log2_min_pu_size; |
||
279 | y_pu = y >> s->sps->log2_min_pu_size; |
||
280 | temp_col = TAB_MVF(x_pu, y_pu); |
||
281 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS; |
||
282 | } |
||
283 | |||
284 | // derive center collocated motion vector |
||
285 | if (tab_mvf && !availableFlagLXCol) { |
||
286 | x = x0 + (nPbW >> 1); |
||
287 | y = y0 + (nPbH >> 1); |
||
288 | x = ((x >> 4) << 4); |
||
289 | y = ((y >> 4) << 4); |
||
290 | x_pu = x >> s->sps->log2_min_pu_size; |
||
291 | y_pu = y >> s->sps->log2_min_pu_size; |
||
292 | temp_col = TAB_MVF(x_pu, y_pu); |
||
293 | availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS; |
||
294 | } |
||
295 | return availableFlagLXCol; |
||
296 | } |
||
297 | |||
298 | #define AVAILABLE(cand, v) \ |
||
299 | (cand && !TAB_MVF_PU(v).is_intra) |
||
300 | |||
301 | #define PRED_BLOCK_AVAILABLE(v) \ |
||
302 | check_prediction_block_available(s, log2_cb_size, \ |
||
303 | x0, y0, nPbW, nPbH, \ |
||
304 | x##v, y##v, part_idx) |
||
305 | |||
306 | #define COMPARE_MV_REFIDX(a, b) \ |
||
307 | compareMVrefidx(TAB_MVF_PU(a), TAB_MVF_PU(b)) |
||
308 | |||
309 | /* |
||
310 | * 8.5.3.1.2 Derivation process for spatial merging candidates |
||
311 | */ |
||
312 | static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, |
||
313 | int nPbW, int nPbH, int log2_cb_size, |
||
314 | int singleMCLFlag, int part_idx, |
||
315 | struct MvField mergecandlist[]) |
||
316 | { |
||
317 | HEVCLocalContext *lc = s->HEVClc; |
||
318 | RefPicList *refPicList = s->ref->refPicList; |
||
319 | MvField *tab_mvf = s->ref->tab_mvf; |
||
320 | |||
321 | const int min_pu_width = s->sps->min_pu_width; |
||
322 | |||
323 | const int cand_bottom_left = lc->na.cand_bottom_left; |
||
324 | const int cand_left = lc->na.cand_left; |
||
325 | const int cand_up_left = lc->na.cand_up_left; |
||
326 | const int cand_up = lc->na.cand_up; |
||
327 | const int cand_up_right = lc->na.cand_up_right_sap; |
||
328 | |||
329 | const int xA1 = x0 - 1; |
||
330 | const int yA1 = y0 + nPbH - 1; |
||
331 | const int xA1_pu = xA1 >> s->sps->log2_min_pu_size; |
||
332 | const int yA1_pu = yA1 >> s->sps->log2_min_pu_size; |
||
333 | |||
334 | const int xB1 = x0 + nPbW - 1; |
||
335 | const int yB1 = y0 - 1; |
||
336 | const int xB1_pu = xB1 >> s->sps->log2_min_pu_size; |
||
337 | const int yB1_pu = yB1 >> s->sps->log2_min_pu_size; |
||
338 | |||
339 | const int xB0 = x0 + nPbW; |
||
340 | const int yB0 = y0 - 1; |
||
341 | const int xB0_pu = xB0 >> s->sps->log2_min_pu_size; |
||
342 | const int yB0_pu = yB0 >> s->sps->log2_min_pu_size; |
||
343 | |||
344 | const int xA0 = x0 - 1; |
||
345 | const int yA0 = y0 + nPbH; |
||
346 | const int xA0_pu = xA0 >> s->sps->log2_min_pu_size; |
||
347 | const int yA0_pu = yA0 >> s->sps->log2_min_pu_size; |
||
348 | |||
349 | const int xB2 = x0 - 1; |
||
350 | const int yB2 = y0 - 1; |
||
351 | const int xB2_pu = xB2 >> s->sps->log2_min_pu_size; |
||
352 | const int yB2_pu = yB2 >> s->sps->log2_min_pu_size; |
||
353 | |||
354 | const int nb_refs = (s->sh.slice_type == P_SLICE) ? |
||
355 | s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]); |
||
356 | int check_MER = 1; |
||
357 | int check_MER_1 = 1; |
||
358 | |||
359 | int zero_idx = 0; |
||
360 | |||
361 | int nb_merge_cand = 0; |
||
362 | int nb_orig_merge_cand = 0; |
||
363 | |||
364 | int is_available_a0; |
||
365 | int is_available_a1; |
||
366 | int is_available_b0; |
||
367 | int is_available_b1; |
||
368 | int is_available_b2; |
||
369 | int check_B0; |
||
370 | int check_A0; |
||
371 | |||
372 | //first left spatial merge candidate |
||
373 | is_available_a1 = AVAILABLE(cand_left, A1); |
||
374 | |||
375 | if (!singleMCLFlag && part_idx == 1 && |
||
376 | (lc->cu.part_mode == PART_Nx2N || |
||
377 | lc->cu.part_mode == PART_nLx2N || |
||
378 | lc->cu.part_mode == PART_nRx2N) || |
||
379 | isDiffMER(s, xA1, yA1, x0, y0)) { |
||
380 | is_available_a1 = 0; |
||
381 | } |
||
382 | |||
383 | if (is_available_a1) |
||
384 | mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A1); |
||
385 | |||
386 | // above spatial merge candidate |
||
387 | is_available_b1 = AVAILABLE(cand_up, B1); |
||
388 | |||
389 | if (!singleMCLFlag && part_idx == 1 && |
||
390 | (lc->cu.part_mode == PART_2NxN || |
||
391 | lc->cu.part_mode == PART_2NxnU || |
||
392 | lc->cu.part_mode == PART_2NxnD) || |
||
393 | isDiffMER(s, xB1, yB1, x0, y0)) { |
||
394 | is_available_b1 = 0; |
||
395 | } |
||
396 | |||
397 | if (is_available_a1 && is_available_b1) |
||
398 | check_MER = !COMPARE_MV_REFIDX(B1, A1); |
||
399 | |||
400 | if (is_available_b1 && check_MER) |
||
401 | mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1); |
||
402 | |||
403 | // above right spatial merge candidate |
||
404 | check_MER = 1; |
||
405 | check_B0 = PRED_BLOCK_AVAILABLE(B0); |
||
406 | |||
407 | is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0); |
||
408 | |||
409 | if (isDiffMER(s, xB0, yB0, x0, y0)) |
||
410 | is_available_b0 = 0; |
||
411 | |||
412 | if (is_available_b1 && is_available_b0) |
||
413 | check_MER = !COMPARE_MV_REFIDX(B0, B1); |
||
414 | |||
415 | if (is_available_b0 && check_MER) |
||
416 | mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B0); |
||
417 | |||
418 | // left bottom spatial merge candidate |
||
419 | check_MER = 1; |
||
420 | check_A0 = PRED_BLOCK_AVAILABLE(A0); |
||
421 | |||
422 | is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0); |
||
423 | |||
424 | if (isDiffMER(s, xA0, yA0, x0, y0)) |
||
425 | is_available_a0 = 0; |
||
426 | |||
427 | if (is_available_a1 && is_available_a0) |
||
428 | check_MER = !COMPARE_MV_REFIDX(A0, A1); |
||
429 | |||
430 | if (is_available_a0 && check_MER) |
||
431 | mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A0); |
||
432 | |||
433 | // above left spatial merge candidate |
||
434 | check_MER = 1; |
||
435 | |||
436 | is_available_b2 = AVAILABLE(cand_up_left, B2); |
||
437 | |||
438 | if (isDiffMER(s, xB2, yB2, x0, y0)) |
||
439 | is_available_b2 = 0; |
||
440 | |||
441 | if (is_available_a1 && is_available_b2) |
||
442 | check_MER = !COMPARE_MV_REFIDX(B2, A1); |
||
443 | |||
444 | if (is_available_b1 && is_available_b2) |
||
445 | check_MER_1 = !COMPARE_MV_REFIDX(B2, B1); |
||
446 | |||
447 | if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4) |
||
448 | mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B2); |
||
449 | |||
450 | // temporal motion vector candidate |
||
451 | if (s->sh.slice_temporal_mvp_enabled_flag && |
||
452 | nb_merge_cand < s->sh.max_num_merge_cand) { |
||
453 | Mv mv_l0_col, mv_l1_col; |
||
454 | int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH, |
||
455 | 0, &mv_l0_col, 0); |
||
456 | int available_l1 = (s->sh.slice_type == B_SLICE) ? |
||
457 | temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH, |
||
458 | 0, &mv_l1_col, 1) : 0; |
||
459 | |||
460 | if (available_l0 || available_l1) { |
||
461 | mergecandlist[nb_merge_cand].is_intra = 0; |
||
462 | mergecandlist[nb_merge_cand].pred_flag[0] = available_l0; |
||
463 | mergecandlist[nb_merge_cand].pred_flag[1] = available_l1; |
||
464 | if (available_l0) { |
||
465 | mergecandlist[nb_merge_cand].mv[0] = mv_l0_col; |
||
466 | mergecandlist[nb_merge_cand].ref_idx[0] = 0; |
||
467 | } |
||
468 | if (available_l1) { |
||
469 | mergecandlist[nb_merge_cand].mv[1] = mv_l1_col; |
||
470 | mergecandlist[nb_merge_cand].ref_idx[1] = 0; |
||
471 | } |
||
472 | nb_merge_cand++; |
||
473 | } |
||
474 | } |
||
475 | |||
476 | nb_orig_merge_cand = nb_merge_cand; |
||
477 | |||
478 | // combined bi-predictive merge candidates (applies for B slices) |
||
479 | if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 && |
||
480 | nb_orig_merge_cand < s->sh.max_num_merge_cand) { |
||
481 | int comb_idx = 0; |
||
482 | |||
483 | for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand && |
||
484 | comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) { |
||
485 | int l0_cand_idx = l0_l1_cand_idx[comb_idx][0]; |
||
486 | int l1_cand_idx = l0_l1_cand_idx[comb_idx][1]; |
||
487 | MvField l0_cand = mergecandlist[l0_cand_idx]; |
||
488 | MvField l1_cand = mergecandlist[l1_cand_idx]; |
||
489 | |||
490 | if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] && |
||
491 | (refPicList[0].list[l0_cand.ref_idx[0]] != |
||
492 | refPicList[1].list[l1_cand.ref_idx[1]] || |
||
493 | l0_cand.mv[0].x != l1_cand.mv[1].x || |
||
494 | l0_cand.mv[0].y != l1_cand.mv[1].y)) { |
||
495 | mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0]; |
||
496 | mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1]; |
||
497 | mergecandlist[nb_merge_cand].pred_flag[0] = 1; |
||
498 | mergecandlist[nb_merge_cand].pred_flag[1] = 1; |
||
499 | mergecandlist[nb_merge_cand].mv[0].x = l0_cand.mv[0].x; |
||
500 | mergecandlist[nb_merge_cand].mv[0].y = l0_cand.mv[0].y; |
||
501 | mergecandlist[nb_merge_cand].mv[1].x = l1_cand.mv[1].x; |
||
502 | mergecandlist[nb_merge_cand].mv[1].y = l1_cand.mv[1].y; |
||
503 | mergecandlist[nb_merge_cand].is_intra = 0; |
||
504 | nb_merge_cand++; |
||
505 | } |
||
506 | } |
||
507 | } |
||
508 | |||
509 | // append Zero motion vector candidates |
||
510 | while (nb_merge_cand < s->sh.max_num_merge_cand) { |
||
511 | mergecandlist[nb_merge_cand].pred_flag[0] = 1; |
||
512 | mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE; |
||
513 | mergecandlist[nb_merge_cand].mv[0].x = 0; |
||
514 | mergecandlist[nb_merge_cand].mv[0].y = 0; |
||
515 | mergecandlist[nb_merge_cand].mv[1].x = 0; |
||
516 | mergecandlist[nb_merge_cand].mv[1].y = 0; |
||
517 | mergecandlist[nb_merge_cand].is_intra = 0; |
||
518 | mergecandlist[nb_merge_cand].ref_idx[0] = (zero_idx < nb_refs) ? zero_idx : 0; |
||
519 | mergecandlist[nb_merge_cand].ref_idx[1] = (zero_idx < nb_refs) ? zero_idx : 0; |
||
520 | |||
521 | nb_merge_cand++; |
||
522 | zero_idx++; |
||
523 | } |
||
524 | } |
||
525 | |||
526 | /* |
||
527 | * 8.5.3.1.1 Derivation process of luma Mvs for merge mode |
||
528 | */ |
||
529 | void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, |
||
530 | int nPbH, int log2_cb_size, int part_idx, |
||
531 | int merge_idx, MvField *mv) |
||
532 | { |
||
533 | int singleMCLFlag = 0; |
||
534 | int nCS = 1 << log2_cb_size; |
||
535 | struct MvField mergecand_list[MRG_MAX_NUM_CANDS] = { { { { 0 } } } }; |
||
536 | int nPbW2 = nPbW; |
||
537 | int nPbH2 = nPbH; |
||
538 | HEVCLocalContext *lc = s->HEVClc; |
||
539 | |||
540 | if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) { |
||
541 | singleMCLFlag = 1; |
||
542 | x0 = lc->cu.x; |
||
543 | y0 = lc->cu.y; |
||
544 | nPbW = nCS; |
||
545 | nPbH = nCS; |
||
546 | part_idx = 0; |
||
547 | } |
||
548 | |||
549 | ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH); |
||
550 | derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size, |
||
551 | singleMCLFlag, part_idx, mergecand_list); |
||
552 | |||
553 | if (mergecand_list[merge_idx].pred_flag[0] == 1 && |
||
554 | mergecand_list[merge_idx].pred_flag[1] == 1 && |
||
555 | (nPbW2 + nPbH2) == 12) { |
||
556 | mergecand_list[merge_idx].ref_idx[1] = -1; |
||
557 | mergecand_list[merge_idx].pred_flag[1] = 0; |
||
558 | } |
||
559 | |||
560 | *mv = mergecand_list[merge_idx]; |
||
561 | } |
||
562 | |||
563 | static av_always_inline void dist_scale(HEVCContext *s, Mv * mv, |
||
564 | int min_pu_width, int x, int y, |
||
565 | int elist, int ref_idx_curr, int ref_idx) |
||
566 | { |
||
567 | RefPicList *refPicList = s->ref->refPicList; |
||
568 | MvField *tab_mvf = s->ref->tab_mvf; |
||
569 | int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]]; |
||
570 | int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx]; |
||
571 | |||
572 | if (ref_pic_elist != ref_pic_curr) |
||
573 | mv_scale(mv, mv, s->poc - ref_pic_elist, s->poc - ref_pic_curr); |
||
574 | } |
||
575 | |||
576 | static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index, |
||
577 | Mv *mv, int ref_idx_curr, int ref_idx) |
||
578 | { |
||
579 | MvField *tab_mvf = s->ref->tab_mvf; |
||
580 | int min_pu_width = s->sps->min_pu_width; |
||
581 | |||
582 | RefPicList *refPicList = s->ref->refPicList; |
||
583 | |||
584 | if (TAB_MVF(x, y).pred_flag[pred_flag_index] == 1 && |
||
585 | refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) { |
||
586 | *mv = TAB_MVF(x, y).mv[pred_flag_index]; |
||
587 | return 1; |
||
588 | } |
||
589 | return 0; |
||
590 | } |
||
591 | |||
592 | |||
593 | static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index, |
||
594 | Mv *mv, int ref_idx_curr, int ref_idx) |
||
595 | { |
||
596 | MvField *tab_mvf = s->ref->tab_mvf; |
||
597 | int min_pu_width = s->sps->min_pu_width; |
||
598 | |||
599 | RefPicList *refPicList = s->ref->refPicList; |
||
600 | int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx]; |
||
601 | |||
602 | int colIsLongTerm = |
||
603 | refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])]; |
||
604 | |||
605 | if (TAB_MVF(x, y).pred_flag[pred_flag_index] && colIsLongTerm == currIsLongTerm) { |
||
606 | *mv = TAB_MVF(x, y).mv[pred_flag_index]; |
||
607 | if (!currIsLongTerm) |
||
608 | dist_scale(s, mv, min_pu_width, x, y, pred_flag_index, ref_idx_curr, ref_idx); |
||
609 | return 1; |
||
610 | } |
||
611 | return 0; |
||
612 | } |
||
613 | |||
614 | #define MP_MX(v, pred, mx) \ |
||
615 | mv_mp_mode_mx(s, x##v##_pu, y##v##_pu, pred, &mx, ref_idx_curr, ref_idx) |
||
616 | |||
617 | #define MP_MX_LT(v, pred, mx) \ |
||
618 | mv_mp_mode_mx_lt(s, x##v##_pu, y##v##_pu, pred, &mx, ref_idx_curr, ref_idx) |
||
619 | |||
620 | void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, |
||
621 | int nPbH, int log2_cb_size, int part_idx, |
||
622 | int merge_idx, MvField *mv, |
||
623 | int mvp_lx_flag, int LX) |
||
624 | { |
||
625 | HEVCLocalContext *lc = s->HEVClc; |
||
626 | MvField *tab_mvf = s->ref->tab_mvf; |
||
627 | int isScaledFlag_L0 = 0; |
||
628 | int availableFlagLXA0 = 0; |
||
629 | int availableFlagLXB0 = 0; |
||
630 | int numMVPCandLX = 0; |
||
631 | int min_pu_width = s->sps->min_pu_width; |
||
632 | |||
633 | int xA0, yA0; |
||
634 | int xA0_pu, yA0_pu; |
||
635 | int is_available_a0; |
||
636 | |||
637 | int xA1, yA1; |
||
638 | int xA1_pu, yA1_pu; |
||
639 | int is_available_a1; |
||
640 | |||
641 | int xB0, yB0; |
||
642 | int xB0_pu, yB0_pu; |
||
643 | int is_available_b0; |
||
644 | |||
645 | int xB1, yB1; |
||
646 | int xB1_pu = 0, yB1_pu = 0; |
||
647 | int is_available_b1 = 0; |
||
648 | |||
649 | int xB2, yB2; |
||
650 | int xB2_pu = 0, yB2_pu = 0; |
||
651 | int is_available_b2 = 0; |
||
652 | Mv mvpcand_list[2] = { { 0 } }; |
||
653 | Mv mxA = { 0 }; |
||
654 | Mv mxB = { 0 }; |
||
655 | int ref_idx_curr = 0; |
||
656 | int ref_idx = 0; |
||
657 | int pred_flag_index_l0; |
||
658 | int pred_flag_index_l1; |
||
659 | int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1); |
||
660 | int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1); |
||
661 | |||
662 | int cand_up = (lc->ctb_up_flag || y0b); |
||
663 | int cand_left = (lc->ctb_left_flag || x0b); |
||
664 | int cand_up_left = |
||
665 | (!x0b && !y0b) ? lc->ctb_up_left_flag : cand_left && cand_up; |
||
666 | int cand_up_right = |
||
667 | (x0b + nPbW == (1 << s->sps->log2_ctb_size) || |
||
668 | x0 + nPbW >= lc->end_of_tiles_x) ? lc->ctb_up_right_flag && !y0b |
||
669 | : cand_up; |
||
670 | int cand_bottom_left = (y0 + nPbH >= lc->end_of_tiles_y) ? 0 : cand_left; |
||
671 | |||
672 | ref_idx_curr = LX; |
||
673 | ref_idx = mv->ref_idx[LX]; |
||
674 | pred_flag_index_l0 = LX; |
||
675 | pred_flag_index_l1 = !LX; |
||
676 | |||
677 | // left bottom spatial candidate |
||
678 | xA0 = x0 - 1; |
||
679 | yA0 = y0 + nPbH; |
||
680 | xA0_pu = xA0 >> s->sps->log2_min_pu_size; |
||
681 | yA0_pu = yA0 >> s->sps->log2_min_pu_size; |
||
682 | |||
683 | is_available_a0 = PRED_BLOCK_AVAILABLE(A0) && AVAILABLE(cand_bottom_left, A0); |
||
684 | |||
685 | //left spatial merge candidate |
||
686 | xA1 = x0 - 1; |
||
687 | yA1 = y0 + nPbH - 1; |
||
688 | xA1_pu = xA1 >> s->sps->log2_min_pu_size; |
||
689 | yA1_pu = yA1 >> s->sps->log2_min_pu_size; |
||
690 | |||
691 | is_available_a1 = AVAILABLE(cand_left, A1); |
||
692 | if (is_available_a0 || is_available_a1) { |
||
693 | isScaledFlag_L0 = 1; |
||
694 | } |
||
695 | |||
696 | if (is_available_a0) { |
||
697 | availableFlagLXA0 = MP_MX(A0, pred_flag_index_l0, mxA); |
||
698 | if (!availableFlagLXA0) |
||
699 | availableFlagLXA0 = MP_MX(A0, pred_flag_index_l1, mxA); |
||
700 | } |
||
701 | |||
702 | if (is_available_a1 && !availableFlagLXA0) { |
||
703 | availableFlagLXA0 = MP_MX(A1, pred_flag_index_l0, mxA); |
||
704 | if (!availableFlagLXA0) |
||
705 | availableFlagLXA0 = MP_MX(A1, pred_flag_index_l1, mxA); |
||
706 | } |
||
707 | |||
708 | if (is_available_a0 && !availableFlagLXA0) { |
||
709 | availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l0, mxA); |
||
710 | if (!availableFlagLXA0) |
||
711 | availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l1, mxA); |
||
712 | } |
||
713 | |||
714 | if (is_available_a1 && !availableFlagLXA0) { |
||
715 | availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l0, mxA); |
||
716 | if (!availableFlagLXA0) |
||
717 | availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l1, mxA); |
||
718 | } |
||
719 | |||
720 | // B candidates |
||
721 | // above right spatial merge candidate |
||
722 | xB0 = x0 + nPbW; |
||
723 | yB0 = y0 - 1; |
||
724 | xB0_pu = xB0 >> s->sps->log2_min_pu_size; |
||
725 | yB0_pu = yB0 >> s->sps->log2_min_pu_size; |
||
726 | |||
727 | is_available_b0 = PRED_BLOCK_AVAILABLE(B0) && AVAILABLE(cand_up_right, B0); |
||
728 | |||
729 | if (is_available_b0) { |
||
730 | availableFlagLXB0 = MP_MX(B0, pred_flag_index_l0, mxB); |
||
731 | if (!availableFlagLXB0) |
||
732 | availableFlagLXB0 = MP_MX(B0, pred_flag_index_l1, mxB); |
||
733 | } |
||
734 | |||
735 | if (!availableFlagLXB0) { |
||
736 | // above spatial merge candidate |
||
737 | xB1 = x0 + nPbW - 1; |
||
738 | yB1 = y0 - 1; |
||
739 | xB1_pu = xB1 >> s->sps->log2_min_pu_size; |
||
740 | yB1_pu = yB1 >> s->sps->log2_min_pu_size; |
||
741 | |||
742 | is_available_b1 = AVAILABLE(cand_up, B1); |
||
743 | |||
744 | if (is_available_b1) { |
||
745 | availableFlagLXB0 = MP_MX(B1, pred_flag_index_l0, mxB); |
||
746 | if (!availableFlagLXB0) |
||
747 | availableFlagLXB0 = MP_MX(B1, pred_flag_index_l1, mxB); |
||
748 | } |
||
749 | } |
||
750 | |||
751 | if (!availableFlagLXB0) { |
||
752 | // above left spatial merge candidate |
||
753 | xB2 = x0 - 1; |
||
754 | yB2 = y0 - 1; |
||
755 | xB2_pu = xB2 >> s->sps->log2_min_pu_size; |
||
756 | yB2_pu = yB2 >> s->sps->log2_min_pu_size; |
||
757 | is_available_b2 = AVAILABLE(cand_up_left, B2); |
||
758 | |||
759 | if (is_available_b2) { |
||
760 | availableFlagLXB0 = MP_MX(B2, pred_flag_index_l0, mxB); |
||
761 | if (!availableFlagLXB0) |
||
762 | availableFlagLXB0 = MP_MX(B2, pred_flag_index_l1, mxB); |
||
763 | } |
||
764 | } |
||
765 | |||
766 | if (isScaledFlag_L0 == 0) { |
||
767 | if (availableFlagLXB0) { |
||
768 | availableFlagLXA0 = 1; |
||
769 | mxA = mxB; |
||
770 | } |
||
771 | availableFlagLXB0 = 0; |
||
772 | |||
773 | // XB0 and L1 |
||
774 | if (is_available_b0) { |
||
775 | availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB); |
||
776 | if (!availableFlagLXB0) |
||
777 | availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB); |
||
778 | } |
||
779 | |||
780 | if (is_available_b1 && !availableFlagLXB0) { |
||
781 | availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB); |
||
782 | if (!availableFlagLXB0) |
||
783 | availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB); |
||
784 | } |
||
785 | |||
786 | if (is_available_b2 && !availableFlagLXB0) { |
||
787 | availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB); |
||
788 | if (!availableFlagLXB0) |
||
789 | availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB); |
||
790 | } |
||
791 | } |
||
792 | |||
793 | if (availableFlagLXA0) |
||
794 | mvpcand_list[numMVPCandLX++] = mxA; |
||
795 | |||
796 | if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y)) |
||
797 | mvpcand_list[numMVPCandLX++] = mxB; |
||
798 | |||
799 | //temporal motion vector prediction candidate |
||
800 | if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag) { |
||
801 | Mv mv_col; |
||
802 | int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW, |
||
803 | nPbH, ref_idx, &mv_col, LX); |
||
804 | if (available_col) |
||
805 | mvpcand_list[numMVPCandLX++] = mv_col; |
||
806 | } |
||
807 | |||
808 | // insert zero motion vectors when the number of available candidates are less than 2 |
||
809 | while (numMVPCandLX < 2) |
||
810 | mvpcand_list[numMVPCandLX++] = (Mv){ 0, 0 }; |
||
811 | |||
812 | mv->mv[LX].x = mvpcand_list[mvp_lx_flag].x; |
||
813 | mv->mv[LX].y = mvpcand_list[mvp_lx_flag].y; |
||
814 | }>>><>><>><>><>>>>>>>>><>><>><>><>>>>>>>><>><>>>=>><>><>><>><>=>>>>><>><>><>><> |