/src/libhevc/decoder/ihevcd_mv_pred.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore |
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 | | /** |
19 | | ******************************************************************************* |
20 | | * @file |
21 | | * ihevcd_mv_pred.c |
22 | | * |
23 | | * @brief |
24 | | * Contains functions for motion vector prediction |
25 | | * |
26 | | * @author |
27 | | * Ittiam |
28 | | * |
29 | | * @par List of Functions: |
30 | | * - ihevcd_scale_mv() |
31 | | * - ihevcd_mv_pred() |
32 | | * |
33 | | * @remarks |
34 | | * None |
35 | | * |
36 | | ******************************************************************************* |
37 | | */ |
38 | | /*****************************************************************************/ |
39 | | /* File Includes */ |
40 | | /*****************************************************************************/ |
41 | | |
42 | | #include <stdio.h> |
43 | | #include <stddef.h> |
44 | | #include <stdlib.h> |
45 | | #include <string.h> |
46 | | |
47 | | #include "ihevc_typedefs.h" |
48 | | #include "iv.h" |
49 | | #include "ivd.h" |
50 | | #include "ihevcd_cxa.h" |
51 | | #include "ithread.h" |
52 | | |
53 | | #include "ihevc_defs.h" |
54 | | #include "ihevc_debug.h" |
55 | | #include "ihevc_structs.h" |
56 | | #include "ihevc_macros.h" |
57 | | #include "ihevc_platform_macros.h" |
58 | | #include "ihevc_cabac_tables.h" |
59 | | #include "ihevc_disp_mgr.h" |
60 | | #include "ihevc_buf_mgr.h" |
61 | | #include "ihevc_dpb_mgr.h" |
62 | | |
63 | | #include "ihevcd_defs.h" |
64 | | #include "ihevcd_function_selector.h" |
65 | | #include "ihevcd_structs.h" |
66 | | #include "ihevcd_error.h" |
67 | | #include "ihevcd_nal.h" |
68 | | #include "ihevcd_bitstream.h" |
69 | | #include "ihevcd_fmt_conv.h" |
70 | | #include "ihevcd_job_queue.h" |
71 | | #include "ihevcd_debug.h" |
72 | | #include "ihevcd_mv_merge.h" |
73 | | |
74 | | /** |
75 | | ******************************************************************************* |
76 | | * |
77 | | * @brief Function scaling motion vector |
78 | | * |
79 | | * |
80 | | * @par Description: |
81 | | * Scales mv based on difference between current POC and current |
82 | | * reference POC and neighbour reference poc |
83 | | * |
84 | | * @param[inout] mv |
85 | | * motion vector to be scaled |
86 | | * |
87 | | * @param[in] cur_ref_poc |
88 | | * Current PU refernce pic poc |
89 | | * |
90 | | * @param[in] nbr_ref_poc |
91 | | * Neighbor PU reference pic poc |
92 | | * |
93 | | * @param[in] cur_poc |
94 | | * Picture order count of current pic |
95 | | * |
96 | | * @returns |
97 | | * None |
98 | | * |
99 | | * @remarks |
100 | | * |
101 | | ******************************************************************************* |
102 | | */ |
103 | | void ihevcd_scale_mv(mv_t *ps_mv, |
104 | | WORD32 cur_ref_poc, |
105 | | WORD32 nbr_ref_poc, |
106 | | WORD32 cur_poc) |
107 | 302k | { |
108 | 302k | WORD32 td, tb, tx; |
109 | 302k | WORD32 dist_scale_factor; |
110 | 302k | WORD32 mvx, mvy; |
111 | | |
112 | 302k | td = CLIP_S8(cur_poc - nbr_ref_poc); |
113 | 302k | tb = CLIP_S8(cur_poc - cur_ref_poc); |
114 | | |
115 | 302k | if(0 != td) |
116 | 299k | { |
117 | 299k | tx = (16384 + (abs(td) >> 1)) / td; |
118 | | |
119 | 299k | dist_scale_factor = (tb * tx + 32) >> 6; |
120 | 299k | dist_scale_factor = CLIP3(dist_scale_factor, -4096, 4095); |
121 | | |
122 | 299k | mvx = ps_mv->i2_mvx; |
123 | 299k | mvy = ps_mv->i2_mvy; |
124 | | |
125 | 299k | mvx = SIGN(dist_scale_factor * mvx) |
126 | 299k | * ((abs(dist_scale_factor * mvx) + 127) >> 8); |
127 | 299k | mvy = SIGN(dist_scale_factor * mvy) |
128 | 299k | * ((abs(dist_scale_factor * mvy) + 127) >> 8); |
129 | | |
130 | 299k | ps_mv->i2_mvx = CLIP_S16(mvx); |
131 | 299k | ps_mv->i2_mvy = CLIP_S16(mvy); |
132 | 299k | } |
133 | 302k | } |
134 | | |
135 | | /** |
136 | | ******************************************************************************* |
137 | | * |
138 | | * @brief Function scaling temporal motion vector |
139 | | * |
140 | | * |
141 | | * @par Description: |
142 | | * Scales mv based on difference between current POC and current |
143 | | * reference POC and neighbour reference poc |
144 | | * |
145 | | * @param[inout] mv |
146 | | * motion vector to be scaled |
147 | | * |
148 | | * @param[in] cur_ref_poc |
149 | | * Current PU refernce pic poc |
150 | | * |
151 | | * @param[in] nbr_ref_poc |
152 | | * Neighbor PU reference pic poc |
153 | | * |
154 | | * @param[in] cur_poc |
155 | | * Picture order count of current pic |
156 | | * |
157 | | * @returns |
158 | | * None |
159 | | * |
160 | | * @remarks |
161 | | * |
162 | | ******************************************************************************* |
163 | | */ |
164 | | void ihevcd_scale_collocated_mv(mv_t *ps_mv, |
165 | | WORD32 cur_ref_poc, |
166 | | WORD32 col_ref_poc, |
167 | | WORD32 col_poc, |
168 | | WORD32 cur_poc) |
169 | 775k | { |
170 | 775k | WORD32 td, tb, tx; |
171 | 775k | WORD32 dist_scale_factor; |
172 | 775k | WORD32 mvx, mvy; |
173 | | |
174 | 775k | td = CLIP_S8(col_poc - col_ref_poc); |
175 | 775k | tb = CLIP_S8(cur_poc - cur_ref_poc); |
176 | | |
177 | 775k | tx = (16384 + (abs(td) >> 1)) / td; |
178 | | |
179 | 775k | dist_scale_factor = (tb * tx + 32) >> 6; |
180 | 775k | dist_scale_factor = CLIP3(dist_scale_factor, -4096, 4095); |
181 | | |
182 | 775k | mvx = ps_mv->i2_mvx; |
183 | 775k | mvy = ps_mv->i2_mvy; |
184 | | |
185 | 775k | mvx = SIGN(dist_scale_factor * mvx) |
186 | 775k | * ((abs(dist_scale_factor * mvx) + 127) >> 8); |
187 | 775k | mvy = SIGN(dist_scale_factor * mvy) |
188 | 775k | * ((abs(dist_scale_factor * mvy) + 127) >> 8); |
189 | | |
190 | 775k | ps_mv->i2_mvx = CLIP_S16(mvx); |
191 | 775k | ps_mv->i2_mvy = CLIP_S16(mvy); |
192 | 775k | } |
193 | | |
194 | | #define CHECK_NBR_MV_ST(pi4_avail_flag, cur_ref_poc, u1_nbr_pred_flag, nbr_ref_poc, \ |
195 | 2.65M | ps_mv, ps_nbr_mv ) \ |
196 | 2.65M | { \ |
197 | 2.65M | if((u1_nbr_pred_flag) && (cur_ref_poc == nbr_ref_poc)) \ |
198 | 2.65M | { \ |
199 | 1.31M | *pi4_avail_flag = 1; \ |
200 | 1.31M | *ps_mv = *ps_nbr_mv; \ |
201 | 1.31M | break ; \ |
202 | 1.31M | } \ |
203 | 2.65M | } |
204 | | #define CHECK_NBR_MV_LT(pi4_avail_flag, u1_cur_ref_lt, cur_poc, cur_ref_poc, \ |
205 | | u1_nbr_pred_flag, u1_nbr_ref_lt, nbr_ref_poc, \ |
206 | 452k | ps_mv, ps_nbr_mv ) \ |
207 | 452k | { \ |
208 | 452k | WORD32 cur_lt, nbr_lt; \ |
209 | 452k | cur_lt = (LONG_TERM_REF == (u1_cur_ref_lt)); \ |
210 | 452k | nbr_lt = (LONG_TERM_REF == (u1_nbr_ref_lt)); \ |
211 | 452k | if((u1_nbr_pred_flag) && (cur_lt == nbr_lt)) \ |
212 | 452k | { \ |
213 | 304k | *pi4_avail_flag = 1; \ |
214 | 304k | *ps_mv = *ps_nbr_mv; \ |
215 | 304k | if(SHORT_TERM_REF == u1_nbr_ref_lt) \ |
216 | 304k | { \ |
217 | 302k | ihevcd_scale_mv(ps_mv, cur_ref_poc, nbr_ref_poc, \ |
218 | 302k | cur_poc); \ |
219 | 302k | } \ |
220 | 304k | break ; \ |
221 | 304k | } \ |
222 | 452k | } |
223 | | |
224 | | |
225 | | void GET_MV_NBR_ST(ref_list_t **ps_ref_pic_list, WORD32 *pi4_avail_flag, pic_buf_t *ps_cur_pic_buf_lx, pu_t **aps_nbr_pu, mv_t *ps_mv, WORD32 num_nbrs, WORD32 lx) |
226 | 1.85M | { |
227 | 1.85M | WORD32 i, nbr_pred_lx; |
228 | 1.85M | pic_buf_t *ps_nbr_pic_buf_lx; |
229 | | /* Short Term */ |
230 | | /* L0 */ |
231 | 1.85M | if(0 == lx) |
232 | 1.33M | { |
233 | 1.73M | for(i = 0; i < num_nbrs; i++) |
234 | 1.35M | { |
235 | 1.35M | nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode); |
236 | 1.35M | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf)); |
237 | 1.35M | CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx, |
238 | 1.35M | ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv); |
239 | 483k | nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode); |
240 | | |
241 | 483k | nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode); |
242 | 483k | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf)); |
243 | 483k | CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx, |
244 | 483k | ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv); |
245 | 403k | } |
246 | 1.33M | } |
247 | | /* L1 */ |
248 | 517k | else |
249 | 517k | { |
250 | 699k | for(i = 0; i < num_nbrs; i++) |
251 | 542k | { |
252 | 542k | nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode); |
253 | 542k | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf)); |
254 | 542k | CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx, |
255 | 542k | ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv); |
256 | | |
257 | 269k | nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode); |
258 | 269k | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf)); |
259 | 269k | CHECK_NBR_MV_ST(pi4_avail_flag, ps_cur_pic_buf_lx->i4_abs_poc, nbr_pred_lx, |
260 | 269k | ps_nbr_pic_buf_lx->i4_abs_poc, ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv); |
261 | 181k | } |
262 | 517k | } |
263 | 1.85M | } |
264 | | |
265 | | void GET_MV_NBR_LT(ref_list_t **ps_ref_pic_list, slice_header_t *ps_slice_hdr, WORD32 *pi4_avail_flag, pic_buf_t *ps_cur_pic_buf_lx, pu_t **aps_nbr_pu, mv_t *ps_mv, WORD32 num_nbrs, WORD32 lx) |
266 | 435k | { |
267 | 435k | WORD32 i, nbr_pred_lx; |
268 | 435k | pic_buf_t *ps_nbr_pic_buf_lx; |
269 | | /* Long Term*/ |
270 | | /* L0 */ |
271 | 435k | if(0 == lx) |
272 | 311k | { |
273 | 311k | for(i = 0; i < num_nbrs; i++) |
274 | 212k | { |
275 | 212k | nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode); |
276 | 212k | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf)); |
277 | 212k | CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc, |
278 | 212k | nbr_pred_lx, |
279 | 212k | ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc, |
280 | 212k | ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv); |
281 | | |
282 | 85.2k | nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode); |
283 | 85.2k | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf)); |
284 | 85.2k | CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc, |
285 | 85.2k | nbr_pred_lx, |
286 | 85.2k | ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc, |
287 | 85.2k | ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv); |
288 | 639 | } |
289 | 311k | } |
290 | | /* L1 */ |
291 | 124k | else |
292 | 124k | { |
293 | 124k | for(i = 0; i < num_nbrs; i++) |
294 | 92.6k | { |
295 | 92.6k | nbr_pred_lx = (PRED_L0 != aps_nbr_pu[i]->b2_pred_mode); |
296 | 92.6k | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[1][aps_nbr_pu[i]->mv.i1_l1_ref_idx].pv_pic_buf)); |
297 | 92.6k | CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc, |
298 | 92.6k | nbr_pred_lx, |
299 | 92.6k | ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc, |
300 | 92.6k | ps_mv, &aps_nbr_pu[i]->mv.s_l1_mv); |
301 | | |
302 | 62.8k | nbr_pred_lx = (PRED_L1 != aps_nbr_pu[i]->b2_pred_mode); |
303 | 62.8k | ps_nbr_pic_buf_lx = (pic_buf_t *)((ps_ref_pic_list[0][aps_nbr_pu[i]->mv.i1_l0_ref_idx].pv_pic_buf)); |
304 | 62.8k | CHECK_NBR_MV_LT(pi4_avail_flag, ps_cur_pic_buf_lx->u1_used_as_ref, ps_slice_hdr->i4_abs_pic_order_cnt, ps_cur_pic_buf_lx->i4_abs_poc, |
305 | 62.8k | nbr_pred_lx, |
306 | 62.8k | ps_nbr_pic_buf_lx->u1_used_as_ref, ps_nbr_pic_buf_lx->i4_abs_poc, |
307 | 62.8k | ps_mv, &aps_nbr_pu[i]->mv.s_l0_mv); |
308 | 142 | } |
309 | 124k | } |
310 | 435k | } |
311 | | /** |
312 | | ******************************************************************************* |
313 | | * |
314 | | * @brief |
315 | | * This function performs Motion Vector prediction and return a list of mv |
316 | | * |
317 | | * @par Description: |
318 | | * MV predictor list is computed using neighbor mvs and colocated mv |
319 | | * |
320 | | * @param[in] ps_ctxt |
321 | | * pointer to mv predictor context |
322 | | * |
323 | | * @param[in] ps_top_nbr_4x4 |
324 | | * pointer to top 4x4 nbr structure |
325 | | * |
326 | | * @param[in] ps_left_nbr_4x4 |
327 | | * pointer to left 4x4 nbr structure |
328 | | * |
329 | | * @param[in] ps_top_left_nbr_4x4 |
330 | | * pointer to top left 4x4 nbr structure |
331 | | * |
332 | | * @param[in] left_nbr_4x4_strd |
333 | | * left nbr buffer stride in terms of 4x4 units |
334 | | * |
335 | | * @param[in] ps_avail_flags |
336 | | * Neighbor availability flags container |
337 | | * |
338 | | * @param[in] ps_col_mv |
339 | | * Colocated MV pointer |
340 | | * |
341 | | * @param[in] ps_pu |
342 | | * Current Partition PU strucrture pointer |
343 | | * |
344 | | * @param[inout] ps_pred_mv |
345 | | * pointer to store predicted MV list |
346 | | * |
347 | | * @returns |
348 | | * None |
349 | | * @remarks |
350 | | * |
351 | | * |
352 | | ******************************************************************************* |
353 | | */ |
354 | | void ihevcd_mv_pred(mv_ctxt_t *ps_mv_ctxt, |
355 | | UWORD32 *pu4_top_pu_idx, |
356 | | UWORD32 *pu4_left_pu_idx, |
357 | | UWORD32 *pu4_top_left_pu_idx, |
358 | | WORD32 left_nbr_4x4_strd, |
359 | | pu_t *ps_pu, |
360 | | WORD32 lb_avail, |
361 | | WORD32 l_avail, |
362 | | WORD32 tr_avail, |
363 | | WORD32 t_avail, |
364 | | WORD32 tl_avail, |
365 | | pu_mv_t *ps_pred_mv) |
366 | 896k | { |
367 | 896k | slice_header_t *ps_slice_hdr; |
368 | 896k | ref_list_t *ps_ref_pic_list[2]; |
369 | 896k | pu_t *ps_pic_pu; |
370 | 896k | WORD32 max_l0_mvp_cand, max_l1_mvp_cand; |
371 | 896k | WORD32 l0_done_flag, l1_done_flag; |
372 | 896k | WORD32 num_l0_mvp_cand, num_l1_mvp_cand; |
373 | 896k | WORD32 is_scaled_flag_list /* Indicates whether A0 or A1 is available */; |
374 | 896k | WORD32 avail_a_flag[2]; |
375 | 896k | mv_t as_mv_a[2]; |
376 | 896k | WORD32 part_pos_x; |
377 | 896k | WORD32 part_pos_y; |
378 | 896k | WORD32 part_wd; |
379 | 896k | WORD32 part_ht; |
380 | 896k | pic_buf_t *ps_cur_pic_buf_l0, *ps_cur_pic_buf_l1; |
381 | 896k | WORD32 nbr_avail[3]; /*[A0/A1] */ /* [B0/B1/B2] */ |
382 | 896k | pu_t *aps_nbr_pu[3]; /*[A0/A1] */ /* [B0/B1/B2] */ |
383 | 896k | WORD32 num_nbrs = 0; |
384 | | |
385 | | /*******************************************/ |
386 | | /* Neighbor location: Graphical indication */ |
387 | | /* */ |
388 | | /* B2 _____________B1 B0 */ |
389 | | /* | | */ |
390 | | /* | | */ |
391 | | /* | | */ |
392 | | /* | PU ht| */ |
393 | | /* | | */ |
394 | | /* | | */ |
395 | | /* A1|______wd_______| */ |
396 | | /* A0 */ |
397 | | /* */ |
398 | | /*******************************************/ |
399 | | |
400 | 896k | ps_slice_hdr = ps_mv_ctxt->ps_slice_hdr; |
401 | 896k | ps_pic_pu = ps_mv_ctxt->ps_pic_pu; |
402 | 896k | max_l0_mvp_cand = ps_pu->b1_l0_mvp_idx + 1; |
403 | 896k | max_l1_mvp_cand = ps_pu->b1_l1_mvp_idx + 1; |
404 | 896k | num_l0_mvp_cand = 0; |
405 | 896k | num_l1_mvp_cand = 0; |
406 | | |
407 | | /* Initializing reference list */ |
408 | 896k | ps_ref_pic_list[0] = ps_slice_hdr->as_ref_pic_list0; |
409 | 896k | ps_ref_pic_list[1] = ps_slice_hdr->as_ref_pic_list1; |
410 | 896k | if(PSLICE == ps_slice_hdr->i1_slice_type) |
411 | 32.6k | ps_ref_pic_list[1] = ps_slice_hdr->as_ref_pic_list0; |
412 | | |
413 | 896k | ps_cur_pic_buf_l0 = (pic_buf_t *)((ps_ref_pic_list[0][ps_pu->mv.i1_l0_ref_idx].pv_pic_buf)); |
414 | 896k | ps_cur_pic_buf_l1 = (pic_buf_t *)((ps_ref_pic_list[1][ps_pu->mv.i1_l1_ref_idx].pv_pic_buf)); |
415 | | |
416 | 896k | is_scaled_flag_list = 0; |
417 | | |
418 | 896k | part_pos_x = ps_pu->b4_pos_x << 2; |
419 | 896k | part_pos_y = ps_pu->b4_pos_y << 2; |
420 | 896k | part_wd = (ps_pu->b4_wd + 1) << 2; |
421 | 896k | part_ht = (ps_pu->b4_ht + 1) << 2; |
422 | | |
423 | | /************************************************************/ |
424 | | /* Calculating of motion vector A from neighbors A0 and A1 */ |
425 | | /************************************************************/ |
426 | 896k | { |
427 | 896k | nbr_avail[0] = 0; |
428 | 896k | nbr_avail[1] = 0; |
429 | | |
430 | | /* Pointers to A0 and A1 */ |
431 | 896k | { |
432 | 896k | WORD32 y_a0, y_a1; |
433 | 896k | WORD32 pu_idx_a0, pu_idx_a1; |
434 | | |
435 | | /* TODO: y_a0, y_a1 is coded assuming left nbr pointer starts at PU */ |
436 | 896k | y_a0 = (part_ht >> 2); |
437 | 896k | y_a1 = ((part_ht - 1) >> 2); |
438 | | |
439 | 896k | pu_idx_a0 = *(pu4_left_pu_idx + (y_a0 * left_nbr_4x4_strd)); |
440 | 896k | pu_idx_a1 = *(pu4_left_pu_idx + (y_a1 * left_nbr_4x4_strd)); |
441 | | |
442 | 896k | if(lb_avail && (!ps_pic_pu[pu_idx_a0].b1_intra_flag)) |
443 | 278k | { |
444 | 278k | aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_a0]; |
445 | 278k | num_nbrs++; |
446 | 278k | nbr_avail[0] = 1; |
447 | 278k | } |
448 | 896k | if(l_avail && (!ps_pic_pu[pu_idx_a1].b1_intra_flag)) |
449 | 810k | { |
450 | 810k | aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_a1]; |
451 | 810k | num_nbrs++; |
452 | 810k | nbr_avail[1] = 1; |
453 | 810k | } |
454 | 896k | } |
455 | | /* Setting is scaled flag based on availability of A0 and A1 */ |
456 | 896k | if((nbr_avail[0] == 1) || (nbr_avail[1])) |
457 | 816k | { |
458 | 816k | is_scaled_flag_list = 1; |
459 | 816k | } |
460 | | |
461 | 896k | avail_a_flag[0] = 0; |
462 | 896k | avail_a_flag[1] = 0; |
463 | | |
464 | | /* L0 */ |
465 | 896k | GET_MV_NBR_ST(ps_ref_pic_list, &avail_a_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_a[0], num_nbrs, 0); |
466 | 896k | if(0 == avail_a_flag[0]) |
467 | 261k | { |
468 | 261k | GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_a_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_a[0], num_nbrs, 0); |
469 | 261k | } |
470 | | |
471 | | /* L1 */ |
472 | 896k | if(PRED_L0 != ps_pu->b2_pred_mode) |
473 | 342k | { |
474 | 342k | GET_MV_NBR_ST(ps_ref_pic_list, &avail_a_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_a[1], num_nbrs, 1); |
475 | 342k | if(0 == avail_a_flag[1]) |
476 | 107k | { |
477 | 107k | GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_a_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_a[1], num_nbrs, 1); |
478 | 107k | } |
479 | 342k | } |
480 | | |
481 | 896k | l0_done_flag = (PRED_L1 == ps_pu->b2_pred_mode); |
482 | 896k | l1_done_flag = (PRED_L0 == ps_pu->b2_pred_mode); |
483 | | |
484 | 896k | if(avail_a_flag[0]) |
485 | 815k | { |
486 | 815k | num_l0_mvp_cand++; |
487 | 815k | if(max_l0_mvp_cand == num_l0_mvp_cand) |
488 | 551k | { |
489 | 551k | ps_pred_mv->s_l0_mv = as_mv_a[0]; |
490 | 551k | l0_done_flag = 1; |
491 | 551k | } |
492 | 815k | } |
493 | 896k | if(avail_a_flag[1]) |
494 | 315k | { |
495 | 315k | num_l1_mvp_cand++; |
496 | 315k | if(max_l1_mvp_cand == num_l1_mvp_cand) |
497 | 188k | { |
498 | 188k | ps_pred_mv->s_l1_mv = as_mv_a[1]; |
499 | 188k | l1_done_flag = 1; |
500 | 188k | } |
501 | 315k | } |
502 | 896k | if(l0_done_flag && l1_done_flag) |
503 | 458k | return; |
504 | 896k | } |
505 | | |
506 | | /************************************************************/ |
507 | | /* Calculating of motion vector B from neighbors B0 and B1 */ |
508 | | /************************************************************/ |
509 | 438k | { |
510 | 438k | WORD32 avail_b_flag[2]; |
511 | 438k | mv_t as_mv_b[2]; |
512 | | |
513 | | /* Pointers to B0, B1 and B2 */ |
514 | 438k | { |
515 | 438k | WORD32 x_b0, x_b1, x_b2; |
516 | 438k | WORD32 pu_idx_b0, pu_idx_b1, pu_idx_b2; |
517 | | |
518 | | /* Relative co-ordiante of Xp,Yp w.r.t CTB start will work */ |
519 | | /* as long as minCTB = 16 */ |
520 | 438k | x_b0 = (part_pos_x + part_wd); |
521 | 438k | x_b1 = (part_pos_x + part_wd - 1); |
522 | 438k | x_b2 = (part_pos_x - 1); |
523 | | /* Getting offset back to given pointer */ |
524 | 438k | x_b0 = x_b0 - part_pos_x; |
525 | 438k | x_b1 = x_b1 - part_pos_x; |
526 | 438k | x_b2 = x_b2 - part_pos_x; |
527 | | |
528 | | /* Below derivation are based on top pointer */ |
529 | | /* is pointing first pixel of PU */ |
530 | 438k | pu_idx_b0 = *(pu4_top_pu_idx + (x_b0 >> 2)); |
531 | 438k | pu_idx_b0 = pu_idx_b0 * tr_avail; |
532 | 438k | pu_idx_b1 = *(pu4_top_pu_idx + (x_b1 >> 2)); |
533 | 438k | pu_idx_b1 = pu_idx_b1 * t_avail; |
534 | | /* At CTB boundary, use top-left passed in */ |
535 | 438k | if(part_pos_y) |
536 | 345k | { |
537 | 345k | pu_idx_b2 = *pu4_top_left_pu_idx; |
538 | 345k | } |
539 | 92.9k | else |
540 | 92.9k | { |
541 | | /* Not at CTB boundary, use top and */ |
542 | | /* add correction to go to top-left */ |
543 | 92.9k | pu_idx_b2 = *((pu4_top_pu_idx)+(x_b2 >> 2)); |
544 | 92.9k | } |
545 | 438k | pu_idx_b2 = pu_idx_b2 * tl_avail; |
546 | | |
547 | 438k | num_nbrs = 0; |
548 | 438k | nbr_avail[0] = 0; |
549 | 438k | nbr_avail[1] = 0; |
550 | 438k | nbr_avail[2] = 0; |
551 | | |
552 | 438k | if(tr_avail && (!ps_pic_pu[pu_idx_b0].b1_intra_flag)) |
553 | 209k | { |
554 | 209k | aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_b0]; |
555 | 209k | num_nbrs++; |
556 | 209k | nbr_avail[0] = 1; |
557 | 209k | } |
558 | 438k | if(t_avail && (!ps_pic_pu[pu_idx_b1].b1_intra_flag)) |
559 | 361k | { |
560 | 361k | aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_b1]; |
561 | 361k | num_nbrs++; |
562 | 361k | nbr_avail[1] = 1; |
563 | 361k | } |
564 | 438k | if(tl_avail && (!ps_pic_pu[pu_idx_b2].b1_intra_flag)) |
565 | 323k | { |
566 | 323k | aps_nbr_pu[num_nbrs] = &ps_pic_pu[pu_idx_b2]; |
567 | 323k | num_nbrs++; |
568 | 323k | nbr_avail[2] = 1; |
569 | 323k | } |
570 | 438k | } |
571 | | |
572 | | /* L0 */ |
573 | 438k | avail_b_flag[0] = 0; |
574 | 438k | avail_b_flag[1] = 0; |
575 | | |
576 | 438k | GET_MV_NBR_ST(ps_ref_pic_list, &avail_b_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_b[0], num_nbrs, 0); |
577 | | |
578 | | /* L1 */ |
579 | 438k | if(PRED_L0 != ps_pu->b2_pred_mode) |
580 | 176k | { |
581 | | /* B0 Short Term */ |
582 | 176k | GET_MV_NBR_ST(ps_ref_pic_list, &avail_b_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_b[1], num_nbrs, 1); |
583 | 176k | } |
584 | | |
585 | 438k | if(avail_b_flag[0]) |
586 | 319k | { |
587 | 319k | if(((0 == num_l0_mvp_cand) |
588 | 270k | || (as_mv_a[0].i2_mvx != as_mv_b[0].i2_mvx) |
589 | 93.2k | || (as_mv_a[0].i2_mvy != as_mv_b[0].i2_mvy))) |
590 | 256k | { |
591 | 256k | num_l0_mvp_cand++; |
592 | 256k | if(max_l0_mvp_cand == num_l0_mvp_cand) |
593 | 196k | { |
594 | 196k | ps_pred_mv->s_l0_mv = as_mv_b[0]; |
595 | 196k | l0_done_flag = 1; |
596 | 196k | } |
597 | 256k | } |
598 | 319k | } |
599 | 438k | if(avail_b_flag[1]) |
600 | 126k | { |
601 | 126k | if(((0 == num_l1_mvp_cand) |
602 | 109k | || (as_mv_a[1].i2_mvx != as_mv_b[1].i2_mvx) |
603 | 42.7k | || (as_mv_a[1].i2_mvy != as_mv_b[1].i2_mvy))) |
604 | 95.2k | { |
605 | 95.2k | num_l1_mvp_cand++; |
606 | 95.2k | if(max_l1_mvp_cand == num_l1_mvp_cand) |
607 | 79.1k | { |
608 | 79.1k | ps_pred_mv->s_l1_mv = as_mv_b[1]; |
609 | 79.1k | l1_done_flag = 1; |
610 | 79.1k | } |
611 | 95.2k | } |
612 | 126k | } |
613 | 438k | if(l0_done_flag && l1_done_flag) |
614 | 238k | return; |
615 | | |
616 | 200k | if((is_scaled_flag_list == 0) && (avail_b_flag[0] == 1)) |
617 | 18.6k | { |
618 | 18.6k | avail_a_flag[0] = 1; |
619 | 18.6k | as_mv_a[0] = as_mv_b[0]; |
620 | 18.6k | } |
621 | 200k | if((is_scaled_flag_list == 0) && (avail_b_flag[1] == 1)) |
622 | 7.31k | { |
623 | 7.31k | avail_a_flag[1] = 1; |
624 | 7.31k | as_mv_a[1] = as_mv_b[1]; |
625 | 7.31k | } |
626 | | |
627 | 200k | if(0 == is_scaled_flag_list) |
628 | 49.6k | { |
629 | 49.6k | avail_b_flag[0] = avail_b_flag[1] = 0; |
630 | | |
631 | 49.6k | GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_b_flag[0], ps_cur_pic_buf_l0, aps_nbr_pu, &as_mv_b[0], num_nbrs, 0); |
632 | | |
633 | 49.6k | if(PRED_L0 != ps_pu->b2_pred_mode) |
634 | 16.8k | { |
635 | 16.8k | GET_MV_NBR_LT(ps_ref_pic_list, ps_slice_hdr, &avail_b_flag[1], ps_cur_pic_buf_l1, aps_nbr_pu, &as_mv_b[1], num_nbrs, 1); |
636 | 16.8k | } |
637 | | |
638 | 49.6k | if(avail_b_flag[0]) |
639 | 31.1k | { |
640 | 31.1k | if(((0 == num_l0_mvp_cand) |
641 | 18.6k | || (as_mv_a[0].i2_mvx != as_mv_b[0].i2_mvx) |
642 | 17.4k | || (as_mv_a[0].i2_mvy != as_mv_b[0].i2_mvy))) |
643 | 13.8k | { |
644 | 13.8k | num_l0_mvp_cand++; |
645 | 13.8k | if(max_l0_mvp_cand == num_l0_mvp_cand) |
646 | 9.46k | { |
647 | 9.46k | ps_pred_mv->s_l0_mv = as_mv_b[0]; |
648 | 9.46k | l0_done_flag = 1; |
649 | 9.46k | } |
650 | 13.8k | } |
651 | 31.1k | } |
652 | 49.6k | if(avail_b_flag[1]) |
653 | 11.5k | { |
654 | 11.5k | if(((0 == num_l1_mvp_cand) |
655 | 7.31k | || (as_mv_a[1].i2_mvx != as_mv_b[1].i2_mvx) |
656 | 6.69k | || (as_mv_a[1].i2_mvy != as_mv_b[1].i2_mvy))) |
657 | 4.98k | { |
658 | 4.98k | num_l1_mvp_cand++; |
659 | 4.98k | if(max_l1_mvp_cand == num_l1_mvp_cand) |
660 | 3.05k | { |
661 | 3.05k | ps_pred_mv->s_l1_mv = as_mv_b[1]; |
662 | 3.05k | l1_done_flag = 1; |
663 | 3.05k | } |
664 | 4.98k | } |
665 | 11.5k | } |
666 | 49.6k | if(l0_done_flag && l1_done_flag) |
667 | 10.0k | return; |
668 | 49.6k | } |
669 | | /***********************************************************/ |
670 | | /* Collocated MV prediction */ |
671 | | /***********************************************************/ |
672 | 190k | if((2 != num_l0_mvp_cand) || (2 != num_l1_mvp_cand)) |
673 | 190k | { |
674 | 190k | mv_t as_mv_col[2], s_mv_col_l0, s_mv_col_l1; |
675 | 190k | WORD32 avail_col_flag[2] = { 0 }; |
676 | 190k | WORD32 x_col, y_col, avail_col_l0, avail_col_l1; |
677 | | // ihevcd_collocated_mvp((mv_ctxt_t *)ps_mv_ctxt,ps_pu,part_pos_x,part_pos_y,part_wd,part_ht,as_mv_col,avail_col_flag,1); |
678 | 190k | x_col = part_pos_x + part_wd; |
679 | 190k | y_col = part_pos_y + part_ht; |
680 | 190k | ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 1, x_col, y_col); |
681 | | |
682 | 190k | avail_col_l0 = avail_col_flag[0]; |
683 | 190k | avail_col_l1 = avail_col_flag[1]; |
684 | 190k | if(avail_col_l0 || avail_col_l1) |
685 | 109k | { |
686 | 109k | s_mv_col_l0 = as_mv_col[0]; |
687 | 109k | s_mv_col_l1 = as_mv_col[1]; |
688 | 109k | } |
689 | | |
690 | 190k | if(avail_col_l0 == 0 || avail_col_l1 == 0) |
691 | 81.9k | { |
692 | | /* Checking Collocated MV availability at Center of PU */ |
693 | 81.9k | x_col = part_pos_x + (part_wd >> 1); |
694 | 81.9k | y_col = part_pos_y + (part_ht >> 1); |
695 | 81.9k | ihevcd_collocated_mvp(ps_mv_ctxt, ps_pu, as_mv_col, avail_col_flag, 1, x_col, y_col); |
696 | | |
697 | 81.9k | if(avail_col_l0 == 0) |
698 | 81.0k | { |
699 | 81.0k | s_mv_col_l0 = as_mv_col[0]; |
700 | 81.0k | } |
701 | 81.9k | if(avail_col_l1 == 0) |
702 | 81.7k | { |
703 | 81.7k | s_mv_col_l1 = as_mv_col[1]; |
704 | 81.7k | } |
705 | | |
706 | 81.9k | avail_col_l0 |= avail_col_flag[0]; |
707 | 81.9k | avail_col_l1 |= avail_col_flag[1]; |
708 | 81.9k | } |
709 | | |
710 | | /* Checking if mvp index matches collocated mv */ |
711 | 190k | if(avail_col_l0) |
712 | 146k | { |
713 | 146k | if(2 != num_l0_mvp_cand) |
714 | 133k | { |
715 | 133k | num_l0_mvp_cand++; |
716 | 133k | if(max_l0_mvp_cand == num_l0_mvp_cand) |
717 | 100k | { |
718 | 100k | ps_pred_mv->s_l0_mv = s_mv_col_l0; |
719 | 100k | l0_done_flag = 1; |
720 | 100k | } |
721 | 133k | } |
722 | 146k | } |
723 | 190k | if(avail_col_l1) |
724 | 144k | { |
725 | 144k | if(2 != num_l1_mvp_cand) |
726 | 141k | { |
727 | 141k | num_l1_mvp_cand++; |
728 | 141k | if(max_l1_mvp_cand == num_l1_mvp_cand) |
729 | 134k | { |
730 | 134k | ps_pred_mv->s_l1_mv = s_mv_col_l1; |
731 | 134k | l1_done_flag = 1; |
732 | 134k | } |
733 | 141k | } |
734 | 144k | } |
735 | 190k | if(l0_done_flag && l1_done_flag) |
736 | 143k | return; |
737 | 190k | } |
738 | | |
739 | 46.4k | if(0 == l0_done_flag) |
740 | 36.7k | { |
741 | 36.7k | ps_pred_mv->s_l0_mv.i2_mvx = 0; |
742 | 36.7k | ps_pred_mv->s_l0_mv.i2_mvy = 0; |
743 | 36.7k | } |
744 | 46.4k | if(0 == l1_done_flag) |
745 | 16.4k | { |
746 | 16.4k | ps_pred_mv->s_l1_mv.i2_mvx = 0; |
747 | 16.4k | ps_pred_mv->s_l1_mv.i2_mvy = 0; |
748 | 16.4k | } |
749 | 46.4k | } |
750 | 46.4k | } |