• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ******************************************************************************
23 * \file ihevce_ipe_pass.c
24 *
25 * \brief
26 *    This file contains interface functions of Intra Prediction Estimation
27 *    module
28 * \date
29 *    18/09/2012
30 *
31 * \author
32 *    Ittiam
33 *
34 *
35 * List of Functions
36 *
37 *
38 ******************************************************************************
39 */
40 
41 /*****************************************************************************/
42 /* File Includes                                                             */
43 /*****************************************************************************/
44 /* System include files */
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <math.h>
51 
52 /* User include files */
53 #include "ihevc_typedefs.h"
54 #include "itt_video_api.h"
55 #include "ihevce_api.h"
56 
57 #include "rc_cntrl_param.h"
58 #include "rc_frame_info_collector.h"
59 #include "rc_look_ahead_params.h"
60 
61 #include "ihevc_debug.h"
62 #include "ihevc_defs.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_quant_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_multi_thrd_funcs.h"
85 #include "ihevce_me_common_defs.h"
86 #include "ihevce_had_satd.h"
87 #include "ihevce_error_codes.h"
88 #include "ihevce_bitstream.h"
89 #include "ihevce_cabac.h"
90 #include "ihevce_rdoq_macros.h"
91 #include "ihevce_function_selector.h"
92 #include "ihevce_enc_structs.h"
93 #include "ihevce_entropy_structs.h"
94 #include "ihevce_cmn_utils_instr_set_router.h"
95 #include "ihevce_enc_loop_structs.h"
96 #include "ihevce_inter_pred.h"
97 #include "ihevc_weighted_pred.h"
98 #include "ihevce_ipe_instr_set_router.h"
99 #include "ihevce_ipe_structs.h"
100 #include "ihevce_ipe_pass.h"
101 #include "ihevce_decomp_pre_intra_structs.h"
102 #include "ihevce_decomp_pre_intra_pass.h"
103 #include "ihevce_recur_bracketing.h"
104 #include "ihevce_nbr_avail.h"
105 #include "ihevce_global_tables.h"
106 #include "ihevc_resi_trans.h"
107 
108 #include "cast_types.h"
109 #include "osal.h"
110 #include "osal_defaults.h"
111 
112 /*****************************************************************************/
113 /* Global Tables                                                             */
114 /*****************************************************************************/
115 
116 /**
117 ******************************************************************************
118 * @brief  Look up table for choosing the appropriate function for
119 *         Intra prediction
120 *
121 * @remarks Same look up table enums are used for luma & chroma but each
122 *          have seperate functions implemented
123 ******************************************************************************
124 */
125 WORD32 g_i4_ipe_funcs[MAX_NUM_IP_MODES] = {
126     IPE_FUNC_MODE_0, /* Mode 0 */
127     IPE_FUNC_MODE_1, /* Mode 1 */
128     IPE_FUNC_MODE_2, /* Mode 2 */
129     IPE_FUNC_MODE_3TO9, /* Mode 3 */
130     IPE_FUNC_MODE_3TO9, /* Mode 4 */
131     IPE_FUNC_MODE_3TO9, /* Mode 5 */
132     IPE_FUNC_MODE_3TO9, /* Mode 6 */
133     IPE_FUNC_MODE_3TO9, /* Mode 7 */
134     IPE_FUNC_MODE_3TO9, /* Mode 8 */
135     IPE_FUNC_MODE_3TO9, /* Mode 9 */
136     IPE_FUNC_MODE_10, /* Mode 10 */
137     IPE_FUNC_MODE_11TO17, /* Mode 11 */
138     IPE_FUNC_MODE_11TO17, /* Mode 12 */
139     IPE_FUNC_MODE_11TO17, /* Mode 13 */
140     IPE_FUNC_MODE_11TO17, /* Mode 14 */
141     IPE_FUNC_MODE_11TO17, /* Mode 15 */
142     IPE_FUNC_MODE_11TO17, /* Mode 16 */
143     IPE_FUNC_MODE_11TO17, /* Mode 17 */
144     IPE_FUNC_MODE_18_34, /* Mode 18 */
145     IPE_FUNC_MODE_19TO25, /* Mode 19 */
146     IPE_FUNC_MODE_19TO25, /* Mode 20 */
147     IPE_FUNC_MODE_19TO25, /* Mode 21 */
148     IPE_FUNC_MODE_19TO25, /* Mode 22 */
149     IPE_FUNC_MODE_19TO25, /* Mode 23 */
150     IPE_FUNC_MODE_19TO25, /* Mode 24 */
151     IPE_FUNC_MODE_19TO25, /* Mode 25 */
152     IPE_FUNC_MODE_26, /* Mode 26 */
153     IPE_FUNC_MODE_27TO33, /* Mode 27 */
154     IPE_FUNC_MODE_27TO33, /* Mode 26 */
155     IPE_FUNC_MODE_27TO33, /* Mode 29 */
156     IPE_FUNC_MODE_27TO33, /* Mode 30 */
157     IPE_FUNC_MODE_27TO33, /* Mode 31 */
158     IPE_FUNC_MODE_27TO33, /* Mode 32 */
159     IPE_FUNC_MODE_27TO33, /* Mode 33 */
160     IPE_FUNC_MODE_18_34, /* Mode 34 */
161 };
162 
163 /**
164 ******************************************************************************
165 * @brief  Look up table for deciding whether to use original samples or
166 *         filtered reference samples for Intra prediction
167 *
168 * @remarks This table has the flags for transform size of 8, 16 and 32
169 *          Input is log2nT - 3 and intra prediction mode
170 ******************************************************************************
171 */
172 UWORD8 gau1_ipe_filter_flag[3][MAX_NUM_IP_MODES] = {
173     { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
175     { 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1,
176       1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
177     { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
178       1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }
179 };
180 
181 /*****************************************************************************/
182 /* Function Definitions                                                      */
183 /*****************************************************************************/
184 
185 /*!
186 ******************************************************************************
187 * \if Function name : ihevce_ipe_recompute_lambda_from_min_8x8_act_in_ctb \endif
188 *
189 * \brief
190 *    This function recomputes lambda using min 8x8 act in CTB
191 *
192 * \author
193 *    Ittiam
194 *
195 * \return
196 *    Nothing
197 *
198 ******************************************************************************
199 */
ihevce_ipe_recompute_lambda_from_min_8x8_act_in_ctb(ihevce_ipe_ctxt_t * ps_ctxt,ihevce_ed_ctb_l1_t * ps_ed_ctb_l1)200 void ihevce_ipe_recompute_lambda_from_min_8x8_act_in_ctb(
201     ihevce_ipe_ctxt_t *ps_ctxt, ihevce_ed_ctb_l1_t *ps_ed_ctb_l1)
202 {
203     WORD32 i4_cu_qp = 0;
204     WORD32 i4_mod_factor_num;
205 #if MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON
206     WORD32 i4_activity;
207 #endif
208     WORD32 i4_qscale;
209     WORD32 i4_curr_satd;
210     long double ld_avg_satd;
211 
212 #if MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON
213     WORD32 i4_mod_factor_denom = QP_MOD_FACTOR_DEN;
214 #endif
215 
216     if(ISLICE == ps_ctxt->i4_slice_type)
217     {
218         i4_mod_factor_num = INTRA_QP_MOD_FACTOR_NUM;
219     }
220     else
221     {
222         i4_mod_factor_num = INTER_QP_MOD_FACTOR_NUM;
223     }
224 
225 #if LAMDA_BASED_ON_QUANT
226     i4_curr_satd = ps_ed_ctb_l1->i4_32x32_satd[0][2];
227     i8_avg_satd = ps_ctxt->i8_curr_frame_32x32_avg_act[2];
228 #else
229     i4_curr_satd = ps_ed_ctb_l1->i4_32x32_satd[0][3];
230 
231     ld_avg_satd = 2.0 + ps_ctxt->ld_curr_frame_16x16_log_avg[0];
232 
233 #endif
234     if(ps_ctxt->i4_l0ipe_qp_mod)
235     {
236 #if MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON
237         i4_cu_qp = ihevce_cu_level_qp_mod(
238             ps_ctxt->i4_qscale,
239             i4_curr_satd,
240             ld_avg_satd,
241             ps_ctxt->f_strength,
242             &i4_activity,
243             &i4_qscale,
244             ps_ctxt->ps_rc_quant_ctxt);
245 #endif
246     }
247     ihevce_get_ipe_ol_cu_lambda_prms(ps_ctxt, i4_cu_qp);
248 }
249 /*!
250 ******************************************************************************
251 * \if Function name : ihevce_ipe_pass_satd \endif
252 *
253 * \brief
254 *    This function calcuates the SATD for a given size and returns the value
255 *
256 * \date
257 *    18/09/2012
258 *
259 * \author
260 *    Ittiam
261 *
262 * \return
263 *
264 * List of Functions
265 *
266 ******************************************************************************
267 */
ihevce_ipe_pass_satd(WORD16 * pi2_coeff,WORD32 coeff_stride,WORD32 trans_size)268 UWORD32 ihevce_ipe_pass_satd(WORD16 *pi2_coeff, WORD32 coeff_stride, WORD32 trans_size)
269 {
270     WORD32 i, j, satd;
271 
272     satd = 0;
273 
274     /* run a loop and find the satd by doing ABS */
275     for(i = 0; i < trans_size; i++)
276     {
277         for(j = 0; j < trans_size; j++)
278         {
279             satd += abs(*pi2_coeff++);
280         }
281         /* row level update */
282         pi2_coeff += coeff_stride - trans_size;
283     }
284 
285     {
286         WORD32 transform_shift;
287         WORD32 log2_trans_size;
288 
289         GETRANGE(log2_trans_size, trans_size);
290         log2_trans_size -= 1;
291         transform_shift = MAX_TR_DYNAMIC_RANGE - BIT_DEPTH - log2_trans_size;
292         satd >>= transform_shift;
293     }
294 
295     return (satd);
296 }
297 
298 /*!
299 ******************************************************************************
300 * \if Function name : ihevce_ipe_get_num_mem_recs \endif
301 *
302 * \brief
303 *    Number of memory records are returned for IPE module
304 *
305 *
306 * \return
307 *    None
308 *
309 * \author
310 *  Ittiam
311 *
312 *****************************************************************************
313 */
ihevce_ipe_get_num_mem_recs(void)314 WORD32 ihevce_ipe_get_num_mem_recs(void)
315 {
316     return (NUM_IPE_MEM_RECS);
317 }
318 
319 /*!
320 ******************************************************************************
321 * \if Function name : ihevce_ipe_get_mem_recs \endif
322 *
323 * \brief
324 *    Memory requirements are returned for IPE.
325 *
326 * \param[in,out]  ps_mem_tab : pointer to memory descriptors table
327 * \param[in] ps_init_prms : Create time static parameters
328 * \param[in] i4_num_proc_thrds : Number of processing threads for this module
329 * \param[in] i4_mem_space : memspace in whihc memory request should be done
330 *
331 * \return
332 *    None
333 *
334 * \author
335 *  Ittiam
336 *
337 *****************************************************************************
338 */
339 WORD32
ihevce_ipe_get_mem_recs(iv_mem_rec_t * ps_mem_tab,WORD32 i4_num_proc_thrds,WORD32 i4_mem_space)340     ihevce_ipe_get_mem_recs(iv_mem_rec_t *ps_mem_tab, WORD32 i4_num_proc_thrds, WORD32 i4_mem_space)
341 {
342     /* memories should be requested assuming worst case requirememnts */
343 
344     /* Module context structure */
345     ps_mem_tab[IPE_CTXT].i4_mem_size = sizeof(ihevce_ipe_master_ctxt_t);
346 
347     ps_mem_tab[IPE_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
348 
349     ps_mem_tab[IPE_CTXT].i4_mem_alignment = 8;
350 
351     /* Threads ctxt structure */
352     ps_mem_tab[IPE_THRDS_CTXT].i4_mem_size = i4_num_proc_thrds * sizeof(ihevce_ipe_ctxt_t);
353 
354     ps_mem_tab[IPE_THRDS_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
355 
356     ps_mem_tab[IPE_THRDS_CTXT].i4_mem_alignment = 32;
357 
358     return (NUM_IPE_MEM_RECS);
359 }
360 
361 /*!
362 ******************************************************************************
363 * \if Function name : ihevce_ipe_init \endif
364 *
365 * \brief
366 *    Intialization for IPE context state structure .
367 *
368 * \param[in] ps_mem_tab : pointer to memory descriptors table
369 * \param[in] ps_init_prms : Create time static parameters
370 *
371 * \return
372 *    None
373 *
374 * \author
375 *  Ittiam
376 *
377 *****************************************************************************
378 */
ihevce_ipe_init(iv_mem_rec_t * ps_mem_tab,ihevce_static_cfg_params_t * ps_init_prms,WORD32 i4_num_proc_thrds,WORD32 i4_ref_id,func_selector_t * ps_func_selector,rc_quant_t * ps_rc_quant_ctxt,WORD32 i4_resolution_id,UWORD8 u1_is_popcnt_available)379 void *ihevce_ipe_init(
380     iv_mem_rec_t *ps_mem_tab,
381     ihevce_static_cfg_params_t *ps_init_prms,
382     WORD32 i4_num_proc_thrds,
383     WORD32 i4_ref_id,
384     func_selector_t *ps_func_selector,
385     rc_quant_t *ps_rc_quant_ctxt,
386     WORD32 i4_resolution_id,
387     UWORD8 u1_is_popcnt_available)
388 {
389     WORD32 i4_thrds;
390     UWORD32 u4_width, u4_ctb_in_a_row;
391     //  WORD32 i4_ctr;
392     ihevce_ipe_master_ctxt_t *ps_master_ctxt;
393     ihevce_ipe_ctxt_t *ps_ctxt;
394 
395     /* IPE master state structure */
396     ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)ps_mem_tab[IPE_CTXT].pv_base;
397 
398     ps_master_ctxt->i4_num_proc_thrds = i4_num_proc_thrds;
399 
400     ps_ctxt = (ihevce_ipe_ctxt_t *)ps_mem_tab[IPE_THRDS_CTXT].pv_base;
401 
402     ps_ctxt->ps_rc_quant_ctxt = ps_rc_quant_ctxt;
403 
404     /*width of the input YUV to be encoded. */
405     u4_width = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width;
406     /*making the width a multiple of CTB size*/
407     u4_width += SET_CTB_ALIGN(
408         ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width, MAX_CTB_SIZE);
409 
410     u4_ctb_in_a_row = (u4_width / MAX_CTB_SIZE);
411 
412     /* perform all one initialisation here */
413     for(i4_thrds = 0; i4_thrds < ps_master_ctxt->i4_num_proc_thrds; i4_thrds++)
414     {
415         ps_master_ctxt->aps_ipe_thrd_ctxt[i4_thrds] = ps_ctxt;
416 
417         /* initialise the CU and TU sizes */
418         ps_ctxt->u1_ctb_size = (1 << ps_init_prms->s_config_prms.i4_max_log2_cu_size);
419         ps_ctxt->u1_min_cu_size = (1 << ps_init_prms->s_config_prms.i4_min_log2_cu_size);
420         ps_ctxt->u1_min_tu_size = (1 << ps_init_prms->s_config_prms.i4_min_log2_tu_size);
421 
422         /** Register the function selector pointer*/
423         ps_ctxt->ps_func_selector = ps_func_selector;
424 
425         /* Initiailize the encoder quality preset           */
426         /* IPE algorithm is controlled based on this preset */
427         ps_ctxt->i4_quality_preset =
428             ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_quality_preset;
429 
430         if(ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P7)
431         {
432             ps_ctxt->i4_quality_preset = IHEVCE_QUALITY_P6;
433         }
434 
435         /* initialise all the pointer to start of arrays */
436         ps_ctxt->ps_ipe_cu_tree = &ps_ctxt->as_ipe_cu_tree[0];
437 
438         /* initialize QP */
439         ps_ctxt->i1_QP =
440             ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].ai4_frame_qp[i4_ref_id];
441         ps_ctxt->u1_num_b_frames =
442             (1 << ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers) - 1;
443 
444         ps_ctxt->b_sad_type = IPE_SAD_TYPE;
445         ps_ctxt->u1_ipe_step_size = IPE_STEP_SIZE;
446 
447         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_0] =
448             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_planar_fptr;
449         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_1] =
450             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_dc_fptr;
451         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_2] =
452             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode2_fptr;
453         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_3TO9] =
454             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_3_to_9_fptr;
455         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_10] =
456             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_horz_fptr;
457         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_11TO17] =
458             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_11_to_17_fptr;
459         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_18_34] =
460             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_18_34_fptr;
461         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_19TO25] =
462             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_19_to_25_fptr;
463         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_26] =
464             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_ver_fptr;
465         ps_ctxt->apf_ipe_lum_ip[IPE_FUNC_MODE_27TO33] =
466             ps_ctxt->ps_func_selector->ihevc_intra_pred_luma_mode_27_to_33_fptr;
467 
468         /* nbr parameters initialization */
469         /* perform all one initialisation here */
470 
471         ps_ctxt->i4_nbr_map_strd = MAX_PU_IN_CTB_ROW + 1 + 8;
472 
473         ps_ctxt->pu1_ctb_nbr_map = ps_ctxt->au1_nbr_ctb_map[0];
474 
475         /* move the pointer to 1,2 location */
476         ps_ctxt->pu1_ctb_nbr_map += ps_ctxt->i4_nbr_map_strd;
477         ps_ctxt->pu1_ctb_nbr_map++;
478         ps_ctxt->i4_l0ipe_qp_mod = ps_init_prms->s_config_prms.i4_cu_level_rc & 1;
479         ps_ctxt->i4_pass = ps_init_prms->s_pass_prms.i4_pass;
480         if(ps_init_prms->s_coding_tools_prms.i4_use_default_sc_mtx == 0)
481         {
482             /* initialise the scale & rescale matricies */
483             ps_ctxt->api2_scal_mat[0] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
484             ps_ctxt->api2_scal_mat[1] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
485             ps_ctxt->api2_scal_mat[2] = (WORD16 *)&gi2_flat_scale_mat_8x8[0];
486             ps_ctxt->api2_scal_mat[3] = (WORD16 *)&gi2_flat_scale_mat_16x16[0];
487             ps_ctxt->api2_scal_mat[4] = (WORD16 *)&gi2_flat_scale_mat_32x32[0];
488             /*init for inter matrix*/
489             ps_ctxt->api2_scal_mat[5] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
490             ps_ctxt->api2_scal_mat[6] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
491             ps_ctxt->api2_scal_mat[7] = (WORD16 *)&gi2_flat_scale_mat_8x8[0];
492             ps_ctxt->api2_scal_mat[8] = (WORD16 *)&gi2_flat_scale_mat_16x16[0];
493             ps_ctxt->api2_scal_mat[9] = (WORD16 *)&gi2_flat_scale_mat_32x32[0];
494 
495             /*init for rescale matrix*/
496             ps_ctxt->api2_rescal_mat[0] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
497             ps_ctxt->api2_rescal_mat[1] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
498             ps_ctxt->api2_rescal_mat[2] = (WORD16 *)&gi2_flat_rescale_mat_8x8[0];
499             ps_ctxt->api2_rescal_mat[3] = (WORD16 *)&gi2_flat_rescale_mat_16x16[0];
500             ps_ctxt->api2_rescal_mat[4] = (WORD16 *)&gi2_flat_rescale_mat_32x32[0];
501             /*init for rescale inter matrix*/
502             ps_ctxt->api2_rescal_mat[5] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
503             ps_ctxt->api2_rescal_mat[6] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
504             ps_ctxt->api2_rescal_mat[7] = (WORD16 *)&gi2_flat_rescale_mat_8x8[0];
505             ps_ctxt->api2_rescal_mat[8] = (WORD16 *)&gi2_flat_rescale_mat_16x16[0];
506             ps_ctxt->api2_rescal_mat[9] = (WORD16 *)&gi2_flat_rescale_mat_32x32[0];
507         }
508         else if(ps_init_prms->s_coding_tools_prms.i4_use_default_sc_mtx == 1)
509         {
510             /* initialise the scale & rescale matricies */
511             ps_ctxt->api2_scal_mat[0] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
512             ps_ctxt->api2_scal_mat[1] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
513             ps_ctxt->api2_scal_mat[2] = (WORD16 *)&gi2_intra_default_scale_mat_8x8[0];
514             ps_ctxt->api2_scal_mat[3] = (WORD16 *)&gi2_intra_default_scale_mat_16x16[0];
515             ps_ctxt->api2_scal_mat[4] = (WORD16 *)&gi2_intra_default_scale_mat_32x32[0];
516             /*init for inter matrix*/
517             ps_ctxt->api2_scal_mat[5] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
518             ps_ctxt->api2_scal_mat[6] = (WORD16 *)&gi2_flat_scale_mat_4x4[0];
519             ps_ctxt->api2_scal_mat[7] = (WORD16 *)&gi2_inter_default_scale_mat_8x8[0];
520             ps_ctxt->api2_scal_mat[8] = (WORD16 *)&gi2_inter_default_scale_mat_16x16[0];
521             ps_ctxt->api2_scal_mat[9] = (WORD16 *)&gi2_inter_default_scale_mat_32x32[0];
522 
523             /*init for rescale matrix*/
524             ps_ctxt->api2_rescal_mat[0] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
525             ps_ctxt->api2_rescal_mat[1] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
526             ps_ctxt->api2_rescal_mat[2] = (WORD16 *)&gi2_intra_default_rescale_mat_8x8[0];
527             ps_ctxt->api2_rescal_mat[3] = (WORD16 *)&gi2_intra_default_rescale_mat_16x16[0];
528             ps_ctxt->api2_rescal_mat[4] = (WORD16 *)&gi2_intra_default_rescale_mat_32x32[0];
529             /*init for rescale inter matrix*/
530             ps_ctxt->api2_rescal_mat[5] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
531             ps_ctxt->api2_rescal_mat[6] = (WORD16 *)&gi2_flat_rescale_mat_4x4[0];
532             ps_ctxt->api2_rescal_mat[7] = (WORD16 *)&gi2_inter_default_rescale_mat_8x8[0];
533             ps_ctxt->api2_rescal_mat[8] = (WORD16 *)&gi2_inter_default_rescale_mat_16x16[0];
534             ps_ctxt->api2_rescal_mat[9] = (WORD16 *)&gi2_inter_default_rescale_mat_32x32[0];
535         }
536         else
537         {
538             ASSERT(0);
539         }
540 
541         ps_ctxt->u1_bit_depth = ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth;
542 
543         /**
544         * Initialize the intra prediction modes map for the CTB to INTRA_DC
545         **/
546         {
547             WORD32 row, col;
548             for(row = 0; row < (MAX_TU_ROW_IN_CTB + 1); row++)
549                 for(col = 0; col < (MAX_TU_COL_IN_CTB + 1); col++)
550                     ps_ctxt->au1_ctb_mode_map[row][col] = INTRA_DC;
551         }
552 
553         ihevce_cmn_utils_instr_set_router(
554             &ps_ctxt->s_cmn_opt_func, u1_is_popcnt_available, ps_init_prms->e_arch_type);
555 
556         ihevce_ipe_instr_set_router(
557             &ps_ctxt->s_ipe_optimised_function_list, ps_init_prms->e_arch_type);
558 
559         /* increment the thread ctxt pointer */
560         ps_ctxt++;
561     }
562 
563     /* return the handle to caller */
564     return ((void *)ps_master_ctxt);
565 }
566 /*!
567 ******************************************************************************
568 * \if Function name : ihevce_ipe_get_frame_intra_satd_cost \endif
569 *
570 * \brief
571 *    Function to export frame-level accumalated SATD .
572 *
573 * \param[in] pv_ctxt : pointer to IPE module
574 *
575 * \return
576 *    None
577 *
578 * \author
579 *  Ittiam
580 *
581 *****************************************************************************
582 */
ihevce_ipe_get_frame_intra_satd_cost(void * pv_ctxt,LWORD64 * pi8_frame_satd_by_qpmod,LWORD64 * pi8_frame_acc_mode_bits_cost,LWORD64 * pi8_frame_acc_activity_factor,LWORD64 * pi8_frame_l0_acc_satd)583 LWORD64 ihevce_ipe_get_frame_intra_satd_cost(
584     void *pv_ctxt,
585     LWORD64 *pi8_frame_satd_by_qpmod,
586     LWORD64 *pi8_frame_acc_mode_bits_cost,
587     LWORD64 *pi8_frame_acc_activity_factor,
588     LWORD64 *pi8_frame_l0_acc_satd)
589 {
590     WORD32 i4_thrds;
591 
592     ihevce_ipe_master_ctxt_t *ps_master_ctxt;
593     ihevce_ipe_ctxt_t *ps_ctxt;
594     LWORD64 i8_frame_acc_satd_cost = 0;
595     LWORD64 i8_frame_acc_satd = 0;
596     LWORD64 i8_frame_satd_by_qpmod = 0;
597     LWORD64 i8_frame_acc_mode_bits_cost = 0;
598     LWORD64 i8_frame_acc_activity_factor = 0;
599     /* IPE master state structure */
600     ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)pv_ctxt;
601 
602     /* perform all one initialisation here */
603     for(i4_thrds = 0; i4_thrds < ps_master_ctxt->i4_num_proc_thrds; i4_thrds++)
604     {
605         ps_ctxt = ps_master_ctxt->aps_ipe_thrd_ctxt[i4_thrds];
606 
607         i8_frame_acc_satd_cost += ps_ctxt->i8_frame_acc_satd_cost;
608         i8_frame_satd_by_qpmod += (ps_ctxt->i8_frame_acc_satd_by_modqp_q10 >> SATD_BY_ACT_Q_FAC);
609         i8_frame_acc_mode_bits_cost += ps_ctxt->i8_frame_acc_mode_bits_cost;
610 
611         i8_frame_acc_activity_factor += ps_ctxt->i8_frame_acc_act_factor;
612 
613         i8_frame_acc_satd += ps_ctxt->i8_frame_acc_satd;
614     }
615     *pi8_frame_satd_by_qpmod = i8_frame_satd_by_qpmod;
616 
617     *pi8_frame_acc_mode_bits_cost = i8_frame_acc_mode_bits_cost;
618 
619     *pi8_frame_acc_activity_factor = i8_frame_acc_activity_factor;
620 
621     *pi8_frame_l0_acc_satd = i8_frame_acc_satd;
622 
623     return (i8_frame_acc_satd_cost);
624 }
625 
626 /**
627 *******************************************************************************
628 * \if Function name : ihevce_intra_pred_ref_filtering \endif
629 *
630 * \brief
631 *    Intra prediction interpolation filter for ref_filtering for Encoder
632 *
633 * \par Description:
634 *    Reference DC filtering for neighboring samples dependent  on TU size and
635 *    mode  Refer to section 8.4.4.2.3 in the standard
636 *
637 * \param[in] pu1_src pointer to the source
638 * \param[out] pu1_dst pointer to the destination
639 * \param[in] nt integer Transform Block size
640 *
641 * \returns
642 *  none
643 *
644 * \author
645 *  Ittiam
646 *
647 *******************************************************************************
648 */
649 
650 #if IHEVCE_INTRA_REF_FILTERING == C
ihevce_intra_pred_ref_filtering(UWORD8 * pu1_src,WORD32 nt,UWORD8 * pu1_dst)651 void ihevce_intra_pred_ref_filtering(UWORD8 *pu1_src, WORD32 nt, UWORD8 *pu1_dst)
652 {
653     WORD32 i; /* Generic indexing variable */
654     WORD32 four_nt = 4 * nt;
655 
656     /* Extremities Untouched*/
657     pu1_dst[0] = pu1_src[0];
658     pu1_dst[4 * nt] = pu1_src[4 * nt];
659     /* Perform bilinear filtering of Reference Samples */
660     for(i = 0; i < (four_nt - 1); i++)
661     {
662         pu1_dst[i + 1] = (pu1_src[i] + 2 * pu1_src[i + 1] + pu1_src[i + 2] + 2) >> 2;
663     }
664 }
665 #endif
666 
667 /*!
668 ******************************************************************************
669 * \if Function name : ihevce_ipe_process_ctb \endif
670 *
671 * \brief
672 *    CTB level IPE function
673 *
674 * \param[in] pv_ctxt : pointer to IPE module
675 * \param[in] ps_frm_ctb_prms : CTB characteristics parameters
676 * \param[in] ps_curr_src  : pointer to input yuv buffer (row buffer)
677 * \param[out] ps_ctb_out : pointer to CTB analyse output structure (row buffer)
678 * \param[out] ps_row_cu : pointer to CU analyse output structure (row buffer)
679 *
680 * \return
681 *    None
682 *
683 * Note : This function will receive CTB pointers which may point to
684 * blocks of CTB size or smaller (at the right and bottom edges of the picture)
685 * This function recursively creates smaller square partitions and passes them
686 * on for intra processing estimation
687 *
688 * \author
689 *  Ittiam
690 *
691 *****************************************************************************
692 */
ihevce_ipe_process_ctb(ihevce_ipe_ctxt_t * ps_ctxt,frm_ctb_ctxt_t * ps_frm_ctb_prms,iv_enc_yuv_buf_t * ps_curr_src,ihevce_ipe_cu_tree_t * ps_curr_ctb_node,ipe_l0_ctb_analyse_for_me_t * ps_l0_ipe_out_ctb,ctb_analyse_t * ps_ctb_out,ihevce_ed_blk_t * ps_ed_l1_ctb,ihevce_ed_blk_t * ps_ed_l2_ctb,ihevce_ed_ctb_l1_t * ps_ed_ctb_l1)693 void ihevce_ipe_process_ctb(
694     ihevce_ipe_ctxt_t *ps_ctxt,
695     frm_ctb_ctxt_t *ps_frm_ctb_prms,
696     iv_enc_yuv_buf_t *ps_curr_src,
697     ihevce_ipe_cu_tree_t *ps_curr_ctb_node,
698     ipe_l0_ctb_analyse_for_me_t *ps_l0_ipe_out_ctb,
699     ctb_analyse_t *ps_ctb_out,
700     //cu_analyse_t      *ps_row_cu,
701     ihevce_ed_blk_t *ps_ed_l1_ctb,
702     ihevce_ed_blk_t *ps_ed_l2_ctb,
703     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1)
704 {
705     /* reset the map buffer to 0*/
706     memset(
707         &ps_ctxt->au1_nbr_ctb_map[0][0],
708         0,
709         (MAX_PU_IN_CTB_ROW + 1 + 8) * (MAX_PU_IN_CTB_ROW + 1 + 8));
710 
711     /* set the CTB neighbour availability flags */
712     ihevce_set_ctb_nbr(
713         &ps_ctxt->s_ctb_nbr_avail_flags,
714         ps_ctxt->pu1_ctb_nbr_map,
715         ps_ctxt->i4_nbr_map_strd,
716         ps_ctxt->u2_ctb_num_in_row,
717         ps_ctxt->u2_ctb_row_num,
718         ps_frm_ctb_prms);
719 
720     /* IPE cu and mode decision */
721     ihevce_bracketing_analysis(
722         ps_ctxt,
723         ps_curr_ctb_node,
724         ps_curr_src,
725         ps_ctb_out,
726         //ps_row_cu,
727         ps_ed_l1_ctb,
728         ps_ed_l2_ctb,
729         ps_ed_ctb_l1,
730         ps_l0_ipe_out_ctb);
731 
732     return;
733 }
734 
735 /*!
736 ******************************************************************************
737 * \if Function name : ihevce_ipe_process_row \endif
738 *
739 * \brief
740 *    Row level IPE function
741 *
742 * \param[in] pv_ctxt : pointer to IPE module
743 * \param[in] ps_frm_ctb_prms : CTB characteristics parameters
744 * \param[in] ps_curr_src  : pointer to input yuv buffer (row buffer)
745 * \param[out] ps_ctb_out : pointer to CTB analyse output structure (row buffer)
746 * \param[out] ps_cu_out : pointer to CU analyse output structure (row buffer)
747 *\param[out]  pi4_num_ctbs_cur_row  : pointer to store the number of ctbs processed in current row
748 *\param[in]  pi4_num_ctbs_top_row  : pointer to check the number of ctbs processed in top row
749 *
750 * \return
751 *    None
752 *
753 * Note : Currently the frame level calculations done assumes that
754 *        framewidth of the input are excat multiple of ctbsize
755 *
756 * \author
757 *  Ittiam
758 *
759 *****************************************************************************
760 */
ihevce_ipe_process_row(ihevce_ipe_ctxt_t * ps_ctxt,frm_ctb_ctxt_t * ps_frm_ctb_prms,iv_enc_yuv_buf_t * ps_curr_src,ipe_l0_ctb_analyse_for_me_t * ps_ipe_ctb_out_row,ctb_analyse_t * ps_ctb_out,ihevce_ed_blk_t * ps_ed_l1_row,ihevce_ed_blk_t * ps_ed_l2_row,ihevce_ed_ctb_l1_t * ps_ed_ctb_l1_row,WORD32 blk_inc_ctb_l1,WORD32 blk_inc_ctb_l2)761 void ihevce_ipe_process_row(
762     ihevce_ipe_ctxt_t *ps_ctxt,
763     frm_ctb_ctxt_t *ps_frm_ctb_prms,
764     iv_enc_yuv_buf_t *ps_curr_src,
765     ipe_l0_ctb_analyse_for_me_t *ps_ipe_ctb_out_row,
766     ctb_analyse_t *ps_ctb_out,
767     //cu_analyse_t   *ps_row_cu,
768     ihevce_ed_blk_t *ps_ed_l1_row,
769     ihevce_ed_blk_t *ps_ed_l2_row,
770     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1_row,
771     WORD32 blk_inc_ctb_l1,
772     WORD32 blk_inc_ctb_l2)
773 {
774     /* local variables */
775     UWORD16 ctb_ctr;
776     iv_enc_yuv_buf_t s_curr_src_bufs;
777     ipe_l0_ctb_analyse_for_me_t *ps_l0_ipe_out_ctb;
778     UWORD16 u2_pic_wdt;
779     UWORD16 u2_pic_hgt;
780     ihevce_ed_blk_t *ps_ed_l1_ctb;
781     ihevce_ed_blk_t *ps_ed_l2_ctb;
782     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1;
783 
784     UWORD8 u1_ctb_size;
785 
786     u2_pic_wdt = ps_frm_ctb_prms->i4_cu_aligned_pic_wd;
787     u2_pic_hgt = ps_frm_ctb_prms->i4_cu_aligned_pic_ht;
788 
789     u1_ctb_size = ps_ctxt->u1_ctb_size;
790 
791     /* ----------------------------------------------------- */
792     /* store the stride and dimensions of source             */
793     /* buffer pointers will be over written at every CTB row */
794     /* ----------------------------------------------------- */
795     memcpy(&s_curr_src_bufs, ps_curr_src, sizeof(iv_enc_yuv_buf_t));
796     ps_l0_ipe_out_ctb = ps_ipe_ctb_out_row;
797 
798     /* --------- Loop over all the CTBs in a row --------------- */
799     for(ctb_ctr = 0; ctb_ctr < ps_frm_ctb_prms->i4_num_ctbs_horz; ctb_ctr++)
800     {
801         //UWORD8            num_cus_in_ctb;
802 
803         UWORD8 *pu1_tmp;
804 
805         /* Create pointer to ctb node */
806         ihevce_ipe_cu_tree_t *ps_ctb_node;
807 
808         WORD32 nbr_flags;
809 
810         WORD32 row;
811         /* luma src */
812         pu1_tmp = (UWORD8 *)ps_curr_src->pv_y_buf;
813         pu1_tmp += (ctb_ctr * ps_frm_ctb_prms->i4_ctb_size);
814 
815         s_curr_src_bufs.pv_y_buf = pu1_tmp;
816 
817         /* Cb & CR pixel interleaved src */
818         pu1_tmp = (UWORD8 *)ps_curr_src->pv_u_buf;
819         pu1_tmp += (ctb_ctr * (ps_frm_ctb_prms->i4_ctb_size >> 1));
820 
821         s_curr_src_bufs.pv_u_buf = pu1_tmp;
822 
823         /* Store the number of current ctb within row in the context */
824         ps_ctxt->u2_ctb_num_in_row = ctb_ctr;
825 
826         /* Initialize number of coding units in ctb to 0 */
827         ps_ctb_out->u1_num_cus_in_ctb = 0;
828         /* Initialize split flag to 0 - No partition  */
829         ps_ctb_out->u4_cu_split_flags = 0;
830         /* store the cu pointer for current ctb out */
831         //ps_ctb_out->ps_coding_units_in_ctb = ps_row_cu;
832 
833         /* Initialize the CTB parameters at the root node level */
834         ps_ctb_node = ps_ctxt->ps_ipe_cu_tree;
835         ps_ctb_node->ps_parent = NULL;
836         ps_ctb_node->u1_depth = 0;
837         ps_ctb_node->u1_cu_size = u1_ctb_size;
838         ps_ctb_node->u2_x0 = 0;
839         ps_ctb_node->u2_y0 = 0;
840 
841         ps_ctb_node->u2_orig_x = ctb_ctr * ps_ctb_node->u1_cu_size;
842         ps_ctb_node->u2_orig_y = ps_ctxt->u2_ctb_row_num * ps_ctb_node->u1_cu_size;
843 
844         ps_ctb_node->u1_width = u1_ctb_size;
845         ps_ctb_node->u1_height = u1_ctb_size;
846 #if !(PIC_ALIGN_CTB_SIZE)
847         if(ps_ctxt->u2_ctb_num_in_row == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
848         {
849             ps_ctb_node->u1_width = u2_pic_wdt - (ps_ctxt->u2_ctb_num_in_row) * (u1_ctb_size);
850         }
851         if(ps_ctxt->u2_ctb_row_num == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
852         {
853             ps_ctb_node->u1_height = u2_pic_hgt - (ps_ctxt->u2_ctb_row_num) * (u1_ctb_size);
854         }
855 #endif
856 
857         switch(ps_ctb_node->u1_cu_size)
858         {
859         case 64:
860             ps_ctb_node->u1_log2_nt = 6;
861             ps_ctb_node->u1_part_flag_pos = 0;
862             break;
863         case 32:
864             ps_ctb_node->u1_log2_nt = 5;
865             ps_ctb_node->u1_part_flag_pos = 4;
866             break;
867         case 16:
868             ps_ctb_node->u1_log2_nt = 4;
869             ps_ctb_node->u1_part_flag_pos = 8;
870             break;
871         }
872 
873         /* Set neighbor flags for the CTB */
874         nbr_flags = 0;
875 
876         if(ps_ctxt->u2_ctb_num_in_row != 0)
877         {
878             nbr_flags |= LEFT_FLAG; /* Set Left Flag if not in first column */
879             ps_ctb_node->u1_num_left_avail = ((u2_pic_hgt - ps_ctb_node->u2_orig_y) >= u1_ctb_size)
880                                                  ? u1_ctb_size
881                                                  : u2_pic_hgt - ps_ctb_node->u2_orig_y;
882         }
883         else
884         {
885             ps_ctb_node->u1_num_left_avail = 0;
886         }
887 
888         if((ps_ctxt->u2_ctb_num_in_row != 0) && (ps_ctxt->u2_ctb_row_num != 0))
889             nbr_flags |= TOP_LEFT_FLAG; /* Set Top-Left Flag if not in first row or first column */
890 
891         if(ps_ctxt->u2_ctb_row_num != 0)
892         {
893             nbr_flags |= TOP_FLAG; /* Set Top Flag if not in first row */
894             ps_ctb_node->u1_num_top_avail = ((u2_pic_wdt - ps_ctb_node->u2_orig_x) >= u1_ctb_size)
895                                                 ? u1_ctb_size
896                                                 : u2_pic_wdt - ps_ctb_node->u2_orig_x;
897         }
898         else
899         {
900             ps_ctb_node->u1_num_top_avail = 0;
901         }
902 
903         if(ps_ctxt->u2_ctb_row_num != 0)
904         {
905             if(ps_ctxt->u2_ctb_num_in_row == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
906                 ps_ctb_node->u1_num_top_right_avail = 0;
907             else
908             {
909                 ps_ctb_node->u1_num_top_right_avail =
910                     ((u2_pic_wdt - ps_ctb_node->u2_orig_x - u1_ctb_size) >= u1_ctb_size)
911                         ? u1_ctb_size
912                         : u2_pic_wdt - ps_ctb_node->u2_orig_x - u1_ctb_size;
913                 nbr_flags |=
914                     TOP_RIGHT_FLAG; /* Set Top-Right Flag if not in first row or last column*/
915             }
916         }
917         else
918         {
919             ps_ctb_node->u1_num_top_right_avail = 0;
920         }
921 
922         ps_ctb_node->u1_num_bottom_left_avail = 0;
923 
924         ps_ctb_node->i4_nbr_flag = nbr_flags;
925 
926         /**
927         * Update CTB Mode Map
928         * In case this is first CTB in a row, set left most column to INTRA_DC (NA)
929         * else copy last column to first column
930         **/
931         if(ctb_ctr == 0)
932         {
933             for(row = 0; row < (MAX_TU_ROW_IN_CTB + 1); row++)
934             {
935                 ps_ctxt->au1_ctb_mode_map[row][0] = INTRA_DC;
936             }
937         }
938         else
939         {
940             for(row = 0; row < (MAX_TU_ROW_IN_CTB + 1); row++)
941             {
942                 ps_ctxt->au1_ctb_mode_map[row][0] =
943                     ps_ctxt->au1_ctb_mode_map[row][MAX_TU_COL_IN_CTB];
944             }
945         }
946 
947         /* --------- IPE call at CTB level ------------------ */
948 
949         /* IPE CTB function is expected to Decide on the CUs sizes  */
950         /* and populate the best intra prediction modes and TX flags*/
951         /* Interface of this CTb level function is kept open */
952 
953         ps_ed_l1_ctb = ps_ed_l1_row + ctb_ctr * blk_inc_ctb_l1;
954         ps_ed_l2_ctb = ps_ed_l2_row + ctb_ctr * blk_inc_ctb_l2;
955         ps_ed_ctb_l1 = ps_ed_ctb_l1_row + ctb_ctr;
956 
957         if(ps_ctxt->u1_use_lambda_derived_from_min_8x8_act_in_ctb)
958         {
959             /*HACK : MAMATHA, This function assumes that data is accumalated
960             for all probable CU-TU combinations for INcomplete CTB, which is currently not the case,
961             hence not recomputing lamda for the incomplete CTB */
962             if((ps_ctb_node->u1_width == u1_ctb_size) && (ps_ctb_node->u1_height == u1_ctb_size))
963             {
964                 ihevce_ipe_recompute_lambda_from_min_8x8_act_in_ctb(ps_ctxt, ps_ed_ctb_l1);
965             }
966         }
967 
968         ihevce_ipe_process_ctb(
969             ps_ctxt,
970             ps_frm_ctb_prms,
971             &s_curr_src_bufs,
972             ps_ctb_node,
973             ps_l0_ipe_out_ctb,
974             ps_ctb_out,
975             //ps_row_cu,
976             ps_ed_l1_ctb,
977             ps_ed_l2_ctb,
978             ps_ed_ctb_l1);
979 
980         /* -------------- ctb level updates ----------------- */
981 
982         ps_l0_ipe_out_ctb++;
983         //num_cus_in_ctb = ps_ctb_out->u1_num_cus_in_ctb;
984 
985         //ps_row_cu += num_cus_in_ctb;
986 
987         ps_ctb_out++;
988     }
989     return;
990 }
991 
992 /*!
993 ******************************************************************************
994 * \if Function name : ihevce_ipe_process \endif
995 *
996 * \brief
997 *    Frame level IPE function
998 *
999 * \param[in] pv_ctxt : pointer to IPE module
1000 * \param[in] ps_frm_ctb_prms : CTB characteristics parameters
1001 * \param[in] ps_inp  : pointer to input yuv buffer (frame buffer)
1002 * \param[out] ps_ctb_out : pointer to CTB analyse output structure (frame buffer)
1003 * \param[out] ps_cu_out : pointer to CU analyse output structure (frame buffer)
1004 *
1005 * \return
1006 *    None
1007 *
1008 * Note : Currently the frame level calculations done assumes that
1009 *        framewidth of the input are excat multiple of ctbsize
1010 *
1011 * \author
1012 *  Ittiam
1013 *
1014 *****************************************************************************
1015 */
ihevce_ipe_process(void * pv_ctxt,frm_ctb_ctxt_t * ps_frm_ctb_prms,frm_lambda_ctxt_t * ps_frm_lamda,ihevce_lap_enc_buf_t * ps_curr_inp,pre_enc_L0_ipe_encloop_ctxt_t * ps_L0_IPE_curr_out_pre_enc,ctb_analyse_t * ps_ctb_out,ipe_l0_ctb_analyse_for_me_t * ps_ipe_ctb_out,void * pv_multi_thrd_ctxt,WORD32 slice_type,ihevce_ed_blk_t * ps_ed_pic_l1,ihevce_ed_blk_t * ps_ed_pic_l2,ihevce_ed_ctb_l1_t * ps_ed_ctb_l1_pic,WORD32 thrd_id,WORD32 i4_ping_pong)1016 void ihevce_ipe_process(
1017     void *pv_ctxt,
1018     frm_ctb_ctxt_t *ps_frm_ctb_prms,
1019     frm_lambda_ctxt_t *ps_frm_lamda,
1020     ihevce_lap_enc_buf_t *ps_curr_inp,
1021     pre_enc_L0_ipe_encloop_ctxt_t *ps_L0_IPE_curr_out_pre_enc,
1022     ctb_analyse_t *ps_ctb_out,
1023     //cu_analyse_t               *ps_cu_out,
1024     ipe_l0_ctb_analyse_for_me_t *ps_ipe_ctb_out,
1025     void *pv_multi_thrd_ctxt,
1026     WORD32 slice_type,
1027     ihevce_ed_blk_t *ps_ed_pic_l1,
1028     ihevce_ed_blk_t *ps_ed_pic_l2,
1029     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1_pic,
1030     WORD32 thrd_id,
1031     WORD32 i4_ping_pong)
1032 {
1033     /* local variables */
1034     ihevce_ipe_master_ctxt_t *ps_master_ctxt;
1035     iv_enc_yuv_buf_t *ps_inp = &ps_curr_inp->s_lap_out.s_input_buf;
1036     ihevce_ipe_ctxt_t *ps_ctxt;
1037     iv_enc_yuv_buf_t s_curr_src_bufs;
1038     WORD32 end_of_frame;
1039 
1040     ihevce_ed_blk_t *ps_ed_l1_row;
1041     ihevce_ed_blk_t *ps_ed_l2_row;
1042     ihevce_ed_ctb_l1_t *ps_ed_ctb_l1_row;
1043     WORD32 blk_inc_ctb_l1 = 0;
1044     WORD32 blk_inc_ctb_l2 = 0;
1045 
1046     /* Layer 1 pre intra analysis related initilization.
1047     * Compute no of 8x8 blks in the ctb which which is
1048     * same as no of 4x4 blks in the ctb in layer 1 */
1049     blk_inc_ctb_l1 = ps_frm_ctb_prms->i4_ctb_size >> 3;
1050     blk_inc_ctb_l1 = blk_inc_ctb_l1 * blk_inc_ctb_l1;
1051 
1052     /* Layer 2 pre intra analysis related initilization.
1053     * Compute no of 16x16 blks in the ctb which which is
1054     * same as no of 8x8 blks in the ctb in layer 2 */
1055     blk_inc_ctb_l2 = ps_frm_ctb_prms->i4_ctb_size >> 4;
1056     blk_inc_ctb_l2 = blk_inc_ctb_l2 * blk_inc_ctb_l2;
1057 
1058     /* ----------------------------------------------------- */
1059     /* store the stride and dimensions of source             */
1060     /* buffer pointers will be over written at every CTB row */
1061     /* ----------------------------------------------------- */
1062     memcpy(&s_curr_src_bufs, ps_inp, sizeof(iv_enc_yuv_buf_t));
1063 
1064     ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)pv_ctxt;
1065     ps_ctxt = ps_master_ctxt->aps_ipe_thrd_ctxt[thrd_id];
1066     end_of_frame = 0;
1067 
1068     if(ISLICE == slice_type)
1069     {
1070         ps_ctxt->b_sad_type = IPE_SAD_TYPE;
1071         ps_ctxt->i4_ol_satd_lambda = ps_frm_lamda->i4_ol_satd_lambda_qf;
1072         ps_ctxt->i4_ol_sad_lambda = ps_frm_lamda->i4_ol_sad_lambda_qf;
1073     }
1074     else
1075     {
1076         ps_ctxt->b_sad_type = IPE_SAD_TYPE; /* SAD */
1077         ps_ctxt->i4_ol_satd_lambda = ps_frm_lamda->i4_ol_satd_lambda_qf;
1078         ps_ctxt->i4_ol_sad_lambda = ps_frm_lamda->i4_ol_sad_lambda_qf;
1079     }
1080 
1081     ihevce_populate_ipe_ol_cu_lambda_prms(
1082         (void *)ps_ctxt,
1083         ps_frm_lamda,
1084         slice_type,
1085         ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
1086         IPE_LAMBDA_TYPE);
1087 
1088     /* register the slice type in the ctxt */
1089     ps_ctxt->i4_slice_type = slice_type;
1090 
1091     /** Frame-levelSATD cost accumalator init to 0 */
1092     ps_ctxt->i8_frame_acc_satd_cost = 0;
1093 
1094     /** Frame-levelSATD accumalator init to 0 */
1095     ps_ctxt->i8_frame_acc_satd = 0;
1096 
1097     /** Frame-level Activity factor accumalator init to 1 */
1098     ps_ctxt->i8_frame_acc_act_factor = 1;
1099 
1100     /** Frame-levelMode Bits cost accumalator init to 0 */
1101     ps_ctxt->i8_frame_acc_mode_bits_cost = 0;
1102 
1103     /** Frame -level SATD/qp acc init to 0*/
1104     ps_ctxt->i8_frame_acc_satd_by_modqp_q10 = 0;
1105 
1106     /* ------------ Loop over all the CTB rows --------------- */
1107     while(0 == end_of_frame)
1108     {
1109         UWORD8 *pu1_tmp;
1110         WORD32 vert_ctr;
1111         //cu_analyse_t *ps_row_cu;
1112         ctb_analyse_t *ps_ctb_out_row;
1113         job_queue_t *ps_job;
1114         ipe_l0_ctb_analyse_for_me_t *ps_ipe_ctb_out_row;
1115 
1116         /* Get the current row from the job queue */
1117         ps_job = (job_queue_t *)ihevce_pre_enc_grp_get_next_job(
1118             pv_multi_thrd_ctxt, IPE_JOB_LYR0, 1, i4_ping_pong);
1119 
1120         /* If all rows are done, set the end of process flag to 1, */
1121         /* and the current row to -1 */
1122         if(NULL == ps_job)
1123         {
1124             vert_ctr = -1;
1125             end_of_frame = 1;
1126         }
1127         else
1128         {
1129             ASSERT(IPE_JOB_LYR0 == ps_job->i4_pre_enc_task_type);
1130 
1131             /* Obtain the current row's details from the job */
1132             vert_ctr = ps_job->s_job_info.s_ipe_job_info.i4_ctb_row_no;
1133             //DBG_PRINTF("IPE PASS : Thread id %d, Vert Ctr %d\n",thrd_id,vert_ctr);
1134 
1135             /* Update the ipe context with current row number */
1136             ps_ctxt->u2_ctb_row_num = vert_ctr;
1137 
1138             /* derive the current ctb row pointers */
1139 
1140             /* luma src */
1141             pu1_tmp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_y_buf;
1142             pu1_tmp += (vert_ctr * ps_frm_ctb_prms->i4_ctb_size * ps_inp->i4_y_strd);
1143 
1144             s_curr_src_bufs.pv_y_buf = pu1_tmp;
1145 
1146             /* Cb & CR pixel interleaved src */
1147             pu1_tmp = (UWORD8 *)ps_curr_inp->s_lap_out.s_input_buf.pv_u_buf;
1148             pu1_tmp += (vert_ctr * (ps_frm_ctb_prms->i4_ctb_size >> 1) * ps_inp->i4_uv_strd);
1149 
1150             s_curr_src_bufs.pv_u_buf = pu1_tmp;
1151 
1152             /* row intra analyse cost buffer */
1153             ps_ipe_ctb_out_row = ps_ipe_ctb_out + vert_ctr * ps_frm_ctb_prms->i4_num_ctbs_horz;
1154 
1155             /* row ctb out structure */
1156             ps_ctb_out_row = ps_ctb_out + vert_ctr * ps_frm_ctb_prms->i4_num_ctbs_horz;
1157 
1158             /* call the row level processing function */
1159             ps_ed_l1_row =
1160                 ps_ed_pic_l1 + ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l1 * vert_ctr;
1161             ps_ed_l2_row =
1162                 ps_ed_pic_l2 + ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l2 * vert_ctr;
1163             ps_ed_ctb_l1_row = ps_ed_ctb_l1_pic + ps_frm_ctb_prms->i4_num_ctbs_horz * vert_ctr;
1164             ihevce_ipe_process_row(
1165                 ps_ctxt,
1166                 ps_frm_ctb_prms,
1167                 &s_curr_src_bufs,
1168                 ps_ipe_ctb_out_row,
1169                 ps_ctb_out_row,
1170                 //ps_row_cu,
1171                 ps_ed_l1_row,
1172                 ps_ed_l2_row,
1173                 ps_ed_ctb_l1_row,
1174                 blk_inc_ctb_l1,
1175                 blk_inc_ctb_l2);
1176 
1177             memset(
1178                 ps_ed_l1_row,
1179                 0,
1180                 ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l1 * sizeof(ihevce_ed_blk_t));
1181             memset(
1182                 ps_ed_l2_row,
1183                 0,
1184                 ps_frm_ctb_prms->i4_num_ctbs_horz * blk_inc_ctb_l2 * sizeof(ihevce_ed_blk_t));
1185 
1186             /* set the output dependency */
1187             ihevce_pre_enc_grp_job_set_out_dep(pv_multi_thrd_ctxt, ps_job, i4_ping_pong);
1188         }
1189     }
1190 
1191     /* EIID: Print stat regarding how many 16x16 blocks are skipped in the frame, valid for single thread only */
1192     //DBG_PRINTF("num_16x16_analyze_skipped: %d\n",ps_ctxt->u4_num_16x16_skips_at_L0_IPE);
1193 
1194     return;
1195 }
1196 
1197 /*!
1198 ******************************************************************************
1199 * \if Function name : ihevce_get_frame_lambda_prms \endif
1200 *
1201 * \brief
1202 *    Function whihc calculates the Lambda params for current picture
1203 *
1204 * \param[in] ps_enc_ctxt : encoder ctxt pointer
1205 * \param[in] ps_cur_pic_ctxt : current pic ctxt
1206 * \param[in] i4_cur_frame_qp : current pic QP
1207 * \param[in] first_field : is first field flag
1208 * \param[in] i4_temporal_lyr_id : Current picture layer id
1209 *
1210 * \return
1211 *    None
1212 *
1213 * \author
1214 *  Ittiam
1215 *
1216 *****************************************************************************
1217 */
ihevce_get_ipe_ol_cu_lambda_prms(void * pv_ctxt,WORD32 i4_cur_cu_qp)1218 void ihevce_get_ipe_ol_cu_lambda_prms(void *pv_ctxt, WORD32 i4_cur_cu_qp)
1219 {
1220     ihevce_ipe_ctxt_t *ps_ctxt = (ihevce_ipe_ctxt_t *)pv_ctxt;
1221     //WORD32 chroma_qp = gau1_ihevc_chroma_qp_scale[i4_cur_cu_qp];
1222 
1223     /* Store the params for IPE pass */
1224     ps_ctxt->i4_ol_satd_lambda = ps_ctxt->i4_ol_satd_lambda_qf_array[i4_cur_cu_qp];
1225     ps_ctxt->i4_ol_sad_lambda = ps_ctxt->i4_ol_sad_lambda_qf_array[i4_cur_cu_qp];
1226 }
1227 
1228 /*!
1229 ******************************************************************************
1230 * \if Function name : ihevce_get_frame_lambda_prms \endif
1231 *
1232 * \brief
1233 *    Function whihc calculates the Lambda params for current picture
1234 *
1235 * \param[in] ps_enc_ctxt : encoder ctxt pointer
1236 * \param[in] ps_cur_pic_ctxt : current pic ctxt
1237 * \param[in] i4_cur_frame_qp : current pic QP
1238 * \param[in] first_field : is first field flag
1239 * \param[in] i4_temporal_lyr_id : Current picture layer id
1240 *
1241 * \return
1242 *    None
1243 *
1244 * \author
1245 *  Ittiam
1246 *
1247 *****************************************************************************
1248 */
ihevce_populate_ipe_ol_cu_lambda_prms(void * pv_ctxt,frm_lambda_ctxt_t * ps_frm_lamda,WORD32 i4_slice_type,WORD32 i4_temporal_lyr_id,WORD32 i4_lambda_type)1249 void ihevce_populate_ipe_ol_cu_lambda_prms(
1250     void *pv_ctxt,
1251     frm_lambda_ctxt_t *ps_frm_lamda,
1252     WORD32 i4_slice_type,
1253     WORD32 i4_temporal_lyr_id,
1254     WORD32 i4_lambda_type)
1255 {
1256     WORD32 i4_curr_cu_qp;
1257     double lambda_modifier;
1258     double lambda_uv_modifier;
1259     double lambda;
1260     double lambda_uv;
1261 
1262     ihevce_ipe_ctxt_t *ps_ctxt = (ihevce_ipe_ctxt_t *)pv_ctxt;
1263 
1264     WORD32 i4_qp_bd_offset = 6 * (ps_ctxt->u1_bit_depth - 8);
1265 
1266     for(i4_curr_cu_qp =
1267             ps_ctxt->ps_rc_quant_ctxt->i2_min_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1268         i4_curr_cu_qp <= ps_ctxt->ps_rc_quant_ctxt->i2_max_qp;
1269         i4_curr_cu_qp++)
1270     {
1271         WORD32 chroma_qp = i4_curr_cu_qp;
1272 
1273         if((BSLICE == i4_slice_type) && (i4_temporal_lyr_id))
1274         {
1275             lambda_modifier = ps_frm_lamda->lambda_modifier *
1276                               CLIP3((((double)(i4_curr_cu_qp - 12)) / 6.0), 2.00, 4.00);
1277             lambda_uv_modifier = ps_frm_lamda->lambda_uv_modifier *
1278                                  CLIP3((((double)(chroma_qp - 12)) / 6.0), 2.00, 4.00);
1279         }
1280         else
1281         {
1282             lambda_modifier = ps_frm_lamda->lambda_modifier;
1283             lambda_uv_modifier = ps_frm_lamda->lambda_uv_modifier;
1284         }
1285         if(ps_ctxt->i4_use_const_lamda_modifier)
1286         {
1287             if(ISLICE == i4_slice_type)
1288             {
1289                 lambda_modifier = ps_ctxt->f_i_pic_lamda_modifier;
1290                 lambda_uv_modifier = ps_ctxt->f_i_pic_lamda_modifier;
1291             }
1292             else
1293             {
1294                 lambda_modifier = CONST_LAMDA_MOD_VAL;
1295                 lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
1296             }
1297         }
1298 
1299         switch(i4_lambda_type)
1300         {
1301         case 0:
1302         {
1303             i4_qp_bd_offset = 0;
1304 
1305             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
1306 
1307             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
1308 
1309             lambda *= lambda_modifier;
1310             lambda_uv *= lambda_uv_modifier;
1311             if(ps_ctxt->i4_use_const_lamda_modifier)
1312             {
1313                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
1314                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1315 
1316                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
1317                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1318             }
1319             else
1320             {
1321                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
1322                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
1323 
1324                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
1325                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
1326             }
1327 
1328             ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
1329                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp];
1330 
1331             ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
1332                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp];
1333 
1334             break;
1335         }
1336         case 1:
1337         {
1338             ASSERT(0); /* should not enter the path for IPE*/
1339             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
1340 
1341             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
1342 
1343             lambda *= lambda_modifier;
1344             lambda_uv *= lambda_uv_modifier;
1345             if(ps_ctxt->i4_use_const_lamda_modifier)
1346             {
1347                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
1348                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1349 
1350                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
1351                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1352             }
1353             else
1354             {
1355                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
1356                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
1357 
1358                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
1359                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
1360             }
1361 
1362             ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
1363                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp];
1364 
1365             ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
1366                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp];
1367 
1368             break;
1369         }
1370         case 2:
1371         {
1372             ASSERT(0); /* should not enter the path for IPE*/
1373             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
1374 
1375             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
1376 
1377             lambda *= lambda_modifier;
1378             lambda_uv *= lambda_uv_modifier;
1379             if(ps_ctxt->i4_use_const_lamda_modifier)
1380             {
1381                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
1382                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1383 
1384                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
1385                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1386             }
1387             else
1388             {
1389                 ps_ctxt->i4_ol_sad_lambda_qf_array[i4_curr_cu_qp] =
1390                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
1391 
1392                 ps_ctxt->i4_ol_satd_lambda_qf_array[i4_curr_cu_qp] =
1393                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
1394             }
1395             i4_qp_bd_offset = 0;
1396 
1397             lambda = pow(2.0, (((double)(i4_curr_cu_qp + i4_qp_bd_offset - 12)) / 3.0));
1398 
1399             lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bd_offset - 12)) / 3.0));
1400 
1401             lambda *= lambda_modifier;
1402             lambda_uv *= lambda_uv_modifier;
1403             if(ps_ctxt->i4_use_const_lamda_modifier)
1404             {
1405                 ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
1406                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1407 
1408                 ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
1409                     (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
1410             }
1411             else
1412             {
1413                 ps_ctxt->i4_ol_sad_type2_lambda_qf_array[i4_curr_cu_qp] =
1414                     (WORD32)((sqrt(lambda) / 2) * (1 << LAMBDA_Q_SHIFT));
1415 
1416                 ps_ctxt->i4_ol_satd_type2_lambda_qf_array[i4_curr_cu_qp] =
1417                     (WORD32)((sqrt(lambda * 1.9) / 2) * (1 << LAMBDA_Q_SHIFT));
1418             }
1419             break;
1420         }
1421         default:
1422         {
1423             /* Intended to be a barren wasteland! */
1424             ASSERT(0);
1425         }
1426         }
1427     }
1428 }
1429 
1430 #define ME_COST_THRSHOLD 7
1431 /*!
1432 ******************************************************************************
1433 * \if Function name : ihevce_get_frame_lambda_prms \endif
1434 *
1435 * \brief
1436 *    Function whihc calculates the Lambda params for current picture
1437 *
1438 * \param[in] ps_enc_ctxt : encoder ctxt pointer
1439 * \param[in] ps_cur_pic_ctxt : current pic ctxt
1440 * \param[in] i4_cur_frame_qp : current pic QP
1441 * \param[in] first_field : is first field flag
1442 * \param[in] i4_temporal_lyr_id : Current picture layer id
1443 *
1444 * \return
1445 *    None
1446 *
1447 * \author
1448 *  Ittiam
1449 *
1450 *****************************************************************************
1451 */
1452 #define MAX_64BIT_VAL 0x7fffffffffffffff
ihevce_populate_ipe_frame_init(void * pv_ctxt,ihevce_static_cfg_params_t * ps_stat_prms,WORD32 i4_curr_frm_qp,WORD32 i4_slice_type,WORD32 i4_thrd_id,pre_enc_me_ctxt_t * ps_curr_out,WORD8 i1_cu_qp_delta_enabled_flag,rc_quant_t * ps_rc_quant_ctxt,WORD32 i4_quality_preset,WORD32 i4_temporal_lyr_id,ihevce_lap_output_params_t * ps_lap_out)1453 void ihevce_populate_ipe_frame_init(
1454     void *pv_ctxt,
1455     ihevce_static_cfg_params_t *ps_stat_prms,
1456     WORD32 i4_curr_frm_qp,
1457     WORD32 i4_slice_type,
1458     WORD32 i4_thrd_id,
1459     pre_enc_me_ctxt_t *ps_curr_out,
1460     WORD8 i1_cu_qp_delta_enabled_flag,
1461     rc_quant_t *ps_rc_quant_ctxt,
1462     WORD32 i4_quality_preset,
1463     WORD32 i4_temporal_lyr_id,
1464     ihevce_lap_output_params_t *ps_lap_out)
1465 {
1466     ihevce_ipe_master_ctxt_t *ps_master_ctxt = (ihevce_ipe_master_ctxt_t *)pv_ctxt;
1467     WORD32 i4_i;
1468     WORD32 ai4_mod_factor_num[2];
1469 
1470     ihevce_ipe_ctxt_t *ps_ctxt = ps_master_ctxt->aps_ipe_thrd_ctxt[i4_thrd_id];
1471     ps_ctxt->i4_hevc_qp = i4_curr_frm_qp;
1472     ps_ctxt->i4_quality_preset = i4_quality_preset;
1473     ps_ctxt->i4_temporal_lyr_id = i4_temporal_lyr_id;
1474     ps_ctxt->ps_rc_quant_ctxt = ps_rc_quant_ctxt;
1475     ps_ctxt->i4_qscale =
1476         ps_ctxt->ps_rc_quant_ctxt
1477             ->pi4_qp_to_qscale[i4_curr_frm_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
1478 
1479     ps_ctxt->i4_frm_qp = i4_curr_frm_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1480     ps_ctxt->i4_slice_type = i4_slice_type;  //EIID
1481     ps_ctxt->i4_temporal_layer = ps_lap_out->i4_temporal_lyr_id;
1482     ps_ctxt->i4_is_ref_pic = ps_lap_out->i4_is_ref_pic;
1483     ps_ctxt->u4_num_16x16_skips_at_L0_IPE = 0;
1484     ps_ctxt->i4_use_const_lamda_modifier = USE_CONSTANT_LAMBDA_MODIFIER;
1485     ps_ctxt->i4_use_const_lamda_modifier =
1486         ps_ctxt->i4_use_const_lamda_modifier ||
1487         ((ps_stat_prms->s_coding_tools_prms.i4_vqet &
1488           (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER)) &&
1489          ((ps_stat_prms->s_coding_tools_prms.i4_vqet &
1490            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION)) ||
1491           (ps_stat_prms->s_coding_tools_prms.i4_vqet &
1492            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_1)) ||
1493           (ps_stat_prms->s_coding_tools_prms.i4_vqet &
1494            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_2)) ||
1495           (ps_stat_prms->s_coding_tools_prms.i4_vqet &
1496            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_3))));
1497     {
1498         ps_ctxt->f_i_pic_lamda_modifier = ps_lap_out->f_i_pic_lamda_modifier;
1499     }
1500 #if POW_OPT
1501     for(i4_i = 0; i4_i < 2; i4_i++)
1502     {
1503         ps_ctxt->ld_curr_frame_8x8_log_avg[i4_i] = ps_curr_out->ld_curr_frame_8x8_log_avg[i4_i];
1504         ps_ctxt->ld_curr_frame_16x16_log_avg[i4_i] = ps_curr_out->ld_curr_frame_16x16_log_avg[i4_i];
1505         ps_ctxt->ld_curr_frame_32x32_log_avg[i4_i] = ps_curr_out->ld_curr_frame_32x32_log_avg[i4_i];
1506     }
1507 
1508     ps_ctxt->ld_curr_frame_16x16_log_avg[2] = ps_curr_out->ld_curr_frame_16x16_log_avg[2];
1509     ps_ctxt->ld_curr_frame_32x32_log_avg[2] = ps_curr_out->ld_curr_frame_32x32_log_avg[2];
1510     ps_ctxt->i8_curr_frame_avg_mean_act = ps_curr_out->i8_curr_frame_avg_mean_act;
1511 #else
1512     for(i4_i = 0; i4_i < 2; i4_i++)
1513     {
1514         ps_ctxt->i8_curr_frame_8x8_avg_act[i4_i] = ps_curr_out->i8_curr_frame_8x8_avg_act[i4_i];
1515         ps_ctxt->i8_curr_frame_16x16_avg_act[i4_i] = ps_curr_out->i8_curr_frame_16x16_avg_act[i4_i];
1516         ps_ctxt->i8_curr_frame_32x32_avg_act[i4_i] = ps_curr_out->i8_curr_frame_32x32_avg_act[i4_i];
1517     }
1518 
1519     ps_ctxt->i8_curr_frame_16x16_avg_act[2] = ps_curr_out->i8_curr_frame_16x16_avg_act[2];
1520     ps_ctxt->i8_curr_frame_32x32_avg_act[2] = ps_curr_out->i8_curr_frame_32x32_avg_act[2];
1521 #endif
1522 
1523     ps_ctxt->pi2_trans_out =
1524         (WORD16 *)&ps_ctxt->au1_pred_samples[0];  //overlaying trans coeff memory with pred_samples
1525     ps_ctxt->pi2_trans_tmp = (WORD16 *)&ps_ctxt->au1_pred_samples[2048];
1526 
1527     /*Mod factor NUM */
1528     ps_ctxt->ai4_mod_factor_derived_by_variance[0] =
1529         ps_curr_out->ai4_mod_factor_derived_by_variance[0];
1530     ps_ctxt->ai4_mod_factor_derived_by_variance[1] =
1531         ps_curr_out->ai4_mod_factor_derived_by_variance[1];
1532 
1533     ps_ctxt->f_strength = ps_curr_out->f_strength;
1534 
1535     if(ps_stat_prms->s_coding_tools_prms.i4_vqet & (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER))
1536     {
1537         if(ps_stat_prms->s_coding_tools_prms.i4_vqet &
1538            (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION))
1539         {
1540             ps_ctxt->i4_enable_noise_detection = 1;
1541         }
1542         else
1543         {
1544             ps_ctxt->i4_enable_noise_detection = 0;
1545         }
1546     }
1547     else
1548     {
1549         ps_ctxt->i4_enable_noise_detection = 0;
1550     }
1551 
1552     {
1553         if(ISLICE == ps_ctxt->i4_slice_type)
1554         {
1555             ai4_mod_factor_num[0] = INTRA_QP_MOD_FACTOR_NUM;  //16;
1556             ai4_mod_factor_num[1] = INTRA_QP_MOD_FACTOR_NUM;  //16;
1557         }
1558         else
1559         {
1560             ai4_mod_factor_num[0] = INTER_QP_MOD_FACTOR_NUM;  //4;
1561             ai4_mod_factor_num[1] = INTER_QP_MOD_FACTOR_NUM;  //4;
1562         }
1563 
1564 #if ENABLE_QP_MOD_BASED_ON_SPATIAL_VARIANCE
1565         for(i4_i = 0; i4_i < 2; i4_i++)
1566         {
1567             WORD32 mod_factor_num_val =
1568                 ps_ctxt->ai4_mod_factor_derived_by_variance[i4_i] * QP_MOD_FACTOR_DEN;
1569 
1570             ai4_mod_factor_num[i4_i] = CLIP3(mod_factor_num_val, 1, ai4_mod_factor_num[i4_i]);
1571             ps_ctxt->ai4_mod_factor_derived_by_variance[i4_i] = ai4_mod_factor_num[i4_i];
1572         }
1573 #else
1574         for(i4_i = 0; i4_i < 2; i4_i++)
1575         {
1576             ps_ctxt->ai4_mod_factor_derived_by_variance[i4_i] = ai4_mod_factor_num[i4_i];
1577         }
1578 #endif
1579     }
1580 
1581     ps_ctxt->u1_use_lambda_derived_from_min_8x8_act_in_ctb = MODULATE_LAMDA_WHEN_SPATIAL_MOD_ON &&
1582                                                              i1_cu_qp_delta_enabled_flag;
1583 
1584     ps_ctxt->u1_use_satd = 1;
1585     ps_ctxt->u1_level_1_refine_on = 1;
1586     ps_ctxt->u1_disable_child_cu_decide = 0;
1587 
1588 #if !OLD_XTREME_SPEED
1589     if(((ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P5) ||
1590         (ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P6)) &&
1591        (ps_ctxt->i4_slice_type != ISLICE))
1592     {
1593         ps_ctxt->u1_use_satd = 0;
1594         ps_ctxt->u1_level_1_refine_on = 1;
1595         ps_ctxt->u1_disable_child_cu_decide = 0;
1596     }
1597 
1598 #endif
1599 
1600     if((ps_ctxt->i4_quality_preset == IHEVCE_QUALITY_P4) && (ps_ctxt->i4_slice_type != ISLICE))
1601         ps_ctxt->u1_use_satd = 0;
1602     if(ps_ctxt->i4_quality_preset > IHEVCE_QUALITY_P3)
1603         ps_ctxt->u1_use_satd = 0;
1604 }
1605