xref: /aosp_15_r20/external/libavc/encoder/svc/isvce_ilp_mv.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
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