/src/libhevc/encoder/ihevce_mv_pred_merge.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2018 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | /** |
21 | | ******************************************************************************* |
22 | | * @file |
23 | | * ihevcd_mv_pred_merge.c |
24 | | * |
25 | | * @brief |
26 | | * Contains functions for motion vector merge candidates derivation |
27 | | * |
28 | | * @author |
29 | | * Ittiam |
30 | | * |
31 | | * @par List of Functions: |
32 | | * - ihevce_compare_pu_mv_t() |
33 | | * - ihevce_mv_pred_merge() |
34 | | * |
35 | | * @remarks |
36 | | * None |
37 | | * |
38 | | ******************************************************************************* |
39 | | */ |
40 | | /*****************************************************************************/ |
41 | | /* File Includes */ |
42 | | /*****************************************************************************/ |
43 | | /* System include files */ |
44 | | #include <stdio.h> |
45 | | #include <string.h> |
46 | | #include <stdlib.h> |
47 | | #include <assert.h> |
48 | | #include <stdarg.h> |
49 | | #include <math.h> |
50 | | |
51 | | /* User include files */ |
52 | | #include "ihevc_typedefs.h" |
53 | | #include "itt_video_api.h" |
54 | | #include "ihevce_api.h" |
55 | | |
56 | | #include "rc_cntrl_param.h" |
57 | | #include "rc_frame_info_collector.h" |
58 | | #include "rc_look_ahead_params.h" |
59 | | |
60 | | #include "ihevc_defs.h" |
61 | | #include "ihevc_macros.h" |
62 | | #include "ihevc_debug.h" |
63 | | #include "ihevc_structs.h" |
64 | | #include "ihevc_platform_macros.h" |
65 | | #include "ihevc_deblk.h" |
66 | | #include "ihevc_itrans_recon.h" |
67 | | #include "ihevc_chroma_itrans_recon.h" |
68 | | #include "ihevc_chroma_intra_pred.h" |
69 | | #include "ihevc_intra_pred.h" |
70 | | #include "ihevc_inter_pred.h" |
71 | | #include "ihevc_mem_fns.h" |
72 | | #include "ihevc_padding.h" |
73 | | #include "ihevc_weighted_pred.h" |
74 | | #include "ihevc_sao.h" |
75 | | #include "ihevc_resi_trans.h" |
76 | | #include "ihevc_quant_iquant_ssd.h" |
77 | | #include "ihevc_cabac_tables.h" |
78 | | #include "ihevc_common_tables.h" |
79 | | |
80 | | #include "ihevce_defs.h" |
81 | | #include "ihevce_hle_interface.h" |
82 | | #include "ihevce_lap_enc_structs.h" |
83 | | #include "ihevce_multi_thrd_structs.h" |
84 | | #include "ihevce_me_common_defs.h" |
85 | | #include "ihevce_had_satd.h" |
86 | | #include "ihevce_error_codes.h" |
87 | | #include "ihevce_bitstream.h" |
88 | | #include "ihevce_cabac.h" |
89 | | #include "ihevce_rdoq_macros.h" |
90 | | #include "ihevce_function_selector.h" |
91 | | #include "ihevce_enc_structs.h" |
92 | | #include "ihevce_entropy_structs.h" |
93 | | #include "ihevce_cmn_utils_instr_set_router.h" |
94 | | #include "ihevce_enc_loop_structs.h" |
95 | | #include "hme_datatype.h" |
96 | | #include "hme_interface.h" |
97 | | #include "hme_common_defs.h" |
98 | | #include "hme_defs.h" |
99 | | #include "ihevce_mv_pred.h" |
100 | | #include "ihevce_mv_pred_merge.h" |
101 | | #include "ihevce_common_utils.h" |
102 | | |
103 | | /*****************************************************************************/ |
104 | | /* Function Definitions */ |
105 | | /*****************************************************************************/ |
106 | | |
107 | | /** |
108 | | ******************************************************************************* |
109 | | * |
110 | | * @brief Function scaling temporal motion vector |
111 | | * |
112 | | * |
113 | | * @par Description: |
114 | | * Scales mv based on difference between current POC and current |
115 | | * reference POC and neighbour reference poc |
116 | | * |
117 | | * @param[inout] mv |
118 | | * motion vector to be scaled |
119 | | * |
120 | | * @param[in] cur_ref_poc |
121 | | * Current PU refernce pic poc |
122 | | * |
123 | | * @param[in] nbr_ref_poc |
124 | | * Neighbor PU reference pic poc |
125 | | * |
126 | | * @param[in] cur_poc |
127 | | * Picture order count of current pic |
128 | | * |
129 | | * @returns |
130 | | * None |
131 | | * |
132 | | * @remarks |
133 | | * |
134 | | ******************************************************************************* |
135 | | */ |
136 | | void ihevce_scale_collocated_mv( |
137 | | mv_t *ps_mv, WORD32 cur_ref_poc, WORD32 col_ref_poc, WORD32 col_poc, WORD32 cur_poc) |
138 | 71.9k | { |
139 | 71.9k | WORD32 td, tb, tx; |
140 | 71.9k | WORD32 dist_scale_factor; |
141 | 71.9k | WORD32 mvx, mvy; |
142 | | |
143 | 71.9k | td = CLIP_S8(col_poc - col_ref_poc); |
144 | 71.9k | tb = CLIP_S8(cur_poc - cur_ref_poc); |
145 | | |
146 | 71.9k | tx = (16384 + (abs(td) >> 1)) / td; |
147 | | |
148 | 71.9k | dist_scale_factor = (tb * tx + 32) >> 6; |
149 | 71.9k | dist_scale_factor = CLIP3(dist_scale_factor, -4096, 4095); |
150 | | |
151 | 71.9k | mvx = ps_mv->i2_mvx; |
152 | 71.9k | mvy = ps_mv->i2_mvy; |
153 | | |
154 | 71.9k | mvx = SIGN(dist_scale_factor * mvx) * ((abs(dist_scale_factor * mvx) + 127) >> 8); |
155 | 71.9k | mvy = SIGN(dist_scale_factor * mvy) * ((abs(dist_scale_factor * mvy) + 127) >> 8); |
156 | | |
157 | 71.9k | ps_mv->i2_mvx = CLIP_S16(mvx); |
158 | 71.9k | ps_mv->i2_mvy = CLIP_S16(mvy); |
159 | | |
160 | 71.9k | } /* End of ihevce_scale_collocated_mv */ |
161 | | |
162 | | void ihevce_collocated_mvp( |
163 | | mv_pred_ctxt_t *ps_mv_ctxt, |
164 | | pu_t *ps_pu, |
165 | | mv_t *ps_mv_col, |
166 | | WORD32 *pu4_avail_col_flag, |
167 | | WORD32 use_pu_ref_idx, |
168 | | WORD32 x_col, |
169 | | WORD32 y_col) |
170 | 580k | { |
171 | 580k | sps_t *ps_sps = ps_mv_ctxt->ps_sps; |
172 | 580k | slice_header_t *ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr; |
173 | 580k | recon_pic_buf_t *ps_col_ref_buf; |
174 | 580k | WORD32 xp_col, yp_col; //In pixel unit |
175 | 580k | WORD32 col_ctb_x, col_ctb_y; //In CTB unit |
176 | 580k | mv_t as_mv_col[2]; |
177 | 580k | WORD32 log2_ctb_size; |
178 | 580k | WORD32 ctb_size; |
179 | 580k | WORD32 avail_col; |
180 | 580k | WORD32 col_ctb_idx, pu_cnt; |
181 | 580k | WORD32 au4_list_col[2]; |
182 | 580k | WORD32 num_minpu_in_ctb; |
183 | 580k | UWORD8 *pu1_pic_pu_map_ctb; |
184 | 580k | pu_col_mv_t *ps_col_mv; |
185 | 580k | WORD32 part_pos_y; |
186 | | |
187 | 580k | part_pos_y = ps_pu->b4_pos_y << 2; |
188 | | |
189 | 580k | log2_ctb_size = ps_sps->i1_log2_ctb_size; |
190 | 580k | ctb_size = (1 << log2_ctb_size); |
191 | | |
192 | 580k | avail_col = 1; |
193 | | |
194 | | /* Initializing reference list */ |
195 | 580k | if((ps_slice_hdr->i1_slice_type == BSLICE) && (ps_slice_hdr->i1_collocated_from_l0_flag == 0)) |
196 | 27.6k | { |
197 | | /* L1 */ |
198 | 27.6k | ps_col_ref_buf = ps_mv_ctxt->ps_ref_list[1][ps_slice_hdr->i1_collocated_ref_idx]; |
199 | 27.6k | } |
200 | 552k | else |
201 | 552k | { |
202 | | /* L0 */ |
203 | 552k | ps_col_ref_buf = ps_mv_ctxt->ps_ref_list[0][ps_slice_hdr->i1_collocated_ref_idx]; |
204 | 552k | } |
205 | 580k | num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE); |
206 | | |
207 | 580k | if(((part_pos_y >> log2_ctb_size) == (y_col >> log2_ctb_size)) && |
208 | 526k | (((x_col + (ps_mv_ctxt->i4_ctb_x << log2_ctb_size)) < ps_sps->i2_pic_width_in_luma_samples) || |
209 | 20.7k | ps_mv_ctxt->ai4_tile_xtra_ctb[2]) && |
210 | 506k | ((((y_col + (ps_mv_ctxt->i4_ctb_y << log2_ctb_size)) < |
211 | 506k | ps_sps->i2_pic_height_in_luma_samples) || |
212 | 7.39k | ps_mv_ctxt->ai4_tile_xtra_ctb[3]))) |
213 | 498k | { |
214 | 498k | xp_col = ((x_col >> 4) << 4); |
215 | 498k | yp_col = ((y_col >> 4) << 4); |
216 | 498k | col_ctb_x = ps_mv_ctxt->i4_ctb_x + (xp_col >> log2_ctb_size); |
217 | 498k | col_ctb_y = ps_mv_ctxt->i4_ctb_y + (yp_col >> log2_ctb_size); |
218 | | |
219 | | /* pu1_frm_pu_map has (i2_pic_wd_in_ctb + 1) CTBs for stride */ |
220 | 498k | col_ctb_idx = col_ctb_x + (col_ctb_y) * (ps_sps->i2_pic_wd_in_ctb + 1); |
221 | | |
222 | 498k | if(xp_col == ctb_size) |
223 | 34.6k | xp_col = 0; |
224 | | |
225 | 498k | pu1_pic_pu_map_ctb = ps_col_ref_buf->pu1_frm_pu_map + col_ctb_idx * num_minpu_in_ctb; |
226 | | |
227 | 498k | pu_cnt = pu1_pic_pu_map_ctb[(yp_col >> 2) * (ctb_size / MIN_PU_SIZE) + (xp_col >> 2)]; |
228 | | |
229 | | /* ps_frm_col_mv has (i2_pic_wd_in_ctb + 1) CTBs for stride */ |
230 | 498k | ps_col_mv = ps_col_ref_buf->ps_frm_col_mv + |
231 | 498k | (col_ctb_y * (ps_sps->i2_pic_wd_in_ctb + 1) + col_ctb_x) * num_minpu_in_ctb + |
232 | 498k | pu_cnt; |
233 | 498k | } |
234 | 81.6k | else |
235 | 81.6k | avail_col = 0; |
236 | | |
237 | 580k | if((avail_col == 0) || (ps_col_mv->b1_intra_flag == 1) || |
238 | 154k | (ps_slice_hdr->i1_slice_temporal_mvp_enable_flag == 0)) |
239 | 425k | { |
240 | 425k | pu4_avail_col_flag[0] = 0; |
241 | 425k | pu4_avail_col_flag[1] = 0; |
242 | 425k | ps_mv_col[0].i2_mvx = 0; |
243 | 425k | ps_mv_col[0].i2_mvy = 0; |
244 | 425k | ps_mv_col[1].i2_mvx = 0; |
245 | 425k | ps_mv_col[1].i2_mvy = 0; |
246 | 425k | } |
247 | 154k | else |
248 | 154k | { |
249 | 154k | WORD32 au4_ref_idx_col[2]; |
250 | 154k | WORD32 pred_flag_l0, pred_flag_l1; |
251 | 154k | pred_flag_l0 = (ps_col_mv->b2_pred_mode != PRED_L1); |
252 | 154k | pred_flag_l1 = (ps_col_mv->b2_pred_mode != PRED_L0); |
253 | | |
254 | 154k | if(pred_flag_l0 == 0) |
255 | 734 | { |
256 | 734 | as_mv_col[0] = ps_col_mv->s_l1_mv; |
257 | 734 | au4_ref_idx_col[0] = ps_col_mv->i1_l1_ref_idx; |
258 | 734 | au4_list_col[0] = 1; /* L1 */ |
259 | | |
260 | 734 | as_mv_col[1] = ps_col_mv->s_l1_mv; |
261 | 734 | au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx; |
262 | 734 | au4_list_col[1] = 1; /* L1 */ |
263 | 734 | } |
264 | 153k | else |
265 | 153k | { |
266 | 153k | if(pred_flag_l1 == 0) |
267 | 151k | { |
268 | 151k | as_mv_col[0] = ps_col_mv->s_l0_mv; |
269 | 151k | au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx; |
270 | 151k | au4_list_col[0] = 0; /* L1 */ |
271 | | |
272 | 151k | as_mv_col[1] = ps_col_mv->s_l0_mv; |
273 | 151k | au4_ref_idx_col[1] = ps_col_mv->i1_l0_ref_idx; |
274 | 151k | au4_list_col[1] = 0; /* L1 */ |
275 | 151k | } |
276 | 2.18k | else |
277 | 2.18k | { |
278 | 2.18k | if(1 == ps_slice_hdr->i1_low_delay_flag) |
279 | 0 | { |
280 | 0 | as_mv_col[0] = ps_col_mv->s_l0_mv; |
281 | 0 | au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx; |
282 | 0 | au4_list_col[0] = 0; /* L0 */ |
283 | |
|
284 | 0 | as_mv_col[1] = ps_col_mv->s_l1_mv; |
285 | 0 | au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx; |
286 | 0 | au4_list_col[1] = 1; /* L1 */ |
287 | 0 | } |
288 | 2.18k | else |
289 | 2.18k | { |
290 | 2.18k | if(0 == ps_slice_hdr->i1_collocated_from_l0_flag) |
291 | 1.74k | { |
292 | 1.74k | as_mv_col[0] = ps_col_mv->s_l0_mv; |
293 | 1.74k | au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx; |
294 | | |
295 | 1.74k | as_mv_col[1] = ps_col_mv->s_l0_mv; |
296 | 1.74k | au4_ref_idx_col[1] = ps_col_mv->i1_l0_ref_idx; |
297 | 1.74k | } |
298 | 440 | else |
299 | 440 | { |
300 | 440 | as_mv_col[0] = ps_col_mv->s_l1_mv; |
301 | 440 | au4_ref_idx_col[0] = ps_col_mv->i1_l1_ref_idx; |
302 | | |
303 | 440 | as_mv_col[1] = ps_col_mv->s_l1_mv; |
304 | 440 | au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx; |
305 | 440 | } |
306 | | |
307 | 2.18k | au4_list_col[0] = |
308 | 2.18k | ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */ |
309 | 2.18k | au4_list_col[1] = |
310 | 2.18k | ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */ |
311 | 2.18k | } |
312 | 2.18k | } |
313 | 153k | } |
314 | 154k | avail_col = 1; |
315 | 154k | { |
316 | 154k | WORD32 cur_poc, col_poc, col_ref_poc_l0, cur_ref_poc; |
317 | 154k | WORD32 col_ref_poc_l0_lt, cur_ref_poc_lt; |
318 | 154k | WORD32 ref_idx_l0, ref_idx_l1; |
319 | | |
320 | 154k | if(use_pu_ref_idx) |
321 | 53.9k | { |
322 | 53.9k | ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx; |
323 | 53.9k | ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx; |
324 | 53.9k | } |
325 | 100k | else |
326 | 100k | { |
327 | 100k | ref_idx_l0 = 0; |
328 | 100k | ref_idx_l1 = 0; |
329 | 100k | } |
330 | | |
331 | 154k | col_poc = ps_col_ref_buf->i4_poc; |
332 | 154k | cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt; |
333 | | |
334 | 154k | if(-1 != ref_idx_l0) |
335 | 151k | { |
336 | 151k | if(au4_list_col[0] == 0) |
337 | 150k | { |
338 | 150k | col_ref_poc_l0 = ps_col_ref_buf->ai4_col_l0_poc[au4_ref_idx_col[0]]; |
339 | 150k | col_ref_poc_l0_lt = 0; /* Encoder has only short term references */ |
340 | 150k | } |
341 | 991 | else |
342 | 991 | { |
343 | 991 | col_ref_poc_l0 = ps_col_ref_buf->ai4_col_l1_poc[au4_ref_idx_col[0]]; |
344 | 991 | col_ref_poc_l0_lt = 0; |
345 | 991 | } |
346 | | /* L0 collocated mv */ |
347 | 151k | cur_ref_poc = ps_mv_ctxt->ps_ref_list[0][ref_idx_l0]->i4_poc; |
348 | 151k | cur_ref_poc_lt = 0; |
349 | | |
350 | 151k | { |
351 | 151k | pu4_avail_col_flag[0] = 1; |
352 | | |
353 | | /*if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc)))*/ |
354 | 151k | if((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc)) |
355 | 89.5k | { |
356 | 89.5k | ps_mv_col[0] = as_mv_col[0]; |
357 | 89.5k | } |
358 | 61.7k | else |
359 | 61.7k | { |
360 | 61.7k | ps_mv_col[0] = as_mv_col[0]; |
361 | 61.7k | if(col_ref_poc_l0 != col_poc) |
362 | 61.7k | { |
363 | 61.7k | ihevce_scale_collocated_mv( |
364 | 61.7k | (mv_t *)(&ps_mv_col[0]), |
365 | 61.7k | cur_ref_poc, |
366 | 61.7k | col_ref_poc_l0, |
367 | 61.7k | col_poc, |
368 | 61.7k | cur_poc); |
369 | 61.7k | } |
370 | 61.7k | } |
371 | 151k | } |
372 | 151k | } |
373 | 3.11k | else |
374 | 3.11k | { |
375 | 3.11k | pu4_avail_col_flag[0] = 0; |
376 | 3.11k | ps_mv_col[0].i2_mvx = 0; |
377 | 3.11k | ps_mv_col[0].i2_mvy = 0; |
378 | 3.11k | } |
379 | 154k | if((BSLICE == ps_slice_hdr->i1_slice_type) && (-1 != ref_idx_l1)) |
380 | 10.3k | { |
381 | 10.3k | WORD32 col_ref_poc_l1_lt, col_ref_poc_l1; |
382 | | |
383 | 10.3k | if(au4_list_col[1] == 0) |
384 | 9.33k | { |
385 | 9.33k | col_ref_poc_l1 = ps_col_ref_buf->ai4_col_l0_poc[au4_ref_idx_col[0]]; |
386 | 9.33k | col_ref_poc_l1_lt = 0; |
387 | 9.33k | } |
388 | 991 | else |
389 | 991 | { |
390 | 991 | col_ref_poc_l1 = ps_col_ref_buf->ai4_col_l1_poc[au4_ref_idx_col[0]]; |
391 | 991 | col_ref_poc_l1_lt = 0; |
392 | 991 | } |
393 | | |
394 | | /* L1 collocated mv */ |
395 | 10.3k | cur_ref_poc = ps_mv_ctxt->ps_ref_list[1][ref_idx_l1]->i4_poc; |
396 | 10.3k | cur_ref_poc_lt = 0; |
397 | | |
398 | 10.3k | { |
399 | 10.3k | pu4_avail_col_flag[1] = 1; |
400 | | |
401 | | /*if(cur_ref_poc_lt || ((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc)))*/ |
402 | 10.3k | if((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc)) |
403 | 146 | { |
404 | 146 | ps_mv_col[1] = as_mv_col[1]; |
405 | 146 | } |
406 | 10.1k | else |
407 | 10.1k | { |
408 | 10.1k | ps_mv_col[1] = as_mv_col[1]; |
409 | 10.1k | if(col_ref_poc_l1 != col_poc) |
410 | 10.1k | { |
411 | 10.1k | ihevce_scale_collocated_mv( |
412 | 10.1k | (mv_t *)&ps_mv_col[1], |
413 | 10.1k | cur_ref_poc, |
414 | 10.1k | col_ref_poc_l1, |
415 | 10.1k | col_poc, |
416 | 10.1k | cur_poc); |
417 | 10.1k | } |
418 | 10.1k | } |
419 | 10.3k | } |
420 | 10.3k | } /* End of if BSLICE */ |
421 | 144k | else |
422 | 144k | { |
423 | 144k | pu4_avail_col_flag[1] = 0; |
424 | 144k | } |
425 | 154k | } |
426 | | |
427 | 154k | } /* End of collocated MV calculation */ |
428 | | |
429 | 580k | } /* End of ihevce_collocated_mvp */ |
430 | | |
431 | | /** |
432 | | ******************************************************************************* |
433 | | * |
434 | | * @brief Compare Motion vectors function |
435 | | * |
436 | | * |
437 | | * @par Description: |
438 | | * Checks if MVs and Reference idx are excatly matching. |
439 | | * |
440 | | * @param[inout] ps_1 |
441 | | * motion vector 1 to be compared |
442 | | * |
443 | | * @param[in] ps_2 |
444 | | * motion vector 2 to be compared |
445 | | * |
446 | | * @returns |
447 | | * 0 : if not matching 1 : if matching |
448 | | * |
449 | | * @remarks |
450 | | * |
451 | | ******************************************************************************* |
452 | | */ |
453 | | |
454 | | /** |
455 | | ******************************************************************************* |
456 | | * |
457 | | * @brief |
458 | | * This function performs Motion Vector Merge candidates derivation |
459 | | * |
460 | | * @par Description: |
461 | | * MV merge list is computed using neighbor mvs and colocated mv |
462 | | * |
463 | | * @param[in] ps_ctxt |
464 | | * pointer to mv predictor context |
465 | | * |
466 | | * @param[in] ps_top_nbr_4x4 |
467 | | * pointer to top 4x4 nbr structure |
468 | | * |
469 | | * @param[in] ps_left_nbr_4x4 |
470 | | * pointer to left 4x4 nbr structure |
471 | | * |
472 | | * @param[in] ps_top_left_nbr_4x4 |
473 | | * pointer to top left 4x4 nbr structure |
474 | | * |
475 | | * @param[in] left_nbr_4x4_strd |
476 | | * left nbr buffer stride in terms of 4x4 units |
477 | | * |
478 | | * @param[in] ps_avail_flags |
479 | | * Neighbor availability flags container |
480 | | * |
481 | | * @param[in] ps_col_mv |
482 | | * Colocated MV pointer |
483 | | * |
484 | | * @param[in] ps_pu |
485 | | * Current Partition PU strucrture pointer |
486 | | * |
487 | | * @param[in] part_mode |
488 | | * Partition mode @sa PART_SIZE_E |
489 | | * |
490 | | * @param[in] part_idx |
491 | | * Partition idx of current partition inside CU |
492 | | * |
493 | | * @param[in] single_mcl_flag |
494 | | * Single MCL flag based on 8x8 CU and Parallel merge value |
495 | | * |
496 | | * @param[out] ps_merge_cand_list |
497 | | * pointer to store MV merge candidates list |
498 | | * |
499 | | * @returns |
500 | | * Number of merge candidates |
501 | | * @remarks |
502 | | * |
503 | | * |
504 | | ******************************************************************************* |
505 | | */ |
506 | | WORD32 ihevce_mv_pred_merge( |
507 | | mv_pred_ctxt_t *ps_ctxt, |
508 | | nbr_4x4_t *ps_top_nbr_4x4, |
509 | | nbr_4x4_t *ps_left_nbr_4x4, |
510 | | nbr_4x4_t *ps_top_left_nbr_4x4, |
511 | | WORD32 left_nbr_4x4_strd, |
512 | | nbr_avail_flags_t *ps_avail_flags, |
513 | | pu_mv_t *ps_col_mv, |
514 | | pu_t *ps_pu, |
515 | | PART_SIZE_E part_mode, |
516 | | WORD32 part_idx, |
517 | | WORD32 single_mcl_flag, |
518 | | merge_cand_list_t *ps_merge_cand_list, |
519 | | UWORD8 *pu1_is_top_used) |
520 | 179k | { |
521 | | /******************************************************/ |
522 | | /* Spatial Merge Candidates */ |
523 | | /******************************************************/ |
524 | 179k | WORD32 part_pos_x; |
525 | 179k | WORD32 part_pos_y; |
526 | 179k | WORD32 part_wd; |
527 | 179k | WORD32 part_ht; |
528 | 179k | WORD32 slice_type; |
529 | 179k | WORD32 num_ref_idx_l0_active; |
530 | 179k | WORD32 num_ref_idx_l1_active; |
531 | 179k | WORD32 num_merge_cand; |
532 | 179k | WORD32 log2_parallel_merge_level_minus2; |
533 | 179k | WORD32 n; |
534 | 179k | WORD8 i1_spatial_avail_flag_n[MAX_NUM_MV_NBR]; /*[A0/A1/B0/B1/B2]*/ |
535 | 179k | WORD32 nbr_x[MAX_NUM_MV_NBR], nbr_y[MAX_NUM_MV_NBR]; |
536 | 179k | UWORD8 u1_nbr_avail[MAX_NUM_MV_NBR]; |
537 | 179k | WORD32 merge_shift; |
538 | 179k | nbr_4x4_t *ps_nbr_mv[MAX_NUM_MV_NBR]; |
539 | | |
540 | | /*******************************************/ |
541 | | /* Neighbor location: Graphical indication */ |
542 | | /* */ |
543 | | /* B2 _____________B1 B0 */ |
544 | | /* | | */ |
545 | | /* | | */ |
546 | | /* | | */ |
547 | | /* | PU ht| */ |
548 | | /* | | */ |
549 | | /* | | */ |
550 | | /* A1|______wd_______| */ |
551 | | /* A0 */ |
552 | | /* */ |
553 | | /*******************************************/ |
554 | | |
555 | 179k | part_pos_x = ps_pu->b4_pos_x << 2; |
556 | 179k | part_pos_y = ps_pu->b4_pos_y << 2; |
557 | 179k | part_ht = (ps_pu->b4_ht + 1) << 2; |
558 | 179k | part_wd = (ps_pu->b4_wd + 1) << 2; |
559 | | |
560 | 179k | slice_type = ps_ctxt->ps_slice_hdr->i1_slice_type; |
561 | 179k | num_ref_idx_l0_active = ps_ctxt->ps_slice_hdr->i1_num_ref_idx_l0_active; |
562 | 179k | num_ref_idx_l1_active = ps_ctxt->ps_slice_hdr->i1_num_ref_idx_l1_active; |
563 | 179k | log2_parallel_merge_level_minus2 = ps_ctxt->i4_log2_parallel_merge_level_minus2; |
564 | | |
565 | | /* Assigning co-ordinates to neighbors */ |
566 | 179k | nbr_x[NBR_A0] = part_pos_x - 1; |
567 | 179k | nbr_y[NBR_A0] = part_pos_y + part_ht; /* A0 */ |
568 | | |
569 | 179k | nbr_x[NBR_A1] = part_pos_x - 1; |
570 | 179k | nbr_y[NBR_A1] = part_pos_y + part_ht - 1; /* A1 */ |
571 | | |
572 | 179k | nbr_x[NBR_B0] = part_pos_x + part_wd; |
573 | 179k | nbr_y[NBR_B0] = part_pos_y - 1; /* B0 */ |
574 | | |
575 | 179k | nbr_x[NBR_B1] = part_pos_x + part_wd - 1; |
576 | 179k | nbr_y[NBR_B1] = part_pos_y - 1; /* B1 */ |
577 | | |
578 | 179k | nbr_x[NBR_B2] = part_pos_x - 1; |
579 | 179k | nbr_y[NBR_B2] = part_pos_y - 1; /* B2 */ |
580 | | |
581 | | /* Assigning mv's */ |
582 | 179k | ps_nbr_mv[NBR_A0] = ps_left_nbr_4x4 + ((nbr_y[NBR_A0] - part_pos_y) >> 2) * left_nbr_4x4_strd; |
583 | 179k | ps_nbr_mv[NBR_A1] = ps_left_nbr_4x4 + ((nbr_y[NBR_A1] - part_pos_y) >> 2) * left_nbr_4x4_strd; |
584 | 179k | ps_nbr_mv[NBR_B0] = ps_top_nbr_4x4 + ((nbr_x[NBR_B0] - part_pos_x) >> 2); |
585 | 179k | ps_nbr_mv[NBR_B1] = ps_top_nbr_4x4 + ((nbr_x[NBR_B1] - part_pos_x) >> 2); |
586 | | |
587 | 179k | if(part_pos_y == 0) /* AT vertical CTB boundary */ |
588 | 41.9k | ps_nbr_mv[NBR_B2] = ps_top_nbr_4x4 + ((nbr_x[NBR_B2] - part_pos_x) >> 2); |
589 | 137k | else |
590 | 137k | ps_nbr_mv[NBR_B2] = ps_top_left_nbr_4x4; |
591 | | |
592 | | /* Assigning nbr availability */ |
593 | 179k | u1_nbr_avail[NBR_A0] = ps_avail_flags->u1_bot_lt_avail && |
594 | 55.3k | (!ps_nbr_mv[NBR_A0]->b1_intra_flag); /* A0 */ |
595 | 179k | u1_nbr_avail[NBR_A1] = ps_avail_flags->u1_left_avail && |
596 | 153k | (!ps_nbr_mv[NBR_A1]->b1_intra_flag); /* A1 */ |
597 | 179k | u1_nbr_avail[NBR_B0] = ps_avail_flags->u1_top_rt_avail && |
598 | 80.7k | (!ps_nbr_mv[NBR_B0]->b1_intra_flag); /* B0 */ |
599 | 179k | u1_nbr_avail[NBR_B1] = ps_avail_flags->u1_top_avail && |
600 | 155k | (!ps_nbr_mv[NBR_B1]->b1_intra_flag); /* B1 */ |
601 | 179k | u1_nbr_avail[NBR_B2] = ps_avail_flags->u1_top_lt_avail && |
602 | 134k | (!ps_nbr_mv[NBR_B2]->b1_intra_flag); /* B2 */ |
603 | | |
604 | 179k | merge_shift = log2_parallel_merge_level_minus2 + 2; |
605 | | |
606 | | /* Availability check */ |
607 | | /* A1 */ |
608 | 179k | { |
609 | 179k | WORD32 avail_flag; |
610 | 179k | avail_flag = 1; |
611 | 179k | n = NBR_A1; |
612 | | |
613 | | /* if at same merge level */ |
614 | 179k | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
615 | 0 | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
616 | 0 | { |
617 | 0 | u1_nbr_avail[n] = 0; |
618 | 0 | } |
619 | | |
620 | | /* SPEC JCTVC-K1003_v9 version has a different way using not available */ |
621 | | /* candidates compared to software. for non square part and seconf part case */ |
622 | | /* ideally nothing from the 1st partition should be used as per spec but */ |
623 | | /* HM 8.2 dev verison does not adhere to this. currenlty code fllows HM */ |
624 | | |
625 | | /* if single MCL is 0 , second part of 2 part in CU */ |
626 | 179k | if((single_mcl_flag == 0) && (part_idx == 1) && |
627 | 36.6k | ((part_mode == PART_Nx2N) || (part_mode == PART_nLx2N) || (part_mode == PART_nRx2N))) |
628 | 7.78k | { |
629 | 7.78k | u1_nbr_avail[n] = 0; |
630 | 7.78k | } |
631 | | |
632 | 179k | if(u1_nbr_avail[n] == 0) |
633 | 100k | { |
634 | 100k | avail_flag = 0; |
635 | 100k | } |
636 | 179k | i1_spatial_avail_flag_n[n] = avail_flag; |
637 | 179k | } |
638 | | /* B1 */ |
639 | 179k | { |
640 | 179k | WORD32 avail_flag; |
641 | 179k | avail_flag = 1; |
642 | 179k | n = NBR_B1; |
643 | | |
644 | | /* if at same merge level */ |
645 | 179k | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
646 | 2.77k | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
647 | 0 | { |
648 | 0 | u1_nbr_avail[n] = 0; |
649 | 0 | } |
650 | | |
651 | | /* if single MCL is 0 , second part of 2 part in CU */ |
652 | 179k | if((single_mcl_flag == 0) && (part_idx == 1) && |
653 | 36.6k | ((part_mode == PART_2NxN) || (part_mode == PART_2NxnU) || (part_mode == PART_2NxnD))) |
654 | 28.9k | { |
655 | 28.9k | u1_nbr_avail[n] = 0; |
656 | 28.9k | } |
657 | | |
658 | 179k | if(u1_nbr_avail[n] == 0) |
659 | 114k | { |
660 | 114k | avail_flag = 0; |
661 | 114k | } |
662 | | |
663 | 179k | if((avail_flag == 1) && (u1_nbr_avail[NBR_A1] == 1)) |
664 | 46.1k | { |
665 | | /* TODO: Assumption: mvs and ref indicies in both l0 and l1*/ |
666 | | /* should match for non availability */ |
667 | 46.1k | WORD32 i4_pred_1, i4_pred_2; |
668 | 46.1k | i4_pred_1 = |
669 | 46.1k | (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) - |
670 | 46.1k | 1; |
671 | 46.1k | i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
672 | 46.1k | if(ihevce_compare_pu_mv_t( |
673 | 46.1k | &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
674 | 27.7k | { |
675 | 27.7k | avail_flag = 0; |
676 | 27.7k | } |
677 | 46.1k | } |
678 | 179k | i1_spatial_avail_flag_n[n] = avail_flag; |
679 | 179k | } |
680 | | |
681 | | /* B0 */ |
682 | 179k | { |
683 | 179k | WORD32 avail_flag; |
684 | 179k | avail_flag = 1; |
685 | 179k | n = NBR_B0; |
686 | | |
687 | | /* if at same merge level */ |
688 | 179k | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
689 | 0 | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
690 | 0 | { |
691 | 0 | u1_nbr_avail[n] = 0; |
692 | 0 | } |
693 | | |
694 | 179k | if(u1_nbr_avail[n] == 0) |
695 | 139k | { |
696 | 139k | avail_flag = 0; |
697 | 139k | } |
698 | | |
699 | 179k | if((avail_flag == 1) && (u1_nbr_avail[NBR_B1] == 1)) |
700 | 35.9k | { |
701 | 35.9k | WORD32 i4_pred_1, i4_pred_2; |
702 | 35.9k | i4_pred_1 = |
703 | 35.9k | (ps_nbr_mv[NBR_B1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_B1]->b1_pred_l1_flag << 1)) - |
704 | 35.9k | 1; |
705 | 35.9k | i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
706 | 35.9k | if(ihevce_compare_pu_mv_t( |
707 | 35.9k | &ps_nbr_mv[NBR_B1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
708 | 30.8k | { |
709 | 30.8k | avail_flag = 0; |
710 | 30.8k | } |
711 | 35.9k | } |
712 | 179k | i1_spatial_avail_flag_n[n] = avail_flag; |
713 | 179k | } |
714 | | |
715 | | /* A0 */ |
716 | 179k | { |
717 | 179k | WORD32 avail_flag; |
718 | 179k | avail_flag = 1; |
719 | 179k | n = NBR_A0; |
720 | | |
721 | | /* if at same merge level */ |
722 | 179k | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
723 | 0 | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
724 | 0 | { |
725 | 0 | u1_nbr_avail[n] = 0; |
726 | 0 | } |
727 | | |
728 | 179k | if(u1_nbr_avail[n] == 0) |
729 | 152k | { |
730 | 152k | avail_flag = 0; |
731 | 152k | } |
732 | | |
733 | 179k | if((avail_flag == 1) && (u1_nbr_avail[NBR_A1] == 1)) |
734 | 24.5k | { |
735 | 24.5k | WORD32 i4_pred_1, i4_pred_2; |
736 | 24.5k | i4_pred_1 = |
737 | 24.5k | (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) - |
738 | 24.5k | 1; |
739 | 24.5k | i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
740 | 24.5k | if(ihevce_compare_pu_mv_t( |
741 | 24.5k | &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
742 | 19.5k | { |
743 | 19.5k | avail_flag = 0; |
744 | 19.5k | } |
745 | 24.5k | } |
746 | 179k | i1_spatial_avail_flag_n[n] = avail_flag; |
747 | 179k | } |
748 | | /* B2 */ |
749 | 179k | { |
750 | 179k | WORD32 avail_flag; |
751 | 179k | avail_flag = 1; |
752 | 179k | n = NBR_B2; |
753 | | |
754 | | /* if at same merge level */ |
755 | 179k | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
756 | 0 | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
757 | 0 | { |
758 | 0 | u1_nbr_avail[n] = 0; |
759 | 0 | } |
760 | | |
761 | 179k | if(u1_nbr_avail[n] == 0) |
762 | 113k | { |
763 | 113k | avail_flag = 0; |
764 | 113k | } |
765 | | |
766 | 179k | if((i1_spatial_avail_flag_n[NBR_A0] + i1_spatial_avail_flag_n[NBR_A1] + |
767 | 179k | i1_spatial_avail_flag_n[NBR_B0] + i1_spatial_avail_flag_n[NBR_B1]) == 4) |
768 | 285 | { |
769 | 285 | avail_flag = 0; |
770 | 285 | } |
771 | | |
772 | 179k | if(avail_flag == 1) |
773 | 65.1k | { |
774 | 65.1k | if(u1_nbr_avail[NBR_A1] == 1) |
775 | 56.4k | { |
776 | 56.4k | WORD32 i4_pred_1, i4_pred_2; |
777 | 56.4k | i4_pred_1 = (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | |
778 | 56.4k | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) - |
779 | 56.4k | 1; |
780 | 56.4k | i4_pred_2 = |
781 | 56.4k | (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
782 | 56.4k | if(ihevce_compare_pu_mv_t( |
783 | 56.4k | &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
784 | 38.1k | { |
785 | 38.1k | avail_flag = 0; |
786 | 38.1k | } |
787 | 56.4k | } |
788 | 65.1k | if(u1_nbr_avail[NBR_B1] == 1) |
789 | 49.3k | { |
790 | 49.3k | WORD32 i4_pred_1, i4_pred_2; |
791 | 49.3k | i4_pred_1 = (ps_nbr_mv[NBR_B1]->b1_pred_l0_flag | |
792 | 49.3k | (ps_nbr_mv[NBR_B1]->b1_pred_l1_flag << 1)) - |
793 | 49.3k | 1; |
794 | 49.3k | i4_pred_2 = |
795 | 49.3k | (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
796 | 49.3k | if(ihevce_compare_pu_mv_t( |
797 | 49.3k | &ps_nbr_mv[NBR_B1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
798 | 41.9k | { |
799 | 41.9k | avail_flag = 0; |
800 | 41.9k | } |
801 | 49.3k | } |
802 | 65.1k | } |
803 | 179k | i1_spatial_avail_flag_n[n] = avail_flag; |
804 | 179k | } |
805 | | |
806 | | /******************************************************/ |
807 | | /* Merge Candidates List */ |
808 | | /******************************************************/ |
809 | | /* Preparing MV merge candidate list */ |
810 | 179k | { |
811 | 179k | WORD32 merge_list_priority[MAX_NUM_MERGE_CAND] = { NBR_A1, NBR_B1, NBR_B0, NBR_A0, NBR_B2 }; |
812 | | |
813 | 179k | num_merge_cand = 0; |
814 | 1.07M | for(n = 0; n < MAX_NUM_MERGE_CAND; n++) |
815 | 896k | { |
816 | 896k | WORD32 merge_idx; |
817 | 896k | merge_idx = merge_list_priority[n]; |
818 | 896k | if(i1_spatial_avail_flag_n[merge_idx] == 1) |
819 | 143k | { |
820 | 143k | ps_merge_cand_list[num_merge_cand].mv = ps_nbr_mv[merge_idx]->mv; |
821 | 143k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = |
822 | 143k | (UWORD8)ps_nbr_mv[merge_idx]->b1_pred_l0_flag; |
823 | 143k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = |
824 | 143k | (UWORD8)ps_nbr_mv[merge_idx]->b1_pred_l1_flag; |
825 | | |
826 | 143k | switch(merge_list_priority[n]) |
827 | 143k | { |
828 | 79.1k | case NBR_A1: |
829 | 86.3k | case NBR_A0: |
830 | 86.3k | { |
831 | 86.3k | pu1_is_top_used[num_merge_cand] = 0; |
832 | | |
833 | 86.3k | break; |
834 | 79.1k | } |
835 | 57.0k | default: |
836 | 57.0k | { |
837 | 57.0k | pu1_is_top_used[num_merge_cand] = 1; |
838 | | |
839 | 57.0k | break; |
840 | 79.1k | } |
841 | 143k | } |
842 | | |
843 | 143k | num_merge_cand++; |
844 | 143k | } |
845 | 896k | } |
846 | | |
847 | | /******************************************************/ |
848 | | /* Temporal Merge Candidates */ |
849 | | /******************************************************/ |
850 | 179k | if(num_merge_cand < MAX_NUM_MERGE_CAND) |
851 | 179k | { |
852 | 179k | mv_t as_mv_col[2]; |
853 | 179k | WORD32 avail_col_flag[2] = { 0 }, x_col, y_col; |
854 | 179k | WORD32 avail_col_l0, avail_col_l1; |
855 | | |
856 | | /* Checking Collocated MV availability at Bottom right of PU*/ |
857 | 179k | x_col = part_pos_x + part_wd; |
858 | 179k | y_col = part_pos_y + part_ht; |
859 | 179k | ihevce_collocated_mvp(ps_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col); |
860 | | |
861 | 179k | avail_col_l0 = avail_col_flag[0]; |
862 | 179k | avail_col_l1 = avail_col_flag[1]; |
863 | | |
864 | 179k | if(avail_col_l0 || avail_col_l1) |
865 | 41.0k | { |
866 | 41.0k | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = as_mv_col[0]; |
867 | 41.0k | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = as_mv_col[1]; |
868 | 41.0k | } |
869 | | |
870 | 179k | if(avail_col_l0 == 0 || avail_col_l1 == 0) |
871 | 174k | { |
872 | | /* Checking Collocated MV availability at Center of PU */ |
873 | 174k | x_col = part_pos_x + (part_wd >> 1); |
874 | 174k | y_col = part_pos_y + (part_ht >> 1); |
875 | 174k | ihevce_collocated_mvp(ps_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col); |
876 | | |
877 | 174k | if(avail_col_l0 == 0) |
878 | 138k | { |
879 | 138k | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = as_mv_col[0]; |
880 | 138k | } |
881 | 174k | if(avail_col_l1 == 0) |
882 | 174k | { |
883 | 174k | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = as_mv_col[1]; |
884 | 174k | } |
885 | | |
886 | 174k | avail_col_l0 |= avail_col_flag[0]; |
887 | 174k | avail_col_l1 |= avail_col_flag[1]; |
888 | 174k | } |
889 | | |
890 | 179k | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = 0; |
891 | 179k | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = 0; |
892 | 179k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = avail_col_l0 ? 1 : 0; |
893 | 179k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = avail_col_l1 ? 1 : 0; |
894 | | |
895 | 179k | if(avail_col_l0 || avail_col_l1) |
896 | 69.1k | { |
897 | 69.1k | pu1_is_top_used[num_merge_cand] = 0; |
898 | 69.1k | num_merge_cand++; |
899 | 69.1k | } |
900 | 179k | } |
901 | | |
902 | | /******************************************************/ |
903 | | /* Bi pred merge candidates */ |
904 | | /******************************************************/ |
905 | 179k | if(slice_type == BSLICE) |
906 | 11.2k | { |
907 | 11.2k | if((num_merge_cand > 1) && (num_merge_cand < MAX_NUM_MERGE_CAND)) |
908 | 6.43k | { |
909 | 6.43k | WORD32 priority_list0[12] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 }; |
910 | 6.43k | WORD32 priority_list1[12] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 }; |
911 | 6.43k | WORD32 l0_cand, l1_cand; |
912 | 6.43k | WORD32 bi_pred_idx = 0; |
913 | 6.43k | WORD32 total_bi_pred_cand = num_merge_cand * (num_merge_cand - 1); |
914 | | |
915 | 14.6k | while(bi_pred_idx < total_bi_pred_cand) |
916 | 14.6k | { |
917 | 14.6k | l0_cand = priority_list0[bi_pred_idx]; |
918 | 14.6k | l1_cand = priority_list1[bi_pred_idx]; |
919 | | |
920 | 14.6k | if((ps_merge_cand_list[l0_cand].u1_pred_flag_l0 == 1) && |
921 | 11.8k | (ps_merge_cand_list[l1_cand].u1_pred_flag_l1 == 1)) |
922 | 9.37k | { |
923 | 9.37k | WORD8 i1_l0_ref_idx, i1_l1_ref_idx; |
924 | 9.37k | WORD32 l0_poc, l1_poc; |
925 | 9.37k | mv_t s_l0_mv, s_l1_mv; |
926 | | |
927 | 9.37k | i1_l0_ref_idx = ps_merge_cand_list[l0_cand].mv.i1_l0_ref_idx; |
928 | 9.37k | i1_l1_ref_idx = ps_merge_cand_list[l1_cand].mv.i1_l1_ref_idx; |
929 | 9.37k | l0_poc = ps_ctxt->ps_ref_list[0][i1_l0_ref_idx]->i4_poc; |
930 | 9.37k | l1_poc = ps_ctxt->ps_ref_list[1][i1_l1_ref_idx]->i4_poc; |
931 | 9.37k | s_l0_mv = ps_merge_cand_list[l0_cand].mv.s_l0_mv; |
932 | 9.37k | s_l1_mv = ps_merge_cand_list[l1_cand].mv.s_l1_mv; |
933 | | |
934 | 9.37k | if((l0_poc != l1_poc) || (s_l0_mv.i2_mvx != s_l1_mv.i2_mvx) || |
935 | 0 | (s_l0_mv.i2_mvy != s_l1_mv.i2_mvy)) |
936 | 9.37k | { |
937 | 9.37k | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = s_l0_mv; |
938 | 9.37k | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = s_l1_mv; |
939 | 9.37k | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = i1_l0_ref_idx; |
940 | 9.37k | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = i1_l1_ref_idx; |
941 | 9.37k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1; |
942 | 9.37k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 1; |
943 | | |
944 | 9.37k | if(pu1_is_top_used[l0_cand] || pu1_is_top_used[l1_cand]) |
945 | 2.20k | { |
946 | 2.20k | pu1_is_top_used[num_merge_cand] = 1; |
947 | 2.20k | } |
948 | 7.16k | else |
949 | 7.16k | { |
950 | 7.16k | pu1_is_top_used[num_merge_cand] = 0; |
951 | 7.16k | } |
952 | | |
953 | 9.37k | num_merge_cand++; |
954 | 9.37k | } |
955 | 9.37k | } |
956 | | |
957 | 14.6k | bi_pred_idx++; |
958 | | |
959 | 14.6k | if((bi_pred_idx == total_bi_pred_cand) || |
960 | 9.41k | (num_merge_cand == MAX_NUM_MERGE_CAND)) |
961 | 6.43k | { |
962 | 6.43k | break; |
963 | 6.43k | } |
964 | 14.6k | } |
965 | 6.43k | } |
966 | 11.2k | } /* End of Bipred merge candidates */ |
967 | | |
968 | | /******************************************************/ |
969 | | /* Zero merge candidates */ |
970 | | /******************************************************/ |
971 | 179k | if(num_merge_cand < MAX_NUM_MERGE_CAND) |
972 | 177k | { |
973 | 177k | WORD32 num_ref_idx; |
974 | 177k | WORD32 zero_idx; |
975 | | |
976 | 177k | zero_idx = 0; |
977 | | |
978 | 177k | if(slice_type == PSLICE) |
979 | 167k | num_ref_idx = num_ref_idx_l0_active; |
980 | 9.87k | else |
981 | | /* Slice type B */ |
982 | 9.87k | num_ref_idx = MIN(num_ref_idx_l0_active, num_ref_idx_l1_active); |
983 | | |
984 | 339k | while(num_merge_cand < MAX_NUM_MERGE_CAND) |
985 | 317k | { |
986 | 317k | if(slice_type == PSLICE) |
987 | 306k | { |
988 | 306k | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = zero_idx; |
989 | 306k | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = -1; |
990 | 306k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1; |
991 | 306k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 0; |
992 | 306k | } |
993 | 10.7k | else /* Slice type B */ |
994 | 10.7k | { |
995 | 10.7k | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = zero_idx; |
996 | 10.7k | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = zero_idx; |
997 | 10.7k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1; |
998 | 10.7k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 1; |
999 | 10.7k | } |
1000 | | |
1001 | 317k | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv.i2_mvx = 0; |
1002 | 317k | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv.i2_mvy = 0; |
1003 | 317k | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv.i2_mvx = 0; |
1004 | 317k | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv.i2_mvy = 0; |
1005 | | |
1006 | 317k | pu1_is_top_used[num_merge_cand] = 0; |
1007 | | |
1008 | 317k | num_merge_cand++; |
1009 | 317k | zero_idx++; |
1010 | | |
1011 | | /* if all the reference pics have been added as candidates */ |
1012 | | /* the the loop shoudl break since it would add same cand again */ |
1013 | 317k | if(zero_idx == num_ref_idx) |
1014 | 155k | { |
1015 | 155k | break; |
1016 | 155k | } |
1017 | 317k | } |
1018 | 177k | } /* End of zero merge candidates */ |
1019 | | |
1020 | 179k | } /* End of merge candidate list population */ |
1021 | | |
1022 | 0 | return (num_merge_cand); |
1023 | 179k | } |