1 /******************************************************************************
2 *
3 * Copyright (C) 2022 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 *******************************************************************************
23 * @file
24 * isvce_ilp_mv.c
25 *
26 * @brief
27 * Contains functions used for deriving inter_layer MV's
28 *
29 *******************************************************************************
30 */
31 #include <stdint.h>
32 #include <math.h>
33 #include <stdbool.h>
34
35 #include "ih264_typedefs.h"
36 #include "ih264_debug.h"
37 #include "isvc_macros.h"
38 #include "isvc_defs.h"
39 #include "isvce_defs.h"
40 #include "isvce_structs.h"
41 #include "isvce_ilp_mv_private_defs.h"
42 #include "isvce_ilp_mv.h"
43 #include "isvce_ilp_mv_utils.h"
44
45 /**
46 *******************************************************************************
47 *
48 * @brief
49 * Returns size of buffers for storing ILP MV ctxt
50 *
51 * @param[in] u1_num_spatial_layers
52 * Num Spatial Layers
53 *
54 * @param[in] d_spatial_res_ratio
55 * Resolution Ratio b/w spatial layers
56 *
57 * @param[in] u4_wd
58 * Input Width
59 *
60 * @param[in] u4_ht
61 * Input Height
62 *
63 * @returns Size of buffers
64 *
65 *******************************************************************************
66 */
isvce_get_ilp_mv_ctxt_size(UWORD8 u1_num_spatial_layers,DOUBLE d_spatial_res_ratio,UWORD32 u4_wd,UWORD32 u4_ht)67 UWORD32 isvce_get_ilp_mv_ctxt_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
68 UWORD32 u4_wd, UWORD32 u4_ht)
69 {
70 UWORD32 u4_size = 0;
71
72 if(u1_num_spatial_layers > 1)
73 {
74 WORD32 i;
75
76 u4_size += MAX_PROCESS_CTXT * sizeof(svc_ilp_mv_ctxt_t);
77 u4_size += MAX_PROCESS_CTXT * sizeof(ilp_mv_state_t);
78
79 u4_size += u1_num_spatial_layers * sizeof(ilp_mv_layer_state_t);
80
81 for(i = u1_num_spatial_layers - 1; i >= 1; i--)
82 {
83 WORD32 i4_layer_luma_wd =
84 (WORD32) ((DOUBLE) u4_wd /
85 pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
86 0.99;
87 WORD32 i4_layer_luma_ht =
88 ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
89 WORD32 i4_layer_luma_mbs = (i4_layer_luma_wd / MB_SIZE) * (i4_layer_luma_ht / MB_SIZE);
90
91 u4_size += i4_layer_luma_mbs * sizeof(ilp_mv_mb_state_t);
92 }
93 }
94
95 return u4_size;
96 }
97
isvce_ref_layer_pu_and_mb_pos_init(layer_resampler_props_t * ps_layer_props,ilp_mv_mb_state_t * ps_mb_state,coordinates_t * ps_mb_pos,UWORD32 u4_ref_wd,UWORD32 u4_ref_ht,UWORD8 u1_field_pic_flag,UWORD8 u1_field_mb_flag)98 static FORCEINLINE void isvce_ref_layer_pu_and_mb_pos_init(layer_resampler_props_t *ps_layer_props,
99 ilp_mv_mb_state_t *ps_mb_state,
100 coordinates_t *ps_mb_pos,
101 UWORD32 u4_ref_wd, UWORD32 u4_ref_ht,
102 UWORD8 u1_field_pic_flag,
103 UWORD8 u1_field_mb_flag)
104 {
105 UWORD32 i, j;
106
107 coordinates_t(*aps_pu_positions)[MAX_PU_IN_MB_ROW] = ps_mb_state->as_pu_positions;
108 coordinates_t(*aps_mb_positions)[MAX_PU_IN_MB_ROW] = ps_mb_state->as_mb_positions;
109
110 for(i = 0; i < MAX_PU_IN_MB_COL; i++)
111 {
112 UWORD32 u4_y_ref16;
113
114 UWORD32 u4_yc = ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht +
115 (4 * i + 1) * (1 + u1_field_mb_flag - u1_field_pic_flag);
116
117 u4_y_ref16 =
118 (u4_yc * ps_layer_props->u4_scale_y + (1 << (ps_layer_props->u4_shift_y - 1))) >>
119 ps_layer_props->u4_shift_y;
120 u4_y_ref16 = MIN(u4_y_ref16, u4_ref_ht - 1);
121
122 for(j = 0; j < MAX_PU_IN_MB_ROW; j++)
123 {
124 UWORD32 u4_x_ref16;
125
126 UWORD32 u4_xc = ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + 4 * j + 1;
127
128 u4_x_ref16 =
129 (u4_xc * ps_layer_props->u4_scale_x + (1 << (ps_layer_props->u4_shift_x - 1))) >>
130 ps_layer_props->u4_shift_x;
131 u4_x_ref16 = MIN(u4_x_ref16, u4_ref_wd - 1);
132
133 aps_pu_positions[i][j].i4_abscissa = u4_x_ref16;
134 aps_pu_positions[i][j].i4_ordinate = u4_y_ref16;
135
136 aps_mb_positions[i][j].i4_abscissa = (u4_x_ref16 / MB_SIZE);
137 aps_mb_positions[i][j].i4_ordinate = (u4_y_ref16 / MB_SIZE);
138 }
139 }
140 }
141
isvce_ilp_mv_layer_state_init(ilp_mv_layer_state_t * ps_layer_state,DOUBLE d_spatial_res_ratio,UWORD32 u4_wd,UWORD32 u4_ht)142 static void isvce_ilp_mv_layer_state_init(ilp_mv_layer_state_t *ps_layer_state,
143 DOUBLE d_spatial_res_ratio, UWORD32 u4_wd, UWORD32 u4_ht)
144 {
145 UWORD32 i, j;
146
147 const UWORD8 u1_ref_layer_field_pic_flag = 0;
148 const UWORD8 u1_field_pic_flag = 0;
149 const UWORD8 u1_field_mb_flag = 0;
150
151 ilp_mv_mb_state_t *ps_mb_states;
152 layer_resampler_props_t *ps_layer_props;
153
154 UWORD32 u4_wd_in_mbs;
155 UWORD32 u4_ht_in_mbs;
156
157 UWORD32 u4_ref_wd = (u4_wd / d_spatial_res_ratio);
158 UWORD32 u4_ref_ht = (u4_ht / d_spatial_res_ratio) * (1 + u1_ref_layer_field_pic_flag);
159 UWORD32 u4_scaled_wd = u4_wd;
160 UWORD32 u4_scaled_ht = u4_ht * (1 + u1_field_pic_flag);
161
162 ps_mb_states = ps_layer_state->ps_mb_states;
163 ps_layer_props = ps_layer_state->ps_props;
164
165 u4_wd_in_mbs = u4_scaled_wd / ps_layer_props->u4_mb_wd;
166 u4_ht_in_mbs = u4_scaled_ht / ps_layer_props->u4_mb_ht;
167
168 ps_layer_state->s_mv_scale.i4_abscissa = ((u4_scaled_wd << 16) + (u4_ref_wd >> 1)) / u4_ref_wd;
169 ps_layer_state->s_mv_scale.i4_ordinate = ((u4_scaled_ht << 16) + (u4_ref_ht >> 1)) / u4_ref_ht;
170
171 for(i = 0; i < u4_ht_in_mbs; i++)
172 {
173 for(j = 0; j < u4_wd_in_mbs; j++)
174 {
175 coordinates_t s_mb_pos = {j, i};
176
177 isvce_ref_layer_pu_and_mb_pos_init(ps_layer_props, &ps_mb_states[j + i * u4_wd_in_mbs],
178 &s_mb_pos, u4_ref_wd, u4_ref_ht, u1_field_pic_flag,
179 u1_field_mb_flag);
180 }
181 }
182 }
183
184 /**
185 *******************************************************************************
186 *
187 * @brief
188 * Function to initialize svc ilp buffers
189 *
190 * @param[in] ps_codec
191 * Pointer to codec context
192 *
193 * @param[in] ps_mem_rec
194 * Pointer to memory allocated for input buffers
195 *
196 *******************************************************************************
197 */
isvce_ilp_mv_ctxt_init(isvce_codec_t * ps_codec,iv_mem_rec_t * ps_mem_rec)198 void isvce_ilp_mv_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
199 {
200 WORD32 i, j;
201
202 const WORD32 i4_num_proc_ctxts = sizeof(ps_codec->as_process) / sizeof(ps_codec->as_process[0]);
203 UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
204
205 if(u1_num_spatial_layers > 1)
206 {
207 ilp_mv_layer_state_t *ps_layer_states = NULL;
208 ilp_mv_mb_state_t *aps_luma_mb_states[MAX_NUM_SPATIAL_LAYERS];
209
210 DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
211 UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
212 UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
213 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
214 WORD64 i8_alloc_mem_size =
215 isvce_get_ilp_mv_ctxt_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
216
217 for(i = 0; i < i4_num_proc_ctxts; i++)
218 {
219 ilp_mv_state_t *ps_ilp_mv_state;
220 svc_ilp_mv_ctxt_t *ps_ilp_mv_ctxt;
221
222 isvce_process_ctxt_t *ps_proc = ps_codec->as_process + i;
223
224 ps_ilp_mv_ctxt = ps_proc->ps_svc_ilp_mv_ctxt = (svc_ilp_mv_ctxt_t *) pu1_buf;
225 pu1_buf += sizeof(svc_ilp_mv_ctxt_t);
226 i8_alloc_mem_size -= sizeof(svc_ilp_mv_ctxt_t);
227
228 ps_ilp_mv_ctxt->s_ilp_mv_constants.pv_state = pu1_buf;
229 ps_ilp_mv_state = (ilp_mv_state_t *) pu1_buf;
230 pu1_buf += sizeof(ilp_mv_state_t);
231 i8_alloc_mem_size -= sizeof(ilp_mv_state_t);
232
233 if(0 == i)
234 {
235 ps_ilp_mv_state->ps_layer_state = (ilp_mv_layer_state_t *) pu1_buf;
236 ps_layer_states = ps_ilp_mv_state->ps_layer_state;
237 pu1_buf += u1_num_spatial_layers * sizeof(ps_ilp_mv_state->ps_layer_state[0]);
238 i8_alloc_mem_size -=
239 u1_num_spatial_layers * sizeof(ps_ilp_mv_state->ps_layer_state[0]);
240 }
241 else
242 {
243 ps_ilp_mv_state->ps_layer_state = ps_layer_states;
244 }
245
246 ASSERT(i8_alloc_mem_size >= 0);
247
248 if(0 == i)
249 {
250 for(j = u1_num_spatial_layers - 1; j >= 1; j--)
251 {
252 ilp_mv_layer_state_t *ps_layer = &ps_ilp_mv_state->ps_layer_state[j];
253
254 WORD32 i4_layer_luma_wd =
255 ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
256 0.99;
257 WORD32 i4_layer_luma_ht =
258 ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
259 0.99;
260 WORD32 i4_layer_luma_mbs =
261 (i4_layer_luma_wd / MB_SIZE) * (i4_layer_luma_ht / MB_SIZE);
262
263 ps_layer->ps_mb_states = (ilp_mv_mb_state_t *) pu1_buf;
264 aps_luma_mb_states[j] = ps_layer->ps_mb_states;
265 pu1_buf += i4_layer_luma_mbs * sizeof(ps_layer->ps_mb_states[0]);
266 i8_alloc_mem_size -= u1_num_spatial_layers * sizeof(ps_layer->ps_mb_states[0]);
267
268 ASSERT(i8_alloc_mem_size >= 0);
269 /* Asserts below verify that
270 * 'ps_codec->s_svc_ilp_data.aps_layer_resampler_props' is initialised
271 */
272 ASSERT(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j].u4_mb_wd ==
273 MB_SIZE);
274
275 ps_layer->ps_props = &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j];
276
277 isvce_ilp_mv_layer_state_init(ps_layer, d_spatial_res_ratio, i4_layer_luma_wd,
278 i4_layer_luma_ht);
279 }
280 }
281 else
282 {
283 for(j = u1_num_spatial_layers - 1; j >= 1; j--)
284 {
285 ilp_mv_layer_state_t *ps_layer = &ps_ilp_mv_state->ps_layer_state[j];
286
287 ps_layer->ps_mb_states = aps_luma_mb_states[j];
288
289 ps_layer->ps_props = &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j];
290 }
291 }
292 }
293 }
294 else
295 {
296 for(i = 0; i < i4_num_proc_ctxts; i++)
297 {
298 ps_codec->as_process[i].ps_svc_ilp_mv_ctxt = NULL;
299 }
300 }
301 }
302
isvce_get_ilp_mvs_for_me(svc_ilp_mv_ctxt_t * ps_ilp_mv_ctxt)303 static void isvce_get_ilp_mvs_for_me(svc_ilp_mv_ctxt_t *ps_ilp_mv_ctxt)
304 {
305 svc_layer_data_t *ps_ref_layer_data;
306 ilp_mv_layer_state_t *ps_layer_state;
307 ilp_mv_mb_state_t *ps_mb_state;
308 isvce_mb_info_t *ps_ref_mb_info;
309 coordinates_t s_frame_dims;
310 coordinates_t s_frame_dims_in_mbs;
311 coordinates_t s_ref_frame_dims;
312 coordinates_t s_ref_frame_dims_in_mbs;
313
314 bool b_is_mv_non_identical;
315 WORD32 i, j, k;
316
317 ilp_mv_constants_t *ps_ilp_mv_constants = &ps_ilp_mv_ctxt->s_ilp_mv_constants;
318 ilp_mv_variables_t *ps_ilp_mv_variables = &ps_ilp_mv_ctxt->s_ilp_mv_variables;
319 ilp_mv_outputs_t *ps_ilp_mv_outputs = &ps_ilp_mv_ctxt->s_ilp_mv_outputs;
320 ilp_mv_state_t *ps_ilp_mv_state = (ilp_mv_state_t *) ps_ilp_mv_constants->pv_state;
321 svc_ilp_data_t *ps_svc_ilp_data = ps_ilp_mv_variables->ps_svc_ilp_data;
322 svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
323 coordinates_t *ps_mb_pos = &ps_ilp_mv_variables->s_mb_pos;
324 const isvce_enc_pu_mv_t s_default_mv = {{0, 0}, -1};
325
326 UWORD8 u1_spatial_layer_id = ps_ilp_mv_variables->u1_spatial_layer_id;
327 WORD32 i4_num_ilp_mvs = 0;
328
329 s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
330 s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
331 s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
332 s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
333 s_ref_frame_dims.i4_abscissa =
334 ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_width;
335 s_ref_frame_dims.i4_ordinate =
336 ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_height;
337 s_ref_frame_dims_in_mbs.i4_abscissa = s_ref_frame_dims.i4_abscissa / MB_SIZE;
338 s_ref_frame_dims_in_mbs.i4_ordinate = s_ref_frame_dims.i4_ordinate / MB_SIZE;
339
340 ps_ref_layer_data = &ps_svc_au_data->ps_svc_layer_data[u1_spatial_layer_id - 1];
341 ps_layer_state = &ps_ilp_mv_state->ps_layer_state[u1_spatial_layer_id];
342 ps_mb_state =
343 &ps_layer_state->ps_mb_states[ps_mb_pos->i4_abscissa +
344 ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa];
345
346 for(i = 0; i < MAX_PU_IN_MB_COL; i++)
347 {
348 for(j = 0; j < MAX_PU_IN_MB_ROW; j++)
349 {
350 b_is_mv_non_identical = true;
351
352 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] = s_default_mv;
353 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] = s_default_mv;
354
355 ps_ref_mb_info =
356 &ps_ref_layer_data->ps_mb_info[ps_mb_state->as_mb_positions[i][j].i4_abscissa +
357 ps_mb_state->as_mb_positions[i][j].i4_ordinate *
358 s_ref_frame_dims_in_mbs.i4_abscissa];
359
360 if((ps_ref_mb_info->u2_mb_type == P16x16) || (ps_ref_mb_info->u2_mb_type == B16x16))
361 {
362 ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] =
363 ps_ref_mb_info->u2_mb_type;
364
365 ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] =
366 ps_ref_mb_info->as_pu->u1_pred_mode;
367
368 if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L0)
369 {
370 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] =
371 ps_ref_mb_info->as_pu->as_me_info[L1];
372
373 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx =
374 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx *
375 ps_layer_state->s_mv_scale.i4_abscissa +
376 32768) >>
377 16;
378 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy =
379 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy *
380 ps_layer_state->s_mv_scale.i4_ordinate +
381 32768) >>
382 16;
383 }
384
385 if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L1)
386 {
387 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] =
388 ps_ref_mb_info->as_pu->as_me_info[L0];
389
390 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx =
391 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx *
392 ps_layer_state->s_mv_scale.i4_abscissa +
393 32768) >>
394 16;
395 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy =
396 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy *
397 ps_layer_state->s_mv_scale.i4_ordinate +
398 32768) >>
399 16;
400 }
401
402 if(i4_num_ilp_mvs == 0)
403 {
404 i4_num_ilp_mvs++;
405 }
406 else
407 {
408 for(k = i4_num_ilp_mvs - 1; k >= 0; k--)
409 {
410 if((ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[k] ==
411 ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs]) &&
412 (ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k] ==
413 ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs]) &&
414 isvce_check_identical_mv(
415 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[k],
416 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs],
417 ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k]))
418 {
419 b_is_mv_non_identical = false;
420 }
421 }
422
423 if(b_is_mv_non_identical)
424 {
425 i4_num_ilp_mvs++;
426 }
427 }
428 }
429 else
430 {
431 ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] = INVALID_MB_TYPE;
432 }
433 }
434 }
435
436 ps_ilp_mv_outputs->s_ilp_me_cands.u4_num_ilp_mvs = i4_num_ilp_mvs;
437
438 for(i = 0; i < MAX_ILP_MV_IN_NBR_RGN; i++)
439 {
440 b_is_mv_non_identical = true;
441
442 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] = s_default_mv;
443 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] = s_default_mv;
444
445 if(ps_mb_pos->i4_abscissa + gai1_nbr_ilp_mv_map[i][0] >= 0 &&
446 ps_mb_pos->i4_abscissa + gai1_nbr_ilp_mv_map[i][0] < s_frame_dims_in_mbs.i4_abscissa &&
447 ps_mb_pos->i4_ordinate + gai1_nbr_ilp_mv_map[i][1] >= 0 &&
448 ps_mb_pos->i4_ordinate + gai1_nbr_ilp_mv_map[i][1] < s_frame_dims_in_mbs.i4_ordinate)
449 {
450 ps_mb_state =
451 &ps_layer_state->ps_mb_states[(ps_mb_pos->i4_abscissa + gai1_nbr_ilp_mv_map[i][0]) +
452 (ps_mb_pos->i4_ordinate + gai1_nbr_ilp_mv_map[i][1]) *
453 s_frame_dims_in_mbs.i4_abscissa];
454
455 ps_ref_mb_info =
456 &ps_ref_layer_data->ps_mb_info[(ps_mb_state
457 ->as_mb_positions[gai1_nbr_ilp_mv_map[i][2]]
458 [gai1_nbr_ilp_mv_map[i][3]]
459 .i4_abscissa) +
460 ps_mb_state
461 ->as_mb_positions[gai1_nbr_ilp_mv_map[i][2]]
462 [gai1_nbr_ilp_mv_map[i][3]]
463 .i4_ordinate *
464 s_ref_frame_dims_in_mbs.i4_abscissa];
465
466 if((ps_ref_mb_info->u2_mb_type == P16x16) || (ps_ref_mb_info->u2_mb_type == B16x16))
467 {
468 ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] =
469 ps_ref_mb_info->u2_mb_type;
470
471 ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] =
472 ps_ref_mb_info->as_pu->u1_pred_mode;
473
474 if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L0)
475 {
476 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] =
477 ps_ref_mb_info->as_pu->as_me_info[L1];
478
479 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx =
480 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx *
481 ps_layer_state->s_mv_scale.i4_abscissa +
482 32768) >>
483 16;
484 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy =
485 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy *
486 ps_layer_state->s_mv_scale.i4_ordinate +
487 32768) >>
488 16;
489 }
490
491 if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L1)
492 {
493 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] =
494 ps_ref_mb_info->as_pu->as_me_info[L0];
495
496 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx =
497 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx *
498 ps_layer_state->s_mv_scale.i4_abscissa +
499 32768) >>
500 16;
501 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy =
502 (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy *
503 ps_layer_state->s_mv_scale.i4_ordinate +
504 32768) >>
505 16;
506 }
507
508 if(i4_num_ilp_mvs == 0)
509 {
510 i4_num_ilp_mvs++;
511 }
512 else
513 {
514 for(k = i4_num_ilp_mvs - 1; k >= 0; k--)
515 {
516 if((ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[k] ==
517 ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs]) &&
518 (ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k] ==
519 ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs]) &&
520 isvce_check_identical_mv(
521 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[k],
522 ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs],
523 ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k]))
524 b_is_mv_non_identical = false;
525 }
526
527 if(b_is_mv_non_identical)
528 {
529 i4_num_ilp_mvs++;
530 }
531 }
532 }
533 else
534 {
535 ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] = INVALID_MB_TYPE;
536 }
537 }
538 }
539
540 ps_ilp_mv_outputs->s_ilp_me_cands.u4_num_ilp_mvs_incl_nbrs = i4_num_ilp_mvs;
541 }
542
isvce_get_mb_ilp_mv(svc_ilp_mv_ctxt_t * ps_ilp_mv_ctxt)543 void isvce_get_mb_ilp_mv(svc_ilp_mv_ctxt_t *ps_ilp_mv_ctxt)
544 {
545 svc_layer_data_t *ps_ref_layer_data;
546 ilp_mv_layer_state_t *ps_layer_state;
547 ilp_mv_mb_state_t *ps_mb_state;
548 isvce_mb_info_t *ps_ref_mb_info;
549 coordinates_t s_frame_dims;
550 coordinates_t s_frame_dims_in_mbs;
551 coordinates_t s_ref_frame_dims;
552 coordinates_t s_ref_frame_dims_in_mbs;
553
554 WORD32 i, j;
555
556 ilp_mv_constants_t *ps_ilp_mv_constants = &ps_ilp_mv_ctxt->s_ilp_mv_constants;
557 ilp_mv_variables_t *ps_ilp_mv_variables = &ps_ilp_mv_ctxt->s_ilp_mv_variables;
558 ilp_mv_outputs_t *ps_ilp_mv_outputs = &ps_ilp_mv_ctxt->s_ilp_mv_outputs;
559 ilp_mv_state_t *ps_ilp_mv_state = (ilp_mv_state_t *) ps_ilp_mv_constants->pv_state;
560 svc_ilp_data_t *ps_svc_ilp_data = ps_ilp_mv_variables->ps_svc_ilp_data;
561 svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
562 coordinates_t *ps_mb_pos = &ps_ilp_mv_variables->s_mb_pos;
563 const isvce_enc_pu_mv_t s_default_mv = {{0, 0}, -1};
564
565 UWORD8 u1_spatial_layer_id = ps_ilp_mv_variables->u1_spatial_layer_id;
566
567 s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
568 s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
569 s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
570 s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
571 s_ref_frame_dims.i4_abscissa =
572 ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_width;
573 s_ref_frame_dims.i4_ordinate =
574 ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_height;
575 s_ref_frame_dims_in_mbs.i4_abscissa = s_ref_frame_dims.i4_abscissa / MB_SIZE;
576 s_ref_frame_dims_in_mbs.i4_ordinate = s_ref_frame_dims.i4_ordinate / MB_SIZE;
577
578 ps_ref_layer_data = &ps_svc_au_data->ps_svc_layer_data[u1_spatial_layer_id - 1];
579 ps_layer_state = &ps_ilp_mv_state->ps_layer_state[u1_spatial_layer_id];
580 ps_mb_state =
581 &ps_layer_state->ps_mb_states[ps_mb_pos->i4_abscissa +
582 ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa];
583
584 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0] = s_default_mv;
585 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1] = s_default_mv;
586
587 ps_ref_mb_info = &ps_ref_layer_data->ps_mb_info[ps_mb_state->as_mb_positions[0][0].i4_abscissa +
588 ps_mb_state->as_mb_positions[0][0].i4_ordinate *
589 s_ref_frame_dims_in_mbs.i4_abscissa];
590
591 if((ps_ref_mb_info->u2_mb_type == P16x16) || (ps_ref_mb_info->u2_mb_type == B16x16))
592 {
593 ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = ps_ref_mb_info->u2_mb_type;
594
595 ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] = ps_ref_mb_info->as_pu->u1_pred_mode;
596
597 if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L0)
598 {
599 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1] = ps_ref_mb_info->as_pu->as_me_info[L1];
600 }
601
602 if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L1)
603 {
604 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0] = ps_ref_mb_info->as_pu->as_me_info[L0];
605 }
606 }
607 else
608 {
609 ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = INVALID_MB_TYPE;
610 }
611
612 /* Function call to get non 16x16 ilp mvs for me candidates */
613 isvce_get_ilp_mvs_for_me(ps_ilp_mv_ctxt);
614
615 /* Encoder supports only 16x16 partition. */
616 /* The code below ensures only 16x16 ILP MV's are used */
617 for(i = 0; i < MAX_PU_IN_MB_COL; i++)
618 {
619 for(j = 0; j < MAX_PU_IN_MB_ROW; j++)
620 {
621 bool b_unsupported_mv;
622
623 ps_ref_mb_info =
624 &ps_ref_layer_data->ps_mb_info[ps_mb_state->as_mb_positions[i][j].i4_abscissa +
625 ps_mb_state->as_mb_positions[i][j].i4_ordinate *
626 s_ref_frame_dims_in_mbs.i4_abscissa];
627
628 b_unsupported_mv =
629 (ps_ref_mb_info->u2_mb_type != ps_ilp_mv_outputs->s_ilp_mv.e_mb_type) ||
630 (ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] !=
631 ps_ref_mb_info->as_pu->u1_pred_mode) ||
632 !isvce_check_identical_mv(ps_ilp_mv_outputs->s_ilp_mv.as_mv[0],
633 ps_ref_mb_info->as_pu->as_me_info,
634 ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0]);
635
636 if(b_unsupported_mv)
637 {
638 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0] = s_default_mv;
639 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1] = s_default_mv;
640 ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = INVALID_MB_TYPE;
641
642 return;
643 }
644 }
645 }
646
647 if(ps_ilp_mv_outputs->s_ilp_mv.e_mb_type != INVALID_MB_TYPE)
648 {
649 if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L0)
650 {
651 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvx =
652 (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvx *
653 ps_layer_state->s_mv_scale.i4_abscissa +
654 32768) >>
655 16;
656 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvy =
657 (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvy *
658 ps_layer_state->s_mv_scale.i4_ordinate +
659 32768) >>
660 16;
661 }
662
663 if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L1)
664 {
665 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvx =
666 (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvx *
667 ps_layer_state->s_mv_scale.i4_abscissa +
668 32768) >>
669 16;
670 ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvy =
671 (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvy *
672 ps_layer_state->s_mv_scale.i4_ordinate +
673 32768) >>
674 16;
675 }
676 }
677 else
678 {
679 ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = INVALID_MB_TYPE;
680 ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] = INVALID_PRED_MODE;
681 }
682 }
683
isvce_mvp_idx_eval(isvce_mb_info_t * ps_mb_info,isvce_enc_pu_mv_t * ps_spatial_mvp,isvce_enc_pu_mv_t * ps_ilp_mvp,UWORD8 * pu1_mvd_costs)684 void isvce_mvp_idx_eval(isvce_mb_info_t *ps_mb_info, isvce_enc_pu_mv_t *ps_spatial_mvp,
685 isvce_enc_pu_mv_t *ps_ilp_mvp, UWORD8 *pu1_mvd_costs)
686 {
687 if(USE_ILP_MV_AS_MVP && ps_ilp_mvp && !ps_mb_info->u1_is_intra &&
688 (ps_mb_info->u2_mb_type != PSKIP) && (ps_mb_info->u2_mb_type != BSKIP) &&
689 (ps_mb_info->u2_mb_type != BASE_MODE))
690 {
691 isvce_enc_pu_mv_t *ps_mv;
692 isvce_enc_pu_mv_t *aps_mvps[2];
693
694 WORD32 ai4_mvd_costs[2];
695 WORD32 i, j;
696
697 for(i = 0; i < NUM_PRED_DIRS; i++)
698 {
699 PRED_MODE_T e_pred_mode = (PRED_MODE_T) i;
700 PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
701
702 if(ps_mb_info->as_pu->u1_pred_mode != e_pred_mode)
703 {
704 ps_mv = &ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode];
705 aps_mvps[0] = &ps_spatial_mvp[e_cmpl_pred_mode];
706 aps_mvps[1] = &ps_ilp_mvp[e_cmpl_pred_mode];
707
708 for(j = 0; j < 2; j++)
709 {
710 if((aps_mvps[j]->i1_ref_idx != -1) &&
711 (!j || ((j == 1) && (ps_mv->i1_ref_idx == aps_mvps[j]->i1_ref_idx))))
712 {
713 ai4_mvd_costs[j] =
714 pu1_mvd_costs[ps_mv->s_mv.i2_mvx - aps_mvps[j]->s_mv.i2_mvx] +
715 pu1_mvd_costs[ps_mv->s_mv.i2_mvy - aps_mvps[j]->s_mv.i2_mvy];
716 }
717 else
718 {
719 ai4_mvd_costs[j] = INT32_MAX;
720 }
721 }
722
723 ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode] =
724 ai4_mvd_costs[0] > ai4_mvd_costs[1];
725 }
726 else
727 {
728 ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode] = 0;
729 }
730 }
731 }
732 else
733 {
734 ps_mb_info->as_pu->au1_mvp_idx[L0] = 0;
735 ps_mb_info->as_pu->au1_mvp_idx[L1] = 0;
736 }
737 }
738