/src/libhevc/encoder/ihevce_mv_pred_merge.c
Line | Count | Source (jump to first uncovered line) |
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 | 2.59M | { |
139 | 2.59M | WORD32 td, tb, tx; |
140 | 2.59M | WORD32 dist_scale_factor; |
141 | 2.59M | WORD32 mvx, mvy; |
142 | | |
143 | 2.59M | td = CLIP_S8(col_poc - col_ref_poc); |
144 | 2.59M | tb = CLIP_S8(cur_poc - cur_ref_poc); |
145 | | |
146 | 2.59M | tx = (16384 + (abs(td) >> 1)) / td; |
147 | | |
148 | 2.59M | dist_scale_factor = (tb * tx + 32) >> 6; |
149 | 2.59M | dist_scale_factor = CLIP3(dist_scale_factor, -4096, 4095); |
150 | | |
151 | 2.59M | mvx = ps_mv->i2_mvx; |
152 | 2.59M | mvy = ps_mv->i2_mvy; |
153 | | |
154 | 2.59M | mvx = SIGN(dist_scale_factor * mvx) * ((abs(dist_scale_factor * mvx) + 127) >> 8); |
155 | 2.59M | mvy = SIGN(dist_scale_factor * mvy) * ((abs(dist_scale_factor * mvy) + 127) >> 8); |
156 | | |
157 | 2.59M | ps_mv->i2_mvx = CLIP_S16(mvx); |
158 | 2.59M | ps_mv->i2_mvy = CLIP_S16(mvy); |
159 | | |
160 | 2.59M | } /* 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 | 7.52M | { |
171 | 7.52M | sps_t *ps_sps = ps_mv_ctxt->ps_sps; |
172 | 7.52M | slice_header_t *ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr; |
173 | 7.52M | recon_pic_buf_t *ps_col_ref_buf; |
174 | 7.52M | WORD32 xp_col, yp_col; //In pixel unit |
175 | 7.52M | WORD32 col_ctb_x, col_ctb_y; //In CTB unit |
176 | 7.52M | mv_t as_mv_col[2]; |
177 | 7.52M | WORD32 log2_ctb_size; |
178 | 7.52M | WORD32 ctb_size; |
179 | 7.52M | WORD32 avail_col; |
180 | 7.52M | WORD32 col_ctb_idx, pu_cnt; |
181 | 7.52M | WORD32 au4_list_col[2]; |
182 | 7.52M | WORD32 num_minpu_in_ctb; |
183 | 7.52M | UWORD8 *pu1_pic_pu_map_ctb; |
184 | 7.52M | pu_col_mv_t *ps_col_mv; |
185 | 7.52M | WORD32 part_pos_y; |
186 | | |
187 | 7.52M | part_pos_y = ps_pu->b4_pos_y << 2; |
188 | | |
189 | 7.52M | log2_ctb_size = ps_sps->i1_log2_ctb_size; |
190 | 7.52M | ctb_size = (1 << log2_ctb_size); |
191 | | |
192 | 7.52M | avail_col = 1; |
193 | | |
194 | | /* Initializing reference list */ |
195 | 7.52M | if((ps_slice_hdr->i1_slice_type == BSLICE) && (ps_slice_hdr->i1_collocated_from_l0_flag == 0)) |
196 | 1.26M | { |
197 | | /* L1 */ |
198 | 1.26M | ps_col_ref_buf = ps_mv_ctxt->ps_ref_list[1][ps_slice_hdr->i1_collocated_ref_idx]; |
199 | 1.26M | } |
200 | 6.26M | else |
201 | 6.26M | { |
202 | | /* L0 */ |
203 | 6.26M | ps_col_ref_buf = ps_mv_ctxt->ps_ref_list[0][ps_slice_hdr->i1_collocated_ref_idx]; |
204 | 6.26M | } |
205 | 7.52M | num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE); |
206 | | |
207 | 7.52M | if(((part_pos_y >> log2_ctb_size) == (y_col >> log2_ctb_size)) && |
208 | 7.52M | (((x_col + (ps_mv_ctxt->i4_ctb_x << log2_ctb_size)) < ps_sps->i2_pic_width_in_luma_samples) || |
209 | 6.73M | ps_mv_ctxt->ai4_tile_xtra_ctb[2]) && |
210 | 7.52M | ((((y_col + (ps_mv_ctxt->i4_ctb_y << log2_ctb_size)) < |
211 | 6.12M | ps_sps->i2_pic_height_in_luma_samples) || |
212 | 6.12M | ps_mv_ctxt->ai4_tile_xtra_ctb[3]))) |
213 | 6.08M | { |
214 | 6.08M | xp_col = ((x_col >> 4) << 4); |
215 | 6.08M | yp_col = ((y_col >> 4) << 4); |
216 | 6.08M | col_ctb_x = ps_mv_ctxt->i4_ctb_x + (xp_col >> log2_ctb_size); |
217 | 6.08M | 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 | 6.08M | col_ctb_idx = col_ctb_x + (col_ctb_y) * (ps_sps->i2_pic_wd_in_ctb + 1); |
221 | | |
222 | 6.08M | if(xp_col == ctb_size) |
223 | 85.3k | xp_col = 0; |
224 | | |
225 | 6.08M | pu1_pic_pu_map_ctb = ps_col_ref_buf->pu1_frm_pu_map + col_ctb_idx * num_minpu_in_ctb; |
226 | | |
227 | 6.08M | 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 | 6.08M | ps_col_mv = ps_col_ref_buf->ps_frm_col_mv + |
231 | 6.08M | (col_ctb_y * (ps_sps->i2_pic_wd_in_ctb + 1) + col_ctb_x) * num_minpu_in_ctb + |
232 | 6.08M | pu_cnt; |
233 | 6.08M | } |
234 | 1.44M | else |
235 | 1.44M | avail_col = 0; |
236 | | |
237 | 7.52M | if((avail_col == 0) || (ps_col_mv->b1_intra_flag == 1) || |
238 | 7.52M | (ps_slice_hdr->i1_slice_temporal_mvp_enable_flag == 0)) |
239 | 3.25M | { |
240 | 3.25M | pu4_avail_col_flag[0] = 0; |
241 | 3.25M | pu4_avail_col_flag[1] = 0; |
242 | 3.25M | ps_mv_col[0].i2_mvx = 0; |
243 | 3.25M | ps_mv_col[0].i2_mvy = 0; |
244 | 3.25M | ps_mv_col[1].i2_mvx = 0; |
245 | 3.25M | ps_mv_col[1].i2_mvy = 0; |
246 | 3.25M | } |
247 | 4.27M | else |
248 | 4.27M | { |
249 | 4.27M | WORD32 au4_ref_idx_col[2]; |
250 | 4.27M | WORD32 pred_flag_l0, pred_flag_l1; |
251 | 4.27M | pred_flag_l0 = (ps_col_mv->b2_pred_mode != PRED_L1); |
252 | 4.27M | pred_flag_l1 = (ps_col_mv->b2_pred_mode != PRED_L0); |
253 | | |
254 | 4.27M | if(pred_flag_l0 == 0) |
255 | 136k | { |
256 | 136k | as_mv_col[0] = ps_col_mv->s_l1_mv; |
257 | 136k | au4_ref_idx_col[0] = ps_col_mv->i1_l1_ref_idx; |
258 | 136k | au4_list_col[0] = 1; /* L1 */ |
259 | | |
260 | 136k | as_mv_col[1] = ps_col_mv->s_l1_mv; |
261 | 136k | au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx; |
262 | 136k | au4_list_col[1] = 1; /* L1 */ |
263 | 136k | } |
264 | 4.13M | else |
265 | 4.13M | { |
266 | 4.13M | if(pred_flag_l1 == 0) |
267 | 3.86M | { |
268 | 3.86M | as_mv_col[0] = ps_col_mv->s_l0_mv; |
269 | 3.86M | au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx; |
270 | 3.86M | au4_list_col[0] = 0; /* L1 */ |
271 | | |
272 | 3.86M | as_mv_col[1] = ps_col_mv->s_l0_mv; |
273 | 3.86M | au4_ref_idx_col[1] = ps_col_mv->i1_l0_ref_idx; |
274 | 3.86M | au4_list_col[1] = 0; /* L1 */ |
275 | 3.86M | } |
276 | 268k | else |
277 | 268k | { |
278 | 268k | 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 | 268k | else |
289 | 268k | { |
290 | 268k | if(0 == ps_slice_hdr->i1_collocated_from_l0_flag) |
291 | 168k | { |
292 | 168k | as_mv_col[0] = ps_col_mv->s_l0_mv; |
293 | 168k | au4_ref_idx_col[0] = ps_col_mv->i1_l0_ref_idx; |
294 | | |
295 | 168k | as_mv_col[1] = ps_col_mv->s_l0_mv; |
296 | 168k | au4_ref_idx_col[1] = ps_col_mv->i1_l0_ref_idx; |
297 | 168k | } |
298 | 100k | else |
299 | 100k | { |
300 | 100k | as_mv_col[0] = ps_col_mv->s_l1_mv; |
301 | 100k | au4_ref_idx_col[0] = ps_col_mv->i1_l1_ref_idx; |
302 | | |
303 | 100k | as_mv_col[1] = ps_col_mv->s_l1_mv; |
304 | 100k | au4_ref_idx_col[1] = ps_col_mv->i1_l1_ref_idx; |
305 | 100k | } |
306 | | |
307 | 268k | au4_list_col[0] = |
308 | 268k | ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */ |
309 | 268k | au4_list_col[1] = |
310 | 268k | ps_slice_hdr->i1_collocated_from_l0_flag; /* L"collocated_from_l0_flag" */ |
311 | 268k | } |
312 | 268k | } |
313 | 4.13M | } |
314 | 4.27M | avail_col = 1; |
315 | 4.27M | { |
316 | 4.27M | WORD32 cur_poc, col_poc, col_ref_poc_l0, cur_ref_poc; |
317 | 4.27M | WORD32 col_ref_poc_l0_lt, cur_ref_poc_lt; |
318 | 4.27M | WORD32 ref_idx_l0, ref_idx_l1; |
319 | | |
320 | 4.27M | if(use_pu_ref_idx) |
321 | 1.32M | { |
322 | 1.32M | ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx; |
323 | 1.32M | ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx; |
324 | 1.32M | } |
325 | 2.94M | else |
326 | 2.94M | { |
327 | 2.94M | ref_idx_l0 = 0; |
328 | 2.94M | ref_idx_l1 = 0; |
329 | 2.94M | } |
330 | | |
331 | 4.27M | col_poc = ps_col_ref_buf->i4_poc; |
332 | 4.27M | cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt; |
333 | | |
334 | 4.27M | if(-1 != ref_idx_l0) |
335 | 4.09M | { |
336 | 4.09M | if(au4_list_col[0] == 0) |
337 | 3.90M | { |
338 | 3.90M | col_ref_poc_l0 = ps_col_ref_buf->ai4_col_l0_poc[au4_ref_idx_col[0]]; |
339 | 3.90M | col_ref_poc_l0_lt = 0; /* Encoder has only short term references */ |
340 | 3.90M | } |
341 | 198k | else |
342 | 198k | { |
343 | 198k | col_ref_poc_l0 = ps_col_ref_buf->ai4_col_l1_poc[au4_ref_idx_col[0]]; |
344 | 198k | col_ref_poc_l0_lt = 0; |
345 | 198k | } |
346 | | /* L0 collocated mv */ |
347 | 4.09M | cur_ref_poc = ps_mv_ctxt->ps_ref_list[0][ref_idx_l0]->i4_poc; |
348 | 4.09M | cur_ref_poc_lt = 0; |
349 | | |
350 | 4.09M | { |
351 | 4.09M | 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 | 4.09M | if((col_poc - col_ref_poc_l0) == (cur_poc - cur_ref_poc)) |
355 | 2.35M | { |
356 | 2.35M | ps_mv_col[0] = as_mv_col[0]; |
357 | 2.35M | } |
358 | 1.74M | else |
359 | 1.74M | { |
360 | 1.74M | ps_mv_col[0] = as_mv_col[0]; |
361 | 1.74M | if(col_ref_poc_l0 != col_poc) |
362 | 1.74M | { |
363 | 1.74M | ihevce_scale_collocated_mv( |
364 | 1.74M | (mv_t *)(&ps_mv_col[0]), |
365 | 1.74M | cur_ref_poc, |
366 | 1.74M | col_ref_poc_l0, |
367 | 1.74M | col_poc, |
368 | 1.74M | cur_poc); |
369 | 1.74M | } |
370 | 1.74M | } |
371 | 4.09M | } |
372 | 4.09M | } |
373 | 175k | else |
374 | 175k | { |
375 | 175k | pu4_avail_col_flag[0] = 0; |
376 | 175k | ps_mv_col[0].i2_mvx = 0; |
377 | 175k | ps_mv_col[0].i2_mvy = 0; |
378 | 175k | } |
379 | 4.27M | if((BSLICE == ps_slice_hdr->i1_slice_type) && (-1 != ref_idx_l1)) |
380 | 858k | { |
381 | 858k | WORD32 col_ref_poc_l1_lt, col_ref_poc_l1; |
382 | | |
383 | 858k | if(au4_list_col[1] == 0) |
384 | 688k | { |
385 | 688k | col_ref_poc_l1 = ps_col_ref_buf->ai4_col_l0_poc[au4_ref_idx_col[0]]; |
386 | 688k | col_ref_poc_l1_lt = 0; |
387 | 688k | } |
388 | 169k | else |
389 | 169k | { |
390 | 169k | col_ref_poc_l1 = ps_col_ref_buf->ai4_col_l1_poc[au4_ref_idx_col[0]]; |
391 | 169k | col_ref_poc_l1_lt = 0; |
392 | 169k | } |
393 | | |
394 | | /* L1 collocated mv */ |
395 | 858k | cur_ref_poc = ps_mv_ctxt->ps_ref_list[1][ref_idx_l1]->i4_poc; |
396 | 858k | cur_ref_poc_lt = 0; |
397 | | |
398 | 858k | { |
399 | 858k | 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 | 858k | if((col_poc - col_ref_poc_l1) == (cur_poc - cur_ref_poc)) |
403 | 7.43k | { |
404 | 7.43k | ps_mv_col[1] = as_mv_col[1]; |
405 | 7.43k | } |
406 | 850k | else |
407 | 850k | { |
408 | 850k | ps_mv_col[1] = as_mv_col[1]; |
409 | 850k | if(col_ref_poc_l1 != col_poc) |
410 | 850k | { |
411 | 850k | ihevce_scale_collocated_mv( |
412 | 850k | (mv_t *)&ps_mv_col[1], |
413 | 850k | cur_ref_poc, |
414 | 850k | col_ref_poc_l1, |
415 | 850k | col_poc, |
416 | 850k | cur_poc); |
417 | 850k | } |
418 | 850k | } |
419 | 858k | } |
420 | 858k | } /* End of if BSLICE */ |
421 | 3.41M | else |
422 | 3.41M | { |
423 | 3.41M | pu4_avail_col_flag[1] = 0; |
424 | 3.41M | } |
425 | 4.27M | } |
426 | | |
427 | 4.27M | } /* End of collocated MV calculation */ |
428 | | |
429 | 7.52M | } /* 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 | 2.83M | { |
521 | | /******************************************************/ |
522 | | /* Spatial Merge Candidates */ |
523 | | /******************************************************/ |
524 | 2.83M | WORD32 part_pos_x; |
525 | 2.83M | WORD32 part_pos_y; |
526 | 2.83M | WORD32 part_wd; |
527 | 2.83M | WORD32 part_ht; |
528 | 2.83M | WORD32 slice_type; |
529 | 2.83M | WORD32 num_ref_idx_l0_active; |
530 | 2.83M | WORD32 num_ref_idx_l1_active; |
531 | 2.83M | WORD32 num_merge_cand; |
532 | 2.83M | WORD32 log2_parallel_merge_level_minus2; |
533 | 2.83M | WORD32 n; |
534 | 2.83M | WORD8 i1_spatial_avail_flag_n[MAX_NUM_MV_NBR]; /*[A0/A1/B0/B1/B2]*/ |
535 | 2.83M | WORD32 nbr_x[MAX_NUM_MV_NBR], nbr_y[MAX_NUM_MV_NBR]; |
536 | 2.83M | UWORD8 u1_nbr_avail[MAX_NUM_MV_NBR]; |
537 | 2.83M | WORD32 merge_shift; |
538 | 2.83M | 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 | 2.83M | part_pos_x = ps_pu->b4_pos_x << 2; |
556 | 2.83M | part_pos_y = ps_pu->b4_pos_y << 2; |
557 | 2.83M | part_ht = (ps_pu->b4_ht + 1) << 2; |
558 | 2.83M | part_wd = (ps_pu->b4_wd + 1) << 2; |
559 | | |
560 | 2.83M | slice_type = ps_ctxt->ps_slice_hdr->i1_slice_type; |
561 | 2.83M | num_ref_idx_l0_active = ps_ctxt->ps_slice_hdr->i1_num_ref_idx_l0_active; |
562 | 2.83M | num_ref_idx_l1_active = ps_ctxt->ps_slice_hdr->i1_num_ref_idx_l1_active; |
563 | 2.83M | log2_parallel_merge_level_minus2 = ps_ctxt->i4_log2_parallel_merge_level_minus2; |
564 | | |
565 | | /* Assigning co-ordinates to neighbors */ |
566 | 2.83M | nbr_x[NBR_A0] = part_pos_x - 1; |
567 | 2.83M | nbr_y[NBR_A0] = part_pos_y + part_ht; /* A0 */ |
568 | | |
569 | 2.83M | nbr_x[NBR_A1] = part_pos_x - 1; |
570 | 2.83M | nbr_y[NBR_A1] = part_pos_y + part_ht - 1; /* A1 */ |
571 | | |
572 | 2.83M | nbr_x[NBR_B0] = part_pos_x + part_wd; |
573 | 2.83M | nbr_y[NBR_B0] = part_pos_y - 1; /* B0 */ |
574 | | |
575 | 2.83M | nbr_x[NBR_B1] = part_pos_x + part_wd - 1; |
576 | 2.83M | nbr_y[NBR_B1] = part_pos_y - 1; /* B1 */ |
577 | | |
578 | 2.83M | nbr_x[NBR_B2] = part_pos_x - 1; |
579 | 2.83M | nbr_y[NBR_B2] = part_pos_y - 1; /* B2 */ |
580 | | |
581 | | /* Assigning mv's */ |
582 | 2.83M | ps_nbr_mv[NBR_A0] = ps_left_nbr_4x4 + ((nbr_y[NBR_A0] - part_pos_y) >> 2) * left_nbr_4x4_strd; |
583 | 2.83M | ps_nbr_mv[NBR_A1] = ps_left_nbr_4x4 + ((nbr_y[NBR_A1] - part_pos_y) >> 2) * left_nbr_4x4_strd; |
584 | 2.83M | ps_nbr_mv[NBR_B0] = ps_top_nbr_4x4 + ((nbr_x[NBR_B0] - part_pos_x) >> 2); |
585 | 2.83M | ps_nbr_mv[NBR_B1] = ps_top_nbr_4x4 + ((nbr_x[NBR_B1] - part_pos_x) >> 2); |
586 | | |
587 | 2.83M | if(part_pos_y == 0) /* AT vertical CTB boundary */ |
588 | 774k | ps_nbr_mv[NBR_B2] = ps_top_nbr_4x4 + ((nbr_x[NBR_B2] - part_pos_x) >> 2); |
589 | 2.06M | else |
590 | 2.06M | ps_nbr_mv[NBR_B2] = ps_top_left_nbr_4x4; |
591 | | |
592 | | /* Assigning nbr availability */ |
593 | 2.83M | u1_nbr_avail[NBR_A0] = ps_avail_flags->u1_bot_lt_avail && |
594 | 2.83M | (!ps_nbr_mv[NBR_A0]->b1_intra_flag); /* A0 */ |
595 | 2.83M | u1_nbr_avail[NBR_A1] = ps_avail_flags->u1_left_avail && |
596 | 2.83M | (!ps_nbr_mv[NBR_A1]->b1_intra_flag); /* A1 */ |
597 | 2.83M | u1_nbr_avail[NBR_B0] = ps_avail_flags->u1_top_rt_avail && |
598 | 2.83M | (!ps_nbr_mv[NBR_B0]->b1_intra_flag); /* B0 */ |
599 | 2.83M | u1_nbr_avail[NBR_B1] = ps_avail_flags->u1_top_avail && |
600 | 2.83M | (!ps_nbr_mv[NBR_B1]->b1_intra_flag); /* B1 */ |
601 | 2.83M | u1_nbr_avail[NBR_B2] = ps_avail_flags->u1_top_lt_avail && |
602 | 2.83M | (!ps_nbr_mv[NBR_B2]->b1_intra_flag); /* B2 */ |
603 | | |
604 | 2.83M | merge_shift = log2_parallel_merge_level_minus2 + 2; |
605 | | |
606 | | /* Availability check */ |
607 | | /* A1 */ |
608 | 2.83M | { |
609 | 2.83M | WORD32 avail_flag; |
610 | 2.83M | avail_flag = 1; |
611 | 2.83M | n = NBR_A1; |
612 | | |
613 | | /* if at same merge level */ |
614 | 2.83M | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
615 | 2.83M | ((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 | 2.83M | if((single_mcl_flag == 0) && (part_idx == 1) && |
627 | 2.83M | ((part_mode == PART_Nx2N) || (part_mode == PART_nLx2N) || (part_mode == PART_nRx2N))) |
628 | 80.2k | { |
629 | 80.2k | u1_nbr_avail[n] = 0; |
630 | 80.2k | } |
631 | | |
632 | 2.83M | if(u1_nbr_avail[n] == 0) |
633 | 1.05M | { |
634 | 1.05M | avail_flag = 0; |
635 | 1.05M | } |
636 | 2.83M | i1_spatial_avail_flag_n[n] = avail_flag; |
637 | 2.83M | } |
638 | | /* B1 */ |
639 | 2.83M | { |
640 | 2.83M | WORD32 avail_flag; |
641 | 2.83M | avail_flag = 1; |
642 | 2.83M | n = NBR_B1; |
643 | | |
644 | | /* if at same merge level */ |
645 | 2.83M | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
646 | 2.83M | ((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 | 2.83M | if((single_mcl_flag == 0) && (part_idx == 1) && |
653 | 2.83M | ((part_mode == PART_2NxN) || (part_mode == PART_2NxnU) || (part_mode == PART_2NxnD))) |
654 | 585k | { |
655 | 585k | u1_nbr_avail[n] = 0; |
656 | 585k | } |
657 | | |
658 | 2.83M | if(u1_nbr_avail[n] == 0) |
659 | 1.43M | { |
660 | 1.43M | avail_flag = 0; |
661 | 1.43M | } |
662 | | |
663 | 2.83M | if((avail_flag == 1) && (u1_nbr_avail[NBR_A1] == 1)) |
664 | 947k | { |
665 | | /* TODO: Assumption: mvs and ref indicies in both l0 and l1*/ |
666 | | /* should match for non availability */ |
667 | 947k | WORD32 i4_pred_1, i4_pred_2; |
668 | 947k | i4_pred_1 = |
669 | 947k | (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) - |
670 | 947k | 1; |
671 | 947k | i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
672 | 947k | if(ihevce_compare_pu_mv_t( |
673 | 947k | &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
674 | 777k | { |
675 | 777k | avail_flag = 0; |
676 | 777k | } |
677 | 947k | } |
678 | 2.83M | i1_spatial_avail_flag_n[n] = avail_flag; |
679 | 2.83M | } |
680 | | |
681 | | /* B0 */ |
682 | 2.83M | { |
683 | 2.83M | WORD32 avail_flag; |
684 | 2.83M | avail_flag = 1; |
685 | 2.83M | n = NBR_B0; |
686 | | |
687 | | /* if at same merge level */ |
688 | 2.83M | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
689 | 2.83M | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
690 | 0 | { |
691 | 0 | u1_nbr_avail[n] = 0; |
692 | 0 | } |
693 | | |
694 | 2.83M | if(u1_nbr_avail[n] == 0) |
695 | 2.03M | { |
696 | 2.03M | avail_flag = 0; |
697 | 2.03M | } |
698 | | |
699 | 2.83M | if((avail_flag == 1) && (u1_nbr_avail[NBR_B1] == 1)) |
700 | 770k | { |
701 | 770k | WORD32 i4_pred_1, i4_pred_2; |
702 | 770k | i4_pred_1 = |
703 | 770k | (ps_nbr_mv[NBR_B1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_B1]->b1_pred_l1_flag << 1)) - |
704 | 770k | 1; |
705 | 770k | i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
706 | 770k | if(ihevce_compare_pu_mv_t( |
707 | 770k | &ps_nbr_mv[NBR_B1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
708 | 727k | { |
709 | 727k | avail_flag = 0; |
710 | 727k | } |
711 | 770k | } |
712 | 2.83M | i1_spatial_avail_flag_n[n] = avail_flag; |
713 | 2.83M | } |
714 | | |
715 | | /* A0 */ |
716 | 2.83M | { |
717 | 2.83M | WORD32 avail_flag; |
718 | 2.83M | avail_flag = 1; |
719 | 2.83M | n = NBR_A0; |
720 | | |
721 | | /* if at same merge level */ |
722 | 2.83M | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
723 | 2.83M | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
724 | 0 | { |
725 | 0 | u1_nbr_avail[n] = 0; |
726 | 0 | } |
727 | | |
728 | 2.83M | if(u1_nbr_avail[n] == 0) |
729 | 2.24M | { |
730 | 2.24M | avail_flag = 0; |
731 | 2.24M | } |
732 | | |
733 | 2.83M | if((avail_flag == 1) && (u1_nbr_avail[NBR_A1] == 1)) |
734 | 586k | { |
735 | 586k | WORD32 i4_pred_1, i4_pred_2; |
736 | 586k | i4_pred_1 = |
737 | 586k | (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) - |
738 | 586k | 1; |
739 | 586k | i4_pred_2 = (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
740 | 586k | if(ihevce_compare_pu_mv_t( |
741 | 586k | &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
742 | 557k | { |
743 | 557k | avail_flag = 0; |
744 | 557k | } |
745 | 586k | } |
746 | 2.83M | i1_spatial_avail_flag_n[n] = avail_flag; |
747 | 2.83M | } |
748 | | /* B2 */ |
749 | 2.83M | { |
750 | 2.83M | WORD32 avail_flag; |
751 | 2.83M | avail_flag = 1; |
752 | 2.83M | n = NBR_B2; |
753 | | |
754 | | /* if at same merge level */ |
755 | 2.83M | if((part_pos_x >> merge_shift) == (nbr_x[n] >> merge_shift) && |
756 | 2.83M | ((part_pos_y >> merge_shift) == (nbr_y[n] >> merge_shift))) |
757 | 0 | { |
758 | 0 | u1_nbr_avail[n] = 0; |
759 | 0 | } |
760 | | |
761 | 2.83M | if(u1_nbr_avail[n] == 0) |
762 | 1.46M | { |
763 | 1.46M | avail_flag = 0; |
764 | 1.46M | } |
765 | | |
766 | 2.83M | if((i1_spatial_avail_flag_n[NBR_A0] + i1_spatial_avail_flag_n[NBR_A1] + |
767 | 2.83M | i1_spatial_avail_flag_n[NBR_B0] + i1_spatial_avail_flag_n[NBR_B1]) == 4) |
768 | 625 | { |
769 | 625 | avail_flag = 0; |
770 | 625 | } |
771 | | |
772 | 2.83M | if(avail_flag == 1) |
773 | 1.37M | { |
774 | 1.37M | if(u1_nbr_avail[NBR_A1] == 1) |
775 | 1.33M | { |
776 | 1.33M | WORD32 i4_pred_1, i4_pred_2; |
777 | 1.33M | i4_pred_1 = (ps_nbr_mv[NBR_A1]->b1_pred_l0_flag | |
778 | 1.33M | (ps_nbr_mv[NBR_A1]->b1_pred_l1_flag << 1)) - |
779 | 1.33M | 1; |
780 | 1.33M | i4_pred_2 = |
781 | 1.33M | (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
782 | 1.33M | if(ihevce_compare_pu_mv_t( |
783 | 1.33M | &ps_nbr_mv[NBR_A1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
784 | 1.16M | { |
785 | 1.16M | avail_flag = 0; |
786 | 1.16M | } |
787 | 1.33M | } |
788 | 1.37M | if(u1_nbr_avail[NBR_B1] == 1) |
789 | 956k | { |
790 | 956k | WORD32 i4_pred_1, i4_pred_2; |
791 | 956k | i4_pred_1 = (ps_nbr_mv[NBR_B1]->b1_pred_l0_flag | |
792 | 956k | (ps_nbr_mv[NBR_B1]->b1_pred_l1_flag << 1)) - |
793 | 956k | 1; |
794 | 956k | i4_pred_2 = |
795 | 956k | (ps_nbr_mv[n]->b1_pred_l0_flag | (ps_nbr_mv[n]->b1_pred_l1_flag << 1)) - 1; |
796 | 956k | if(ihevce_compare_pu_mv_t( |
797 | 956k | &ps_nbr_mv[NBR_B1]->mv, &ps_nbr_mv[n]->mv, i4_pred_1, i4_pred_2)) |
798 | 893k | { |
799 | 893k | avail_flag = 0; |
800 | 893k | } |
801 | 956k | } |
802 | 1.37M | } |
803 | 2.83M | i1_spatial_avail_flag_n[n] = avail_flag; |
804 | 2.83M | } |
805 | | |
806 | | /******************************************************/ |
807 | | /* Merge Candidates List */ |
808 | | /******************************************************/ |
809 | | /* Preparing MV merge candidate list */ |
810 | 2.83M | { |
811 | 2.83M | WORD32 merge_list_priority[MAX_NUM_MERGE_CAND] = { NBR_A1, NBR_B1, NBR_B0, NBR_A0, NBR_B2 }; |
812 | | |
813 | 2.83M | num_merge_cand = 0; |
814 | 17.0M | for(n = 0; n < MAX_NUM_MERGE_CAND; n++) |
815 | 14.1M | { |
816 | 14.1M | WORD32 merge_idx; |
817 | 14.1M | merge_idx = merge_list_priority[n]; |
818 | 14.1M | if(i1_spatial_avail_flag_n[merge_idx] == 1) |
819 | 2.58M | { |
820 | 2.58M | ps_merge_cand_list[num_merge_cand].mv = ps_nbr_mv[merge_idx]->mv; |
821 | 2.58M | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = |
822 | 2.58M | (UWORD8)ps_nbr_mv[merge_idx]->b1_pred_l0_flag; |
823 | 2.58M | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = |
824 | 2.58M | (UWORD8)ps_nbr_mv[merge_idx]->b1_pred_l1_flag; |
825 | | |
826 | 2.58M | switch(merge_list_priority[n]) |
827 | 2.58M | { |
828 | 1.78M | case NBR_A1: |
829 | 1.82M | case NBR_A0: |
830 | 1.82M | { |
831 | 1.82M | pu1_is_top_used[num_merge_cand] = 0; |
832 | | |
833 | 1.82M | break; |
834 | 1.78M | } |
835 | 761k | default: |
836 | 761k | { |
837 | 761k | pu1_is_top_used[num_merge_cand] = 1; |
838 | | |
839 | 761k | break; |
840 | 1.78M | } |
841 | 2.58M | } |
842 | | |
843 | 2.58M | num_merge_cand++; |
844 | 2.58M | } |
845 | 14.1M | } |
846 | | |
847 | | /******************************************************/ |
848 | | /* Temporal Merge Candidates */ |
849 | | /******************************************************/ |
850 | 2.83M | if(num_merge_cand < MAX_NUM_MERGE_CAND) |
851 | 2.83M | { |
852 | 2.83M | mv_t as_mv_col[2]; |
853 | 2.83M | WORD32 avail_col_flag[2] = { 0 }, x_col, y_col; |
854 | 2.83M | WORD32 avail_col_l0, avail_col_l1; |
855 | | |
856 | | /* Checking Collocated MV availability at Bottom right of PU*/ |
857 | 2.83M | x_col = part_pos_x + part_wd; |
858 | 2.83M | y_col = part_pos_y + part_ht; |
859 | 2.83M | ihevce_collocated_mvp(ps_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col); |
860 | | |
861 | 2.83M | avail_col_l0 = avail_col_flag[0]; |
862 | 2.83M | avail_col_l1 = avail_col_flag[1]; |
863 | | |
864 | 2.83M | if(avail_col_l0 || avail_col_l1) |
865 | 1.24M | { |
866 | 1.24M | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = as_mv_col[0]; |
867 | 1.24M | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = as_mv_col[1]; |
868 | 1.24M | } |
869 | | |
870 | 2.83M | if(avail_col_l0 == 0 || avail_col_l1 == 0) |
871 | 2.45M | { |
872 | | /* Checking Collocated MV availability at Center of PU */ |
873 | 2.45M | x_col = part_pos_x + (part_wd >> 1); |
874 | 2.45M | y_col = part_pos_y + (part_ht >> 1); |
875 | 2.45M | ihevce_collocated_mvp(ps_ctxt, ps_pu, as_mv_col, avail_col_flag, 0, x_col, y_col); |
876 | | |
877 | 2.45M | if(avail_col_l0 == 0) |
878 | 1.59M | { |
879 | 1.59M | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = as_mv_col[0]; |
880 | 1.59M | } |
881 | 2.45M | if(avail_col_l1 == 0) |
882 | 2.45M | { |
883 | 2.45M | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = as_mv_col[1]; |
884 | 2.45M | } |
885 | | |
886 | 2.45M | avail_col_l0 |= avail_col_flag[0]; |
887 | 2.45M | avail_col_l1 |= avail_col_flag[1]; |
888 | 2.45M | } |
889 | | |
890 | 2.83M | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = 0; |
891 | 2.83M | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = 0; |
892 | 2.83M | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = avail_col_l0 ? 1 : 0; |
893 | 2.83M | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = avail_col_l1 ? 1 : 0; |
894 | | |
895 | 2.83M | if(avail_col_l0 || avail_col_l1) |
896 | 2.12M | { |
897 | 2.12M | pu1_is_top_used[num_merge_cand] = 0; |
898 | 2.12M | num_merge_cand++; |
899 | 2.12M | } |
900 | 2.83M | } |
901 | | |
902 | | /******************************************************/ |
903 | | /* Bi pred merge candidates */ |
904 | | /******************************************************/ |
905 | 2.83M | if(slice_type == BSLICE) |
906 | 700k | { |
907 | 700k | if((num_merge_cand > 1) && (num_merge_cand < MAX_NUM_MERGE_CAND)) |
908 | 540k | { |
909 | 540k | WORD32 priority_list0[12] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 }; |
910 | 540k | WORD32 priority_list1[12] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 }; |
911 | 540k | WORD32 l0_cand, l1_cand; |
912 | 540k | WORD32 bi_pred_idx = 0; |
913 | 540k | WORD32 total_bi_pred_cand = num_merge_cand * (num_merge_cand - 1); |
914 | | |
915 | 1.13M | while(bi_pred_idx < total_bi_pred_cand) |
916 | 1.13M | { |
917 | 1.13M | l0_cand = priority_list0[bi_pred_idx]; |
918 | 1.13M | l1_cand = priority_list1[bi_pred_idx]; |
919 | | |
920 | 1.13M | if((ps_merge_cand_list[l0_cand].u1_pred_flag_l0 == 1) && |
921 | 1.13M | (ps_merge_cand_list[l1_cand].u1_pred_flag_l1 == 1)) |
922 | 836k | { |
923 | 836k | WORD8 i1_l0_ref_idx, i1_l1_ref_idx; |
924 | 836k | WORD32 l0_poc, l1_poc; |
925 | 836k | mv_t s_l0_mv, s_l1_mv; |
926 | | |
927 | 836k | i1_l0_ref_idx = ps_merge_cand_list[l0_cand].mv.i1_l0_ref_idx; |
928 | 836k | i1_l1_ref_idx = ps_merge_cand_list[l1_cand].mv.i1_l1_ref_idx; |
929 | 836k | l0_poc = ps_ctxt->ps_ref_list[0][i1_l0_ref_idx]->i4_poc; |
930 | 836k | l1_poc = ps_ctxt->ps_ref_list[1][i1_l1_ref_idx]->i4_poc; |
931 | 836k | s_l0_mv = ps_merge_cand_list[l0_cand].mv.s_l0_mv; |
932 | 836k | s_l1_mv = ps_merge_cand_list[l1_cand].mv.s_l1_mv; |
933 | | |
934 | 836k | if((l0_poc != l1_poc) || (s_l0_mv.i2_mvx != s_l1_mv.i2_mvx) || |
935 | 836k | (s_l0_mv.i2_mvy != s_l1_mv.i2_mvy)) |
936 | 829k | { |
937 | 829k | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv = s_l0_mv; |
938 | 829k | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv = s_l1_mv; |
939 | 829k | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = i1_l0_ref_idx; |
940 | 829k | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = i1_l1_ref_idx; |
941 | 829k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1; |
942 | 829k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 1; |
943 | | |
944 | 829k | if(pu1_is_top_used[l0_cand] || pu1_is_top_used[l1_cand]) |
945 | 216k | { |
946 | 216k | pu1_is_top_used[num_merge_cand] = 1; |
947 | 216k | } |
948 | 612k | else |
949 | 612k | { |
950 | 612k | pu1_is_top_used[num_merge_cand] = 0; |
951 | 612k | } |
952 | | |
953 | 829k | num_merge_cand++; |
954 | 829k | } |
955 | 836k | } |
956 | | |
957 | 1.13M | bi_pred_idx++; |
958 | | |
959 | 1.13M | if((bi_pred_idx == total_bi_pred_cand) || |
960 | 1.13M | (num_merge_cand == MAX_NUM_MERGE_CAND)) |
961 | 540k | { |
962 | 540k | break; |
963 | 540k | } |
964 | 1.13M | } |
965 | 540k | } |
966 | 700k | } /* End of Bipred merge candidates */ |
967 | | |
968 | | /******************************************************/ |
969 | | /* Zero merge candidates */ |
970 | | /******************************************************/ |
971 | 2.83M | if(num_merge_cand < MAX_NUM_MERGE_CAND) |
972 | 2.79M | { |
973 | 2.79M | WORD32 num_ref_idx; |
974 | 2.79M | WORD32 zero_idx; |
975 | | |
976 | 2.79M | zero_idx = 0; |
977 | | |
978 | 2.79M | if(slice_type == PSLICE) |
979 | 2.13M | num_ref_idx = num_ref_idx_l0_active; |
980 | 653k | else |
981 | | /* Slice type B */ |
982 | 653k | num_ref_idx = MIN(num_ref_idx_l0_active, num_ref_idx_l1_active); |
983 | | |
984 | 5.87M | while(num_merge_cand < MAX_NUM_MERGE_CAND) |
985 | 5.24M | { |
986 | 5.24M | if(slice_type == PSLICE) |
987 | 4.54M | { |
988 | 4.54M | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = zero_idx; |
989 | 4.54M | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = -1; |
990 | 4.54M | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1; |
991 | 4.54M | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 0; |
992 | 4.54M | } |
993 | 702k | else /* Slice type B */ |
994 | 702k | { |
995 | 702k | ps_merge_cand_list[num_merge_cand].mv.i1_l0_ref_idx = zero_idx; |
996 | 702k | ps_merge_cand_list[num_merge_cand].mv.i1_l1_ref_idx = zero_idx; |
997 | 702k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l0 = 1; |
998 | 702k | ps_merge_cand_list[num_merge_cand].u1_pred_flag_l1 = 1; |
999 | 702k | } |
1000 | | |
1001 | 5.24M | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv.i2_mvx = 0; |
1002 | 5.24M | ps_merge_cand_list[num_merge_cand].mv.s_l0_mv.i2_mvy = 0; |
1003 | 5.24M | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv.i2_mvx = 0; |
1004 | 5.24M | ps_merge_cand_list[num_merge_cand].mv.s_l1_mv.i2_mvy = 0; |
1005 | | |
1006 | 5.24M | pu1_is_top_used[num_merge_cand] = 0; |
1007 | | |
1008 | 5.24M | num_merge_cand++; |
1009 | 5.24M | 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 | 5.24M | if(zero_idx == num_ref_idx) |
1014 | 2.15M | { |
1015 | 2.15M | break; |
1016 | 2.15M | } |
1017 | 5.24M | } |
1018 | 2.79M | } /* End of zero merge candidates */ |
1019 | | |
1020 | 2.83M | } /* End of merge candidate list population */ |
1021 | | |
1022 | 0 | return (num_merge_cand); |
1023 | 2.83M | } |