Coverage Report

Created: 2026-08-13 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/encoder/ihevce_frame_process.c
Line
Count
Source
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_frame_process.c
24
*
25
* \brief
26
*    This file contains top level functions related Frame processing
27
*
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
#include <time.h>
52
53
/* User include files */
54
#include "ihevc_typedefs.h"
55
#include "itt_video_api.h"
56
#include "ihevce_api.h"
57
58
#include "rc_cntrl_param.h"
59
#include "rc_frame_info_collector.h"
60
#include "rc_look_ahead_params.h"
61
62
#include "ihevc_defs.h"
63
#include "ihevc_debug.h"
64
#include "ihevc_macros.h"
65
#include "ihevc_structs.h"
66
#include "ihevc_platform_macros.h"
67
#include "ihevc_deblk.h"
68
#include "ihevc_itrans_recon.h"
69
#include "ihevc_chroma_itrans_recon.h"
70
#include "ihevc_chroma_intra_pred.h"
71
#include "ihevc_intra_pred.h"
72
#include "ihevc_inter_pred.h"
73
#include "ihevc_mem_fns.h"
74
#include "ihevc_padding.h"
75
#include "ihevc_weighted_pred.h"
76
#include "ihevc_sao.h"
77
#include "ihevc_resi_trans.h"
78
#include "ihevc_quant_iquant_ssd.h"
79
#include "ihevc_cabac_tables.h"
80
#include "ihevc_common_tables.h"
81
82
#include "ihevce_defs.h"
83
#include "ihevce_buffer_que_interface.h"
84
#include "ihevce_hle_interface.h"
85
#include "ihevce_hle_q_func.h"
86
#include "ihevce_lap_enc_structs.h"
87
#include "ihevce_lap_interface.h"
88
#include "ihevce_multi_thrd_structs.h"
89
#include "ihevce_multi_thrd_funcs.h"
90
#include "ihevce_me_common_defs.h"
91
#include "ihevce_had_satd.h"
92
#include "ihevce_error_checks.h"
93
#include "ihevce_error_codes.h"
94
#include "ihevce_bitstream.h"
95
#include "ihevce_cabac.h"
96
#include "ihevce_rdoq_macros.h"
97
#include "ihevce_function_selector.h"
98
#include "ihevce_enc_structs.h"
99
#include "ihevce_global_tables.h"
100
#include "ihevce_cmn_utils_instr_set_router.h"
101
#include "ihevce_ipe_instr_set_router.h"
102
#include "ihevce_entropy_structs.h"
103
#include "ihevce_enc_loop_structs.h"
104
#include "ihevce_enc_loop_utils.h"
105
#include "ihevce_inter_pred.h"
106
#include "ihevce_common_utils.h"
107
#include "ihevce_sub_pic_rc.h"
108
#include "hme_datatype.h"
109
#include "hme_interface.h"
110
#include "hme_common_defs.h"
111
#include "hme_defs.h"
112
#include "ihevce_enc_loop_pass.h"
113
#include "ihevce_trace.h"
114
#include "ihevce_encode_header.h"
115
#include "ihevce_encode_header_sei_vui.h"
116
#include "ihevce_ipe_structs.h"
117
#include "ihevce_ipe_pass.h"
118
#include "ihevce_dep_mngr_interface.h"
119
#include "ihevce_rc_enc_structs.h"
120
#include "hme_globals.h"
121
#include "ihevce_me_pass.h"
122
#include "ihevce_coarse_me_pass.h"
123
#include "ihevce_frame_process.h"
124
#include "ihevce_rc_interface.h"
125
#include "ihevce_profile.h"
126
#include "ihevce_decomp_pre_intra_structs.h"
127
#include "ihevce_decomp_pre_intra_pass.h"
128
#include "ihevce_frame_process_utils.h"
129
130
#include "cast_types.h"
131
#include "osal.h"
132
#include "osal_defaults.h"
133
134
/*****************************************************************************/
135
/* Constant Macros                                                           */
136
/*****************************************************************************/
137
138
207k
#define REF_MOD_STRENGTH 1.0
139
#define REF_MAX_STRENGTH 1.4f
140
141
/*****************************************************************************/
142
/* Extern variables                                                          */
143
/*****************************************************************************/
144
145
/**
146
* @var   QP2QUANT_MD[]
147
*
148
* @brief Direct Cost Comoparision Table
149
*
150
* @param Comments: Direct cost is compared with 16 * QP2QUANT_MD[Qp]
151
*                  If direct cost is less  than 16 * QP2QUANT_MD[Qp]
152
*                  than direct cost is assumed to be zero
153
*/
154
const WORD16 QP2QUANT_MD[52] = { 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
155
                                 1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  4,  4,  4,
156
                                 5,  6,  6,  7,  8,  9,  10, 11, 13, 14, 16, 18, 20,
157
                                 23, 25, 29, 32, 36, 40, 45, 51, 57, 64, 72, 81, 91 };
158
159
/*
160
Gaussian 11x11 window with a sigma of 1.5 - values multiplied by 2048
161
Window made into 9x9 window as most entries were zero
162
The center weight has been reduced by 1 after dropping first row/col and last row/col
163
*/
164
UWORD8 g_u1_win_size = 9;
165
UWORD8 g_u1_win_q_shift = 11;
166
UWORD8 au1_g_win[81] = { 0,  1,  2, 3,  4,  3,   2,   1,   0,  1,  3, 8,  16, 20, 16,  8,   3,
167
                         1,  2,  8, 24, 48, 60,  48,  24,  8,  2,  3, 16, 48, 93, 116, 93,  48,
168
                         16, 3,  4, 20, 60, 116, 144, 116, 60, 20, 4, 3,  16, 48, 93,  116, 93,
169
                         48, 16, 3, 2,  8,  24,  48,  60,  48, 24, 8, 2,  1,  3,  8,   16,  20,
170
                         16, 8,  3, 1,  0,  1,   2,   3,   4,  3,  2, 1,  0 };
171
172
/* lagrange params */
173
const double lamda_modifier_for_I_pic[8] = { 0.85,   0.7471, 0.6646, 0.5913,
174
                                             0.5261, 0.4680, 0.4164, 0.3705 };
175
176
/*****************************************************************************/
177
/* Function Definitions                                                      */
178
/*****************************************************************************/
179
180
/*!
181
******************************************************************************
182
* \if Function name : ihevce_mbr_quality_tool_set_configuration \endif
183
*
184
* \brief
185
*   tool set selection for auxilary bitrate. currently only num intra and inter
186
*       candidates for auxilary bitrates are controlled
187
*
188
* \param[in] ps_enc_loop_thrd_ctxt : enc ctxt
189
* \param[in] ps_stat_prms: static parameters
190
* \return
191
*    None
192
*
193
* \author
194
*  Ittiam
195
*
196
*****************************************************************************
197
*/
198
void ihevce_mbr_quality_tool_set_configuration(
199
    ihevce_enc_loop_ctxt_t *ps_enc_loop_thrd_ctxt, ihevce_static_cfg_params_t *ps_stat_prms)
200
0
{
201
    /* for single bitrate encoder*/
202
0
    switch(ps_stat_prms->s_tgt_lyr_prms.i4_mbr_quality_setting)
203
0
    {
204
0
    case IHEVCE_MBR_HIGH_QUALITY:
205
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 3;
206
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 4;
207
0
        break;
208
209
0
    case IHEVCE_MBR_MEDIUM_SPEED:
210
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 3;
211
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 3;
212
0
        break;
213
214
0
    case IHEVCE_MBR_HIGH_SPEED:
215
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 2;
216
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 2;
217
0
        break;
218
219
0
    case IHEVCE_MBR_EXTREME_SPEED:
220
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_intra = 1;
221
0
        ps_enc_loop_thrd_ctxt->i4_num_modes_to_evaluate_inter = 1;
222
0
        break;
223
224
0
    default:
225
0
        assert(0);
226
0
        break;
227
0
    }
228
0
}
229
230
/*!
231
******************************************************************************
232
* \if Function name : ihevce_find_free_indx \endif
233
*
234
* \brief
235
*    Pre encode Frame processing slave thread entry point function
236
*
237
* \param[in] Frame processing thread context pointer
238
*
239
* \return
240
*    None
241
*
242
* \author
243
*  Ittiam
244
*
245
*****************************************************************************
246
*/
247
WORD32 ihevce_find_free_indx(recon_pic_buf_t **pps_recon_buf_q, WORD32 i4_num_buf)
248
2.76k
{
249
2.76k
    WORD32 i4_ctr;
250
2.76k
    WORD32 i4_is_full = 1;
251
2.76k
    WORD32 i4_least_POC = 0x7FFFFFFF;
252
2.76k
    WORD32 i4_least_POC_idx = -1;
253
2.76k
    WORD32 i4_least_GOP_num = 0x7FFFFFFF;
254
255
13.8k
    for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
256
11.9k
    {
257
11.9k
        if(pps_recon_buf_q[i4_ctr]->i4_is_free == 1)
258
837
        {
259
837
            i4_is_full = 0;
260
837
            break;
261
837
        }
262
11.9k
    }
263
2.76k
    if(i4_is_full)
264
1.93k
    {
265
        /* remove if any non-reference pictures are present */
266
11.5k
        for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
267
9.63k
        {
268
9.63k
            if(!pps_recon_buf_q[i4_ctr]->i4_is_reference &&
269
14
               pps_recon_buf_q[i4_ctr]->i4_non_ref_free_flag)
270
14
            {
271
14
                i4_least_POC_idx = i4_ctr;
272
14
                break;
273
14
            }
274
9.63k
        }
275
        /* if all non reference pictures are removed, then find the least poc
276
        in the least gop number*/
277
1.93k
        if(i4_least_POC_idx == -1)
278
1.91k
        {
279
11.5k
            for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
280
9.58k
            {
281
9.58k
                if(i4_least_GOP_num > pps_recon_buf_q[i4_ctr]->i4_idr_gop_num)
282
2.18k
                {
283
2.18k
                    i4_least_GOP_num = pps_recon_buf_q[i4_ctr]->i4_idr_gop_num;
284
2.18k
                }
285
9.58k
            }
286
11.5k
            for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
287
9.58k
            {
288
9.58k
                if(i4_least_POC > pps_recon_buf_q[i4_ctr]->i4_poc &&
289
4.32k
                   i4_least_GOP_num == pps_recon_buf_q[i4_ctr]->i4_idr_gop_num)
290
3.12k
                {
291
3.12k
                    i4_least_POC = pps_recon_buf_q[i4_ctr]->i4_poc;
292
3.12k
                    i4_least_POC_idx = i4_ctr;
293
3.12k
                }
294
9.58k
            }
295
1.91k
        }
296
1.93k
    }
297
2.76k
    return i4_least_POC_idx;
298
2.76k
}
299
300
/*!
301
******************************************************************************
302
* \if Function name : complexity_RC_reset_marking \endif
303
*
304
* \brief
305
*   this function the complexity variation and set the complexity change flag for
306
*   rate control to reset the model
307
*
308
* \param[in] ps_enc_loop_thrd_ctxt : enc ctxt
309
* \param[in] ps_stat_prms: static parameters
310
* \return
311
*    None
312
*
313
* \author
314
*  Ittiam
315
*
316
*****************************************************************************
317
*/
318
void complexity_RC_reset_marking(enc_ctxt_t *ps_enc_ctxt, WORD32 i4_cur_ipe_idx, WORD32 i4_end_flag)
319
2.14k
{
320
2.14k
    rc_lap_out_params_t *ps_cur_ipe_lap_out;
321
2.14k
    rc_lap_out_params_t *ps_lap_out_temp;
322
2.14k
    WORD32 i4_max_temporal_layers;
323
324
2.14k
    ps_cur_ipe_lap_out =
325
2.14k
        &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out;
326
2.14k
    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_model = 0;
327
2.14k
    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 0;
328
329
2.14k
    i4_max_temporal_layers = ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers;
330
331
    /*reset the RC_reset counter at reset points*/
332
2.14k
    if(ps_cur_ipe_lap_out->i4_is_I_only_scd || ps_cur_ipe_lap_out->i4_is_non_I_scd ||
333
1.94k
       ps_cur_ipe_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
334
198
    {
335
198
        ps_enc_ctxt->i4_past_RC_reset_count = 0;
336
198
    }
337
338
2.14k
    if(ps_cur_ipe_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
339
0
    {
340
0
        ps_enc_ctxt->i4_past_RC_scd_reset_count = 0;
341
0
    }
342
2.14k
    ps_enc_ctxt->i4_past_RC_reset_count++;
343
2.14k
    ps_enc_ctxt->i4_past_RC_scd_reset_count++;
344
345
    /*complexity based rate control reset */
346
347
2.14k
    if((ps_cur_ipe_lap_out->i4_rc_pic_type == IV_P_FRAME ||
348
493
        ps_cur_ipe_lap_out->i4_rc_pic_type == IV_I_FRAME) &&
349
1.72k
       (i4_max_temporal_layers > 1) && (!i4_end_flag) &&
350
13
       (ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe > (2 * (1 << i4_max_temporal_layers))))
351
0
    {
352
0
        WORD32 i4_is_cur_pic_high_complex_region =
353
0
            ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_cur_ipe_idx]
354
0
                ->i4_is_high_complex_region;
355
0
        WORD32 i4_next_ipe_idx;
356
0
        WORD32 i4_next_next_ipe_idx;
357
0
        WORD32 i4_temp_ipe_idx;
358
0
        WORD32 i;
359
360
0
        ps_enc_ctxt->i4_future_RC_reset = 0;
361
0
        ps_enc_ctxt->i4_future_RC_scd_reset = 0;
362
0
        ASSERT(i4_is_cur_pic_high_complex_region != -1);
363
364
        /*get the next idx of p/i picture */
365
0
        i4_next_ipe_idx = (i4_cur_ipe_idx + 1);
366
0
        if(i4_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
367
0
        {
368
0
            i4_next_ipe_idx = 0;
369
0
        }
370
0
        i4_temp_ipe_idx = i4_next_ipe_idx;
371
0
        for(i = 0; i < (1 << i4_max_temporal_layers); i++)
372
0
        {
373
0
            ps_lap_out_temp =
374
0
                &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_next_ipe_idx]->s_rc_lap_out;
375
376
0
            if(ps_lap_out_temp->i4_rc_pic_type == IV_P_FRAME ||
377
0
               ps_lap_out_temp->i4_rc_pic_type == IV_I_FRAME)
378
0
            {
379
0
                break;
380
0
            }
381
0
            i4_next_ipe_idx++;
382
0
            if(i4_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
383
0
            {
384
0
                i4_next_ipe_idx = 0;
385
0
            }
386
0
        }
387
        /* get the next idx of next p/i picture*/
388
0
        i4_next_next_ipe_idx = (i4_next_ipe_idx + 1);
389
0
        if(i4_next_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
390
0
        {
391
0
            i4_next_next_ipe_idx = 0;
392
0
        }
393
0
        for(i = 0; i < (1 << i4_max_temporal_layers); i++)
394
0
        {
395
0
            ps_lap_out_temp =
396
0
                &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_next_next_ipe_idx]->s_rc_lap_out;
397
398
0
            if(ps_lap_out_temp->i4_rc_pic_type == IV_P_FRAME ||
399
0
               ps_lap_out_temp->i4_rc_pic_type == IV_I_FRAME)
400
0
            {
401
0
                break;
402
0
            }
403
0
            i4_next_next_ipe_idx++;
404
0
            if(i4_next_next_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
405
0
            {
406
0
                i4_next_next_ipe_idx = 0;
407
0
            }
408
0
        }
409
410
        /*check for any possible RC reset in the future 8 frames*/
411
0
        for(i = 0; i < 8; i++)
412
0
        {
413
0
            ps_lap_out_temp =
414
0
                &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_temp_ipe_idx]->s_rc_lap_out;
415
416
0
            if(ps_lap_out_temp->i4_is_I_only_scd || ps_lap_out_temp->i4_is_non_I_scd ||
417
0
               ps_lap_out_temp->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
418
0
            {
419
0
                ps_enc_ctxt->i4_future_RC_reset = 1;
420
0
            }
421
0
            if(ps_cur_ipe_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
422
0
            {
423
0
                ps_enc_ctxt->i4_future_RC_scd_reset = 1;
424
0
            }
425
0
            i4_temp_ipe_idx++;
426
0
            if(i4_temp_ipe_idx >= ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe)
427
0
            {
428
0
                i4_temp_ipe_idx = 0;
429
0
            }
430
0
        }
431
432
0
        if((!ps_enc_ctxt->i4_future_RC_reset) && (ps_enc_ctxt->i4_past_RC_reset_count > 8))
433
0
        {
434
            /*if the prev two P/I pic is not in high complex region
435
            then enable reset RC flag*/
436
0
            if((!ps_enc_ctxt->ai4_is_past_pic_complex[0]) &&
437
0
               (!ps_enc_ctxt->ai4_is_past_pic_complex[1]))
438
0
            {
439
0
                if(i4_is_cur_pic_high_complex_region)
440
0
                {
441
0
                    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_model = 1;
442
0
                    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
443
0
                    ps_enc_ctxt->i4_is_I_reset_done = 0;
444
0
                }
445
0
            }
446
447
            /*if the next two P/I pic is not in high complex region
448
            then enable reset RC flag*/
449
0
            if((!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_ipe_idx]
450
0
                     ->i4_is_high_complex_region) &&
451
0
               (!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_next_ipe_idx]
452
0
                     ->i4_is_high_complex_region))
453
0
            {
454
0
                if(i4_is_cur_pic_high_complex_region)
455
0
                {
456
0
                    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_model = 1;
457
0
                    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
458
0
                    ps_enc_ctxt->i4_is_I_reset_done = 0;
459
0
                }
460
0
            }
461
0
        }
462
0
        else if((!ps_enc_ctxt->i4_future_RC_scd_reset) && (ps_enc_ctxt->i4_past_RC_scd_reset_count > 8))
463
0
        {
464
            /*if the prev two P/I pic is not in high complex region
465
            then enable reset RC flag*/
466
0
            if((!ps_enc_ctxt->ai4_is_past_pic_complex[0]) &&
467
0
               (!ps_enc_ctxt->ai4_is_past_pic_complex[1]))
468
0
            {
469
0
                if(i4_is_cur_pic_high_complex_region)
470
0
                {
471
0
                    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
472
0
                }
473
0
            }
474
475
            /*if the next two P/I pic is not in high complex region
476
            then enable reset RC flag*/
477
0
            if((!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_ipe_idx]
478
0
                     ->i4_is_high_complex_region) &&
479
0
               (!ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_next_next_ipe_idx]
480
0
                     ->i4_is_high_complex_region))
481
0
            {
482
0
                if(i4_is_cur_pic_high_complex_region)
483
0
                {
484
0
                    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 1;
485
0
                }
486
0
            }
487
0
        }
488
489
        /* forcing I frame reset after complexity change is disable as it gives gain, could be due to that
490
        required i reset is already happening on pre Intra SAD*/
491
        /*if(!ps_enc_ctxt->i4_is_I_reset_done && (ps_cur_ipe_lap_out->i4_pic_type
492
        == IV_I_FRAME))
493
        {
494
            ps_cur_ipe_lap_out->i4_is_I_only_scd = 1;
495
            ps_enc_ctxt->i4_is_I_reset_done = 1;
496
        }*/
497
498
0
        ps_enc_ctxt->ai4_is_past_pic_complex[0] = i4_is_cur_pic_high_complex_region;
499
500
0
        ps_enc_ctxt->ai4_is_past_pic_complex[1] = ps_enc_ctxt->ai4_is_past_pic_complex[0];
501
0
    }
502
2.14k
    return;
503
2.14k
}
504
/*!
505
******************************************************************************
506
* \if Function name : ihevce_manage_ref_pics \endif
507
*
508
* \brief
509
*    Reference picture management based on delta poc array given by LAP
510
*    Populates the reference list after removing non used reference pictures
511
*    populates the delta poc of reference pics to be signalled in slice header
512
*
513
* \param[in] encoder context pointer
514
* \param[in] current LAP Encoder buffer pointer
515
* \param[in] current frame process and entropy buffer pointer
516
*
517
* \return
518
*    None
519
*
520
* \author
521
*  Ittiam
522
*
523
*****************************************************************************
524
*/
525
void ihevce_pre_enc_manage_ref_pics(
526
    enc_ctxt_t *ps_enc_ctxt,
527
    ihevce_lap_enc_buf_t *ps_curr_inp,
528
    pre_enc_me_ctxt_t *ps_curr_out,
529
    WORD32 i4_ping_pong)
530
2.76k
{
531
    /* local variables */
532
2.76k
    WORD32 ctr;
533
2.76k
    WORD32 ref_pics;
534
2.76k
    WORD32 ai4_buf_status[HEVCE_MAX_DPB_PICS] = { 0 };
535
2.76k
    WORD32 curr_poc;
536
2.76k
    WORD32 wp_flag = 0;
537
2.76k
    WORD32 num_ref_pics_list0 = 0;
538
2.76k
    WORD32 num_ref_pics_list1 = 0;
539
2.76k
    WORD32 cra_poc = ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc;
540
2.76k
    WORD32 slice_type = ps_curr_out->s_slice_hdr.i1_slice_type;
541
2.76k
    recon_pic_buf_t *(*aps_pre_enc_ref_pic_list)[HEVCE_MAX_REF_PICS * 2];
542
2.76k
    WORD32 i4_inc_L1_active_ref_pic = 0;
543
2.76k
    WORD32 i4_inc_L0_active_ref_pic = 0;
544
545
2.76k
    (void)ps_curr_out;
546
2.76k
    curr_poc = ps_curr_inp->s_lap_out.i4_poc;
547
548
    /* Number of reference pics given by LAP should not be greater than max */
549
2.76k
    ASSERT(HEVCE_MAX_REF_PICS >= ps_curr_inp->s_lap_out.i4_num_ref_pics);
550
551
    /*derive ref_pic_list based on ping_pong instance */
552
2.76k
    aps_pre_enc_ref_pic_list = ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong];
553
554
    /* derive the weighted prediction enable flag based on slice type */
555
2.76k
    if(BSLICE == slice_type)
556
36
    {
557
36
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_bipred_flag;
558
36
    }
559
2.73k
    else if(PSLICE == slice_type)
560
2.15k
    {
561
2.15k
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_pred_flag;
562
2.15k
    }
563
579
    else
564
579
    {
565
579
        wp_flag = 0;
566
579
    }
567
568
    /*to support diplicate pics*/
569
2.76k
    {
570
2.76k
        WORD32 i, j;
571
8.30k
        for(i = 0; i < 2; i++)
572
5.53k
        {
573
94.1k
            for(j = 0; j < HEVCE_MAX_REF_PICS * 2; j++)
574
88.5k
            {
575
88.5k
                aps_pre_enc_ref_pic_list[i][j] =
576
88.5k
                    &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][i][j];
577
88.5k
            }
578
5.53k
        }
579
2.76k
    }
580
581
    /* run a loop over the number of reference pics given by LAP */
582
10.0k
    for(ref_pics = 0; ref_pics < ps_curr_inp->s_lap_out.i4_num_ref_pics; ref_pics++)
583
7.29k
    {
584
7.29k
        WORD32 ref_poc;
585
7.29k
        WORD32 i4_loop = 1;
586
7.29k
        WORD32 i4_temp_list;
587
588
7.29k
        ref_poc = curr_poc + ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_ref_pic_delta_poc;
589
590
        /* run a loop to check the poc based on delta poc array */
591
19.5k
        for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
592
19.5k
        {
593
            /* if the POC is matching with current ref picture*/
594
19.5k
            if((ref_poc == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_poc) &&
595
7.29k
               (0 == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free))
596
7.29k
            {
597
                /* mark the buf status as used */
598
7.29k
                ai4_buf_status[ctr] = 1;
599
600
                /* populate the reference lists based on delta poc array */
601
7.29k
                if((ref_poc < curr_poc) || (0 == curr_poc))
602
7.24k
                {
603
                    /* list 0 */
604
7.24k
                    memcpy(
605
7.24k
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0],
606
7.24k
                        ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
607
7.24k
                        sizeof(recon_pic_buf_t));
608
7.24k
                    i4_temp_list = num_ref_pics_list0;
609
610
                    /*duplicate pics added to the list*/
611
7.24k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
612
7.24k
                                         .i4_num_duplicate_entries_in_ref_list)
613
0
                    {
614
                        /* list 0 */
615
0
                        i4_temp_list++;
616
0
                        memcpy(
617
0
                            &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][i4_temp_list],
618
0
                            ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
619
0
                            sizeof(recon_pic_buf_t));
620
0
                        i4_loop++;
621
0
                    }
622
623
                    /* populate weights and offsets corresponding to this ref pic */
624
7.24k
                    memcpy(
625
7.24k
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
626
7.24k
                             .s_weight_offset,
627
7.24k
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
628
7.24k
                        sizeof(ihevce_wght_offst_t));
629
630
                    /* Store the used as ref for current pic flag  */
631
7.24k
                    ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
632
7.24k
                        .i4_used_by_cur_pic_flag =
633
7.24k
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
634
635
7.24k
                    num_ref_pics_list0++;
636
7.24k
                    i4_loop = 1;
637
                    /*duplicate pics added to the list*/
638
7.24k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
639
7.24k
                                         .i4_num_duplicate_entries_in_ref_list)
640
0
                    {
641
                        /* populate weights and offsets corresponding to this ref pic */
642
0
                        memcpy(
643
0
                            &ps_enc_ctxt
644
0
                                 ->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
645
0
                                 .s_weight_offset,
646
0
                            &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
647
0
                            sizeof(ihevce_wght_offst_t));
648
649
                        /* Store the used as ref for current pic flag  */
650
0
                        ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
651
0
                            .i4_used_by_cur_pic_flag =
652
0
                            ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
653
654
0
                        num_ref_pics_list0++;
655
0
                        i4_loop++;
656
0
                    }
657
7.24k
                }
658
49
                else
659
49
                {
660
                    /* list 1 */
661
49
                    memcpy(
662
49
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1],
663
49
                        ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
664
49
                        sizeof(recon_pic_buf_t));
665
666
49
                    i4_temp_list = num_ref_pics_list1;
667
                    /*duplicate pics added to the list*/
668
49
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
669
49
                                         .i4_num_duplicate_entries_in_ref_list)
670
0
                    {
671
                        /* list 1 */
672
0
                        i4_temp_list++;
673
0
                        memcpy(
674
0
                            &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][i4_temp_list],
675
0
                            ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
676
0
                            sizeof(recon_pic_buf_t));
677
0
                        i4_loop++;
678
0
                    }
679
680
                    /* populate weights and offsets corresponding to this ref pic */
681
49
                    memcpy(
682
49
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
683
49
                             .s_weight_offset,
684
49
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
685
49
                        sizeof(ihevce_wght_offst_t));
686
687
                    /* Store the used as ref for current pic flag  */
688
49
                    ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
689
49
                        .i4_used_by_cur_pic_flag =
690
49
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
691
692
49
                    num_ref_pics_list1++;
693
49
                    i4_loop = 1;
694
                    /*duplicate pics added to the list*/
695
49
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
696
49
                                         .i4_num_duplicate_entries_in_ref_list)
697
0
                    {
698
                        /* populate weights and offsets corresponding to this ref pic */
699
0
                        memcpy(
700
0
                            &ps_enc_ctxt
701
0
                                 ->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
702
0
                                 .s_weight_offset,
703
0
                            &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
704
0
                            sizeof(ihevce_wght_offst_t));
705
706
                        /* Store the used as ref for current pic flag  */
707
0
                        ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
708
0
                            .i4_used_by_cur_pic_flag =
709
0
                            ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
710
711
0
                        num_ref_pics_list1++;
712
0
                        i4_loop++;
713
0
                    }
714
49
                }
715
7.29k
                break;
716
7.29k
            }
717
19.5k
        }
718
719
        /* if the reference picture is not found then error */
720
7.29k
        ASSERT(ctr != ps_enc_ctxt->i4_pre_enc_num_buf_recon_q);
721
7.29k
    }
722
    /* sort the reference pics in List0 in descending order POC */
723
2.76k
    if(num_ref_pics_list0 > 1)
724
1.93k
    {
725
        /* run a loop for num ref pics -1 */
726
6.88k
        for(ctr = 0; ctr < num_ref_pics_list0 - 1; ctr++)
727
4.95k
        {
728
4.95k
            WORD32 max_idx = ctr;
729
4.95k
            recon_pic_buf_t *ps_temp;
730
4.95k
            WORD32 i;
731
732
14.2k
            for(i = (ctr + 1); i < num_ref_pics_list0; i++)
733
9.34k
            {
734
                /* check for poc greater than current ref poc */
735
9.34k
                if(aps_pre_enc_ref_pic_list[LIST_0][i]->i4_poc >
736
9.34k
                   aps_pre_enc_ref_pic_list[LIST_0][max_idx]->i4_poc)
737
0
                {
738
0
                    max_idx = i;
739
0
                }
740
9.34k
            }
741
742
            /* if max of remaining is not current, swap the pointers */
743
4.95k
            if(max_idx != ctr)
744
0
            {
745
0
                ps_temp = aps_pre_enc_ref_pic_list[LIST_0][max_idx];
746
0
                aps_pre_enc_ref_pic_list[LIST_0][max_idx] = aps_pre_enc_ref_pic_list[LIST_0][ctr];
747
0
                aps_pre_enc_ref_pic_list[LIST_0][ctr] = ps_temp;
748
0
            }
749
4.95k
        }
750
1.93k
    }
751
752
    /* sort the reference pics in List1 in ascending order POC */
753
2.76k
    if(num_ref_pics_list1 > 1)
754
13
    {
755
        /* run a loop for num ref pics -1 */
756
26
        for(ctr = 0; ctr < num_ref_pics_list1 - 1; ctr++)
757
13
        {
758
13
            WORD32 min_idx = ctr;
759
13
            recon_pic_buf_t *ps_temp;
760
13
            WORD32 i;
761
762
26
            for(i = (ctr + 1); i < num_ref_pics_list1; i++)
763
13
            {
764
                /* check for p[oc less than current ref poc */
765
13
                if(aps_pre_enc_ref_pic_list[LIST_1][i]->i4_poc <
766
13
                   aps_pre_enc_ref_pic_list[LIST_1][min_idx]->i4_poc)
767
0
                {
768
0
                    min_idx = i;
769
0
                }
770
13
            }
771
772
            /* if min of remaining is not current, swap the pointers */
773
13
            if(min_idx != ctr)
774
0
            {
775
0
                ps_temp = aps_pre_enc_ref_pic_list[LIST_1][min_idx];
776
0
                aps_pre_enc_ref_pic_list[LIST_1][min_idx] = aps_pre_enc_ref_pic_list[LIST_1][ctr];
777
0
                aps_pre_enc_ref_pic_list[LIST_1][ctr] = ps_temp;
778
0
            }
779
13
        }
780
13
    }
781
782
    /* call the ME API to update the DPB of HME pyramids coarse layers */
783
2.76k
    ihevce_coarse_me_frame_dpb_update(
784
2.76k
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
785
2.76k
        num_ref_pics_list0,
786
2.76k
        num_ref_pics_list1,
787
2.76k
        &aps_pre_enc_ref_pic_list[LIST_0][0],
788
2.76k
        &aps_pre_enc_ref_pic_list[LIST_1][0]);
789
790
    /* Default list creation based on uses as ref pic for current pic flag */
791
2.76k
    {
792
2.76k
        WORD32 num_ref_pics_list_final = 0;
793
2.76k
        WORD32 list_idx = 0;
794
795
        /* LIST 0 */
796
        /* run a loop for num ref pics in list 0 */
797
10.0k
        for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
798
7.24k
        {
799
            /* check for used as reference flag */
800
7.24k
            if(1 == aps_pre_enc_ref_pic_list[LIST_0][ctr]->i4_used_by_cur_pic_flag)
801
7.24k
            {
802
                /* copy the pointer to the actual valid list idx */
803
7.24k
                aps_pre_enc_ref_pic_list[LIST_0][list_idx] = aps_pre_enc_ref_pic_list[LIST_0][ctr];
804
805
                /* increment the valid pic counters and idx */
806
7.24k
                list_idx++;
807
7.24k
                num_ref_pics_list_final++;
808
7.24k
            }
809
7.24k
        }
810
811
        /* finally store the number of pictures in List0 */
812
2.76k
        num_ref_pics_list0 = num_ref_pics_list_final;
813
        /* LIST 1 */
814
2.76k
        num_ref_pics_list_final = 0;
815
2.76k
        list_idx = 0;
816
817
        /* run a loop for num ref pics in list 1 */
818
2.81k
        for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
819
49
        {
820
            /* check for used as reference flag */
821
49
            if(1 == aps_pre_enc_ref_pic_list[LIST_1][ctr]->i4_used_by_cur_pic_flag)
822
49
            {
823
                /* copy the pointer to the actual valid list idx */
824
49
                aps_pre_enc_ref_pic_list[LIST_1][list_idx] = aps_pre_enc_ref_pic_list[LIST_1][ctr];
825
826
                /* increment the valid pic counters and idx */
827
49
                list_idx++;
828
49
                num_ref_pics_list_final++;
829
49
            }
830
49
        }
831
832
        /* finally store the number of pictures in List1 */
833
2.76k
        num_ref_pics_list1 = num_ref_pics_list_final;
834
2.76k
    }
835
    /*in case of single active ref picture on L0 and L1, then consider one of them weighted
836
    and another non-weighted*/
837
2.76k
    if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
838
2.15k
    {
839
2.15k
        if(num_ref_pics_list0 > 2)
840
1.54k
        {
841
1.54k
            if(aps_pre_enc_ref_pic_list[LIST_0][0]->i4_poc ==
842
1.54k
               aps_pre_enc_ref_pic_list[LIST_0][1]->i4_poc)
843
0
            {
844
0
                i4_inc_L0_active_ref_pic = 1;
845
0
            }
846
1.54k
        }
847
2.15k
    }
848
615
    else
849
615
    {
850
615
        if(num_ref_pics_list0 >= 2 && num_ref_pics_list1 >= 2)
851
4
        {
852
4
            if(aps_pre_enc_ref_pic_list[LIST_0][0]->i4_poc ==
853
4
               aps_pre_enc_ref_pic_list[LIST_0][1]->i4_poc)
854
0
            {
855
0
                i4_inc_L0_active_ref_pic = 1;
856
0
            }
857
4
            if(aps_pre_enc_ref_pic_list[LIST_1][0]->i4_poc ==
858
4
               aps_pre_enc_ref_pic_list[LIST_1][1]->i4_poc)
859
0
            {
860
0
                i4_inc_L1_active_ref_pic = 1;
861
0
            }
862
4
        }
863
615
    }
864
865
    /* append the reference pics in List1 and end of list0 */
866
2.81k
    for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
867
49
    {
868
49
        aps_pre_enc_ref_pic_list[LIST_0][num_ref_pics_list0 + ctr] =
869
49
            aps_pre_enc_ref_pic_list[LIST_1][ctr];
870
49
    }
871
872
    /* append the reference pics in List0 and end of list1 */
873
10.0k
    for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
874
7.24k
    {
875
7.24k
        aps_pre_enc_ref_pic_list[LIST_1][num_ref_pics_list1 + ctr] =
876
7.24k
            aps_pre_enc_ref_pic_list[LIST_0][ctr];
877
7.24k
    }
878
879
    /* reference list modification for adding duplicate reference */
880
2.76k
    {
881
882
2.76k
    }
883
884
    /* popluate the default weights and offsets for disabled cases */
885
2.76k
    {
886
2.76k
        WORD32 i;
887
888
        /* populate the weights and offsets for all pics in L0 + L1 */
889
10.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
890
7.29k
        {
891
            /* populate the weights and offsets if weighted prediction is disabled */
892
7.29k
            if(1 == wp_flag)
893
0
            {
894
                /* if weights are disabled then populate default values */
895
0
                if(0 ==
896
0
                   aps_pre_enc_ref_pic_list[LIST_0][i]->s_weight_offset.u1_luma_weight_enable_flag)
897
0
                {
898
                    /* set to default values */
899
0
                    aps_pre_enc_ref_pic_list[LIST_0][i]->s_weight_offset.i2_luma_weight =
900
0
                        (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
901
902
0
                    aps_pre_enc_ref_pic_list[LIST_0][i]->s_weight_offset.i2_luma_offset = 0;
903
0
                }
904
0
            }
905
7.29k
        }
906
907
10.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
908
7.29k
        {
909
            /* populate the weights and offsets if weighted prediction is enabled */
910
7.29k
            if(1 == wp_flag)
911
0
            {
912
                /* if weights are disabled then populate default values */
913
0
                if(0 ==
914
0
                   aps_pre_enc_ref_pic_list[LIST_1][i]->s_weight_offset.u1_luma_weight_enable_flag)
915
0
                {
916
                    /* set to default values */
917
0
                    aps_pre_enc_ref_pic_list[LIST_1][i]->s_weight_offset.i2_luma_weight =
918
0
                        (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
919
920
0
                    aps_pre_enc_ref_pic_list[LIST_1][i]->s_weight_offset.i2_luma_offset = 0;
921
0
                }
922
0
            }
923
7.29k
        }
924
2.76k
    }
925
926
    /* run a loop to free the non used reference pics */
927
16.6k
    for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
928
13.8k
    {
929
        /* if not used as reference */
930
13.8k
        if(0 == ai4_buf_status[ctr])
931
6.54k
        {
932
6.54k
            ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free = 1;
933
6.54k
            ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_poc = -1;
934
6.54k
        }
935
13.8k
    }
936
937
    /* store the number of reference pics in the list for ME/MC etc */
938
2.76k
    ps_enc_ctxt->i4_pre_enc_num_ref_l0 = num_ref_pics_list0;
939
2.76k
    ps_enc_ctxt->i4_pre_enc_num_ref_l1 = num_ref_pics_list1;
940
941
2.76k
#define HME_USE_ONLY_2REF
942
#ifndef HME_USE_ONLY_2REF
943
    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = num_ref_pics_list0;
944
    ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = num_ref_pics_list1;
945
#else
946
2.76k
#if MULTI_REF_ENABLE == 1
947
2.76k
    if(ps_curr_inp->s_lap_out.i4_quality_preset >= IHEVCE_QUALITY_P3)
948
1.69k
    {
949
1.69k
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
950
1.41k
        {
951
1.41k
            if(IHEVCE_QUALITY_P6 == ps_curr_inp->s_lap_out.i4_quality_preset)
952
194
            {
953
194
                if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
954
0
                {
955
0
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active =
956
0
                        MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25 + 1, num_ref_pics_list0);
957
0
                }
958
194
                else
959
194
                {
960
194
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active =
961
194
                        MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25, num_ref_pics_list0);
962
194
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
963
194
                }
964
965
194
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
966
194
            }
967
1.22k
            else
968
1.22k
            {
969
1.22k
                if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
970
0
                {
971
0
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(3, num_ref_pics_list0);
972
0
                }
973
1.22k
                else
974
1.22k
                {
975
1.22k
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
976
1.22k
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
977
1.22k
                }
978
979
1.22k
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
980
1.22k
            }
981
1.41k
        }
982
279
        else
983
279
        {
984
279
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
985
0
            {
986
0
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
987
0
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
988
0
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active += i4_inc_L1_active_ref_pic;
989
0
            }
990
279
            else
991
279
            {
992
279
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(1, num_ref_pics_list0);
993
279
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
994
279
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active += i4_inc_L1_active_ref_pic;
995
279
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
996
279
            }
997
279
        }
998
1.69k
    }
999
1.07k
    else
1000
1.07k
    {
1001
1.07k
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1002
735
        {
1003
735
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1004
0
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1005
735
            else
1006
735
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1007
1008
735
            ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
1009
735
        }
1010
336
        else
1011
336
        {
1012
336
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1013
0
            {
1014
0
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1015
0
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1016
0
            }
1017
336
            else
1018
336
            {
1019
336
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1020
336
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1021
336
            }
1022
336
        }
1023
1.07k
    }
1024
#else
1025
    {
1026
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1027
        {
1028
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1029
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(3, num_ref_pics_list0);
1030
            else
1031
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1032
1033
            ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
1034
        }
1035
        else
1036
        {
1037
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1038
            {
1039
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1040
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1041
            }
1042
            else
1043
            {
1044
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(1, num_ref_pics_list0);
1045
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1046
            }
1047
        }
1048
    }
1049
#endif
1050
2.76k
#endif
1051
1052
2.76k
    return;
1053
2.76k
}
1054
1055
/*!
1056
******************************************************************************
1057
* \if Function name : ihevce_manage_ref_pics \endif
1058
*
1059
* \brief
1060
*    Reference picture management based on delta poc array given by LAP
1061
*    Populates the reference list after removing non used reference pictures
1062
*    populates the delta poc of reference pics to be signalled in slice header
1063
*
1064
* \param[in] encoder context pointer
1065
* \param[in] current LAP Encoder buffer pointer
1066
* \param[in] current frame process and entropy buffer pointer
1067
*
1068
* \return
1069
*    None
1070
*
1071
* \author
1072
*  Ittiam
1073
*
1074
*****************************************************************************
1075
*/
1076
void ihevce_manage_ref_pics(
1077
    enc_ctxt_t *ps_enc_ctxt,
1078
    ihevce_lap_enc_buf_t *ps_curr_inp,
1079
    slice_header_t *ps_slice_header,
1080
    WORD32 i4_me_frm_id,
1081
    WORD32 i4_thrd_id,
1082
    WORD32 i4_bitrate_instance_id)
1083
2.76k
{
1084
2.76k
    WORD32 ctr;
1085
2.76k
    WORD32 ref_pics;
1086
2.76k
    WORD32 curr_poc, curr_idr_gop_num;
1087
2.76k
    WORD32 wp_flag;
1088
2.76k
    WORD32 num_ref_pics_list0 = 0;
1089
2.76k
    WORD32 num_ref_pics_list1 = 0;
1090
2.76k
    WORD32 cra_poc = ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc;
1091
2.76k
    WORD32 slice_type = ps_slice_header->i1_slice_type;
1092
2.76k
    recon_pic_buf_t *(*aps_ref_list)[HEVCE_MAX_REF_PICS * 2];
1093
2.76k
    recon_pic_buf_t(*aps_ref_list_temp)[HEVCE_MAX_REF_PICS * 2];
1094
2.76k
    WORD32 i4_num_rpics_l0_excl_dup;
1095
2.76k
    WORD32 i4_num_rpics_l1_excl_dup;
1096
2.76k
    WORD32 i4_inc_L1_active_ref_pic = 0;
1097
2.76k
    WORD32 i4_inc_L0_active_ref_pic = 0;
1098
2.76k
    WORD32 i4_bridx = i4_bitrate_instance_id;  //bitrate instance index
1099
2.76k
    WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
1100
2.76k
    me_enc_rdopt_ctxt_t *ps_cur_out_me_prms;
1101
2.76k
    recon_pic_buf_t ***ppps_recon_bufs = ps_enc_ctxt->pps_recon_buf_q;
1102
2.76k
    WORD32 i4_num_recon_bufs = ps_enc_ctxt->ai4_num_buf_recon_q[i4_bridx];
1103
1104
2.76k
    ps_cur_out_me_prms = ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id];
1105
1106
    /*to support diplicate pics*/
1107
2.76k
    {
1108
2.76k
        WORD32 i, j;
1109
8.30k
        for(i = 0; i < NUM_REF_LISTS; i++)
1110
5.53k
        {
1111
94.1k
            for(j = 0; j < HEVCE_MAX_REF_PICS * 2; j++)
1112
88.5k
            {
1113
88.5k
                ps_cur_out_me_prms->aps_ref_list[i4_bridx][i][j] =
1114
88.5k
                    &ps_cur_out_me_prms->as_ref_list[i4_bridx][i][j];
1115
88.5k
            }
1116
5.53k
        }
1117
2.76k
    }
1118
1119
2.76k
    aps_ref_list = ps_cur_out_me_prms->aps_ref_list[i4_bridx];
1120
2.76k
    aps_ref_list_temp = ps_cur_out_me_prms->as_ref_list[i4_bridx];
1121
1122
2.76k
    curr_poc = ps_curr_inp->s_lap_out.i4_poc;
1123
2.76k
    curr_idr_gop_num = ps_curr_inp->s_lap_out.i4_idr_gop_num;
1124
1125
    /* Number of reference pics given by LAP should not be greater than max */
1126
2.76k
    ASSERT(HEVCE_MAX_REF_PICS >= ps_curr_inp->s_lap_out.i4_num_ref_pics);
1127
1128
    /* derive the weighted prediction enable flag based on slice type */
1129
2.76k
    if(BSLICE == slice_type)
1130
36
    {
1131
36
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_bipred_flag;
1132
36
    }
1133
2.73k
    else if(PSLICE == slice_type)
1134
2.15k
    {
1135
2.15k
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_pred_flag;
1136
2.15k
    }
1137
579
    else
1138
579
    {
1139
579
        wp_flag = 0;
1140
579
    }
1141
1142
2.76k
    ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l0 = 0;
1143
2.76k
    ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l1 = 0;
1144
2.76k
    ASSERT(curr_poc != INVALID_POC);
1145
1146
    /* run a loop over the number of reference pics given by LAP */
1147
10.0k
    for(ref_pics = 0; ref_pics < ps_curr_inp->s_lap_out.i4_num_ref_pics; ref_pics++)
1148
7.29k
    {
1149
7.29k
        WORD32 ref_poc;
1150
7.29k
        WORD32 i4_loop = 1;
1151
7.29k
        WORD32 i4_temp_list;
1152
1153
7.29k
        ref_poc = curr_poc + ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_ref_pic_delta_poc;
1154
7.29k
        if((0 == curr_poc) && curr_idr_gop_num)
1155
0
        {
1156
0
            curr_idr_gop_num -= 1;
1157
0
        }
1158
7.29k
        ASSERT(ref_poc != INVALID_POC);
1159
        /* run a loop to check the poc based on delta poc array */
1160
20.7k
        for(ctr = 0; ctr < i4_num_recon_bufs; ctr++)
1161
20.7k
        {
1162
            /* if the POC is matching with current ref picture*/
1163
20.7k
            if((ref_poc == ppps_recon_bufs[i4_bridx][ctr]->i4_poc) &&
1164
7.32k
               (0 == ppps_recon_bufs[i4_bridx][ctr]->i4_is_free) &&
1165
7.32k
               (curr_idr_gop_num == ppps_recon_bufs[i4_bridx][ctr]->i4_idr_gop_num))
1166
7.29k
            {
1167
                /* populate the reference lists based on delta poc array */
1168
7.29k
                if((ref_poc < curr_poc) || (0 == curr_poc))
1169
7.24k
                {
1170
                    /* list 0 */
1171
7.24k
                    memcpy(
1172
7.24k
                        &aps_ref_list_temp[LIST_0][num_ref_pics_list0],
1173
7.24k
                        ppps_recon_bufs[i4_bridx][ctr],
1174
7.24k
                        sizeof(recon_pic_buf_t));
1175
1176
7.24k
                    i4_temp_list = num_ref_pics_list0;
1177
1178
                    /*duplicate pics added to the list*/
1179
7.24k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1180
7.24k
                                         .i4_num_duplicate_entries_in_ref_list)
1181
0
                    {
1182
0
                        i4_temp_list++;
1183
                        /* list 0 */
1184
0
                        memcpy(
1185
0
                            &aps_ref_list_temp[LIST_0][i4_temp_list],
1186
0
                            ppps_recon_bufs[i4_bridx][ctr],
1187
0
                            sizeof(recon_pic_buf_t));
1188
0
                        i4_loop++;
1189
0
                    }
1190
1191
                    /* populate weights and offsets corresponding to this ref pic */
1192
7.24k
                    memcpy(
1193
7.24k
                        &aps_ref_list_temp[LIST_0][num_ref_pics_list0].s_weight_offset,
1194
7.24k
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
1195
7.24k
                        sizeof(ihevce_wght_offst_t));
1196
1197
                    /* Store the used as ref for current pic flag  */
1198
7.24k
                    aps_ref_list_temp[LIST_0][num_ref_pics_list0].i4_used_by_cur_pic_flag =
1199
7.24k
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1200
1201
7.24k
                    if(wp_flag)
1202
0
                    {
1203
0
                        WORD16 i2_luma_weight = (aps_ref_list[LIST_0][num_ref_pics_list0]
1204
0
                                                     ->s_weight_offset.i2_luma_weight);
1205
1206
0
                        aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1207
0
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1208
1209
0
                        aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1210
0
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1211
0
                    }
1212
7.24k
                    else
1213
7.24k
                    {
1214
7.24k
                        WORD16 i2_luma_weight =
1215
7.24k
                            (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1216
1217
7.24k
                        aps_ref_list[LIST_0][num_ref_pics_list0]->s_weight_offset.i2_luma_weight =
1218
7.24k
                            i2_luma_weight;
1219
1220
7.24k
                        aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1221
7.24k
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1222
1223
7.24k
                        aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1224
7.24k
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1225
7.24k
                    }
1226
1227
7.24k
                    num_ref_pics_list0++;
1228
7.24k
                    i4_loop = 1;
1229
1230
                    /*duplicate pics added to the list*/
1231
7.24k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1232
7.24k
                                         .i4_num_duplicate_entries_in_ref_list)
1233
0
                    {
1234
                        /* populate weights and offsets corresponding to this ref pic */
1235
0
                        memcpy(
1236
0
                            &aps_ref_list_temp[LIST_0][num_ref_pics_list0].s_weight_offset,
1237
0
                            &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
1238
0
                            sizeof(ihevce_wght_offst_t));
1239
1240
                        /* Store the used as ref for current pic flag  */
1241
0
                        aps_ref_list_temp[LIST_0][num_ref_pics_list0].i4_used_by_cur_pic_flag =
1242
0
                            ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1243
1244
0
                        if(wp_flag)
1245
0
                        {
1246
0
                            WORD16 i2_luma_weight = (aps_ref_list[LIST_0][num_ref_pics_list0]
1247
0
                                                         ->s_weight_offset.i2_luma_weight);
1248
1249
0
                            aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1250
0
                                ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1251
1252
0
                            aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1253
0
                                ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1254
0
                        }
1255
0
                        else
1256
0
                        {
1257
0
                            WORD16 i2_luma_weight =
1258
0
                                (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1259
1260
0
                            aps_ref_list[LIST_0][num_ref_pics_list0]
1261
0
                                ->s_weight_offset.i2_luma_weight = i2_luma_weight;
1262
1263
0
                            aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1264
0
                                ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1265
1266
0
                            aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1267
0
                                ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1268
0
                        }
1269
1270
0
                        num_ref_pics_list0++;
1271
0
                        i4_loop++;
1272
0
                        ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l0 = 1;
1273
0
                        ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l1 = 1;
1274
0
                    }
1275
7.24k
                }
1276
49
                else
1277
49
                {
1278
                    /* list 1 */
1279
49
                    memcpy(
1280
49
                        &aps_ref_list_temp[LIST_1][num_ref_pics_list1],
1281
49
                        ppps_recon_bufs[i4_bridx][ctr],
1282
49
                        sizeof(recon_pic_buf_t));
1283
49
                    i4_temp_list = num_ref_pics_list1;
1284
                    /*duplicate pics added to the list*/
1285
49
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1286
49
                                         .i4_num_duplicate_entries_in_ref_list)
1287
0
                    {
1288
0
                        i4_temp_list++;
1289
                        /* list 1 */
1290
0
                        memcpy(
1291
0
                            &aps_ref_list_temp[LIST_1][i4_temp_list],
1292
0
                            ppps_recon_bufs[i4_bridx][ctr],
1293
0
                            sizeof(recon_pic_buf_t));
1294
0
                        i4_loop++;
1295
0
                    }
1296
1297
                    /* populate weights and offsets corresponding to this ref pic */
1298
49
                    memcpy(
1299
49
                        &aps_ref_list_temp[LIST_1][num_ref_pics_list1].s_weight_offset,
1300
49
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
1301
49
                        sizeof(ihevce_wght_offst_t));
1302
1303
                    /* Store the used as ref for current pic flag  */
1304
49
                    aps_ref_list_temp[LIST_1][num_ref_pics_list1].i4_used_by_cur_pic_flag =
1305
49
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1306
1307
49
                    if(wp_flag)
1308
0
                    {
1309
0
                        WORD16 i2_luma_weight = (aps_ref_list[LIST_1][num_ref_pics_list1]
1310
0
                                                     ->s_weight_offset.i2_luma_weight);
1311
1312
0
                        aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1313
0
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1314
1315
0
                        aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1316
0
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1317
0
                    }
1318
49
                    else
1319
49
                    {
1320
49
                        WORD16 i2_luma_weight =
1321
49
                            (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1322
1323
49
                        aps_ref_list[LIST_1][num_ref_pics_list1]->s_weight_offset.i2_luma_weight =
1324
49
                            i2_luma_weight;
1325
1326
49
                        aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1327
49
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1328
1329
49
                        aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1330
49
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1331
49
                    }
1332
1333
49
                    num_ref_pics_list1++;
1334
49
                    i4_loop = 1;
1335
                    /*duplicate pics added to the list*/
1336
49
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1337
49
                                         .i4_num_duplicate_entries_in_ref_list)
1338
0
                    {
1339
                        /* populate weights and offsets corresponding to this ref pic */
1340
0
                        memcpy(
1341
0
                            &aps_ref_list_temp[LIST_1][num_ref_pics_list1].s_weight_offset,
1342
0
                            &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[i4_loop],
1343
0
                            sizeof(ihevce_wght_offst_t));
1344
1345
                        /* Store the used as ref for current pic flag  */
1346
0
                        aps_ref_list_temp[LIST_1][num_ref_pics_list1].i4_used_by_cur_pic_flag =
1347
0
                            ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1348
1349
0
                        if(wp_flag)
1350
0
                        {
1351
0
                            WORD16 i2_luma_weight = (aps_ref_list[LIST_1][num_ref_pics_list1]
1352
0
                                                         ->s_weight_offset.i2_luma_weight);
1353
1354
0
                            aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1355
0
                                ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1356
1357
0
                            aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1358
0
                                ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1359
0
                        }
1360
0
                        else
1361
0
                        {
1362
0
                            WORD16 i2_luma_weight =
1363
0
                                (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1364
1365
0
                            aps_ref_list[LIST_1][num_ref_pics_list1]
1366
0
                                ->s_weight_offset.i2_luma_weight = i2_luma_weight;
1367
1368
0
                            aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1369
0
                                ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1370
1371
0
                            aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1372
0
                                ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1373
0
                        }
1374
1375
0
                        num_ref_pics_list1++;
1376
0
                        i4_loop++;
1377
0
                        ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l1 = 1;
1378
0
                        ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l0 = 1;
1379
0
                    }
1380
49
                }
1381
7.29k
                break;
1382
7.29k
            }
1383
20.7k
        }
1384
1385
        /* if the reference picture is not found then error */
1386
7.29k
        ASSERT(ctr != i4_num_recon_bufs);
1387
7.29k
    }
1388
1389
2.76k
    i4_num_rpics_l0_excl_dup = num_ref_pics_list0;
1390
2.76k
    i4_num_rpics_l1_excl_dup = num_ref_pics_list1;
1391
1392
    /* sort the reference pics in List0 in descending order POC */
1393
2.76k
    if(num_ref_pics_list0 > 1)
1394
1.93k
    {
1395
        /* run a loop for num ref pics -1 */
1396
6.88k
        for(ctr = 0; ctr < num_ref_pics_list0 - 1; ctr++)
1397
4.95k
        {
1398
4.95k
            WORD32 max_idx = ctr;
1399
4.95k
            recon_pic_buf_t *ps_temp;
1400
4.95k
            WORD32 i;
1401
1402
14.2k
            for(i = (ctr + 1); i < num_ref_pics_list0; i++)
1403
9.34k
            {
1404
                /* check for poc greater than current ref poc */
1405
9.34k
                if(aps_ref_list[LIST_0][i]->i4_poc > aps_ref_list[LIST_0][max_idx]->i4_poc)
1406
0
                {
1407
0
                    max_idx = i;
1408
0
                }
1409
9.34k
            }
1410
1411
            /* if max of remaining is not current, swap the pointers */
1412
4.95k
            if(max_idx != ctr)
1413
0
            {
1414
0
                ps_temp = aps_ref_list[LIST_0][max_idx];
1415
0
                aps_ref_list[LIST_0][max_idx] = aps_ref_list[LIST_0][ctr];
1416
0
                aps_ref_list[LIST_0][ctr] = ps_temp;
1417
0
            }
1418
4.95k
        }
1419
1.93k
    }
1420
1421
    /* sort the reference pics in List1 in ascending order POC */
1422
2.76k
    if(num_ref_pics_list1 > 1)
1423
13
    {
1424
        /* run a loop for num ref pics -1 */
1425
26
        for(ctr = 0; ctr < num_ref_pics_list1 - 1; ctr++)
1426
13
        {
1427
13
            WORD32 min_idx = ctr;
1428
13
            recon_pic_buf_t *ps_temp;
1429
13
            WORD32 i;
1430
1431
26
            for(i = (ctr + 1); i < num_ref_pics_list1; i++)
1432
13
            {
1433
                /* check for p[oc less than current ref poc */
1434
13
                if(aps_ref_list[LIST_1][i]->i4_poc < aps_ref_list[LIST_1][min_idx]->i4_poc)
1435
0
                {
1436
0
                    min_idx = i;
1437
0
                }
1438
13
            }
1439
1440
            /* if min of remaining is not current, swap the pointers */
1441
13
            if(min_idx != ctr)
1442
0
            {
1443
0
                ps_temp = aps_ref_list[LIST_1][min_idx];
1444
0
                aps_ref_list[LIST_1][min_idx] = aps_ref_list[LIST_1][ctr];
1445
0
                aps_ref_list[LIST_1][ctr] = ps_temp;
1446
0
            }
1447
13
        }
1448
13
    }
1449
1450
    /* popluate the slice header parameters to signal delta POCs and use flags */
1451
2.76k
    {
1452
2.76k
        WORD32 i;
1453
2.76k
        WORD32 prev_poc = curr_poc;
1454
1455
2.76k
        ps_slice_header->s_stref_picset.i1_inter_ref_pic_set_prediction_flag = 0;
1456
1457
2.76k
        ps_slice_header->s_stref_picset.i1_num_neg_pics = num_ref_pics_list0;
1458
1459
2.76k
        ps_slice_header->s_stref_picset.i1_num_pos_pics = num_ref_pics_list1;
1460
1461
2.76k
        ps_slice_header->s_stref_picset.i1_num_ref_idc = -1;
1462
1463
        /* populate the delta POCs of reference pics */
1464
2.76k
        i = 0;
1465
1466
10.0k
        for(ctr = 0; ctr < i4_num_rpics_l0_excl_dup; ctr++)
1467
7.24k
        {
1468
7.24k
            WORD32 ref_poc_l0 = aps_ref_list[LIST_0][i]->i4_poc;
1469
1470
7.24k
            ps_slice_header->s_stref_picset.ai2_delta_poc[ctr] = prev_poc - ref_poc_l0;
1471
7.24k
            ps_slice_header->s_stref_picset.ai1_used[ctr] =
1472
7.24k
                aps_ref_list[LIST_0][i]->i4_used_by_cur_pic_flag;
1473
1474
            /* check if this picture has to be used as reference */
1475
7.24k
            if(1 == ps_slice_header->s_stref_picset.ai1_used[ctr])
1476
7.24k
            {
1477
                /* check for CRA poc related use flag signalling */
1478
7.24k
                ps_slice_header->s_stref_picset.ai1_used[ctr] =
1479
7.24k
                    (curr_poc > cra_poc) ? (ref_poc_l0 >= cra_poc) : (slice_type != ISLICE);
1480
7.24k
            }
1481
7.24k
            if(!(prev_poc - ref_poc_l0))
1482
0
            {
1483
0
                ctr -= 1;
1484
0
                i4_num_rpics_l0_excl_dup -= 1;
1485
0
            }
1486
7.24k
            prev_poc = ref_poc_l0;
1487
1488
7.24k
            i++;
1489
7.24k
        }
1490
1491
2.76k
        i = 0;
1492
2.76k
        prev_poc = curr_poc;
1493
2.81k
        for(; ctr < (i4_num_rpics_l0_excl_dup + i4_num_rpics_l1_excl_dup); ctr++)
1494
49
        {
1495
49
            WORD32 ref_poc_l1 = aps_ref_list[LIST_1][i]->i4_poc;
1496
1497
49
            ps_slice_header->s_stref_picset.ai2_delta_poc[ctr] = ref_poc_l1 - prev_poc;
1498
1499
49
            ps_slice_header->s_stref_picset.ai1_used[ctr] =
1500
49
                aps_ref_list[LIST_1][i]->i4_used_by_cur_pic_flag;
1501
1502
            /* check if this picture has to be used as reference */
1503
49
            if(1 == ps_slice_header->s_stref_picset.ai1_used[ctr])
1504
49
            {
1505
                /* check for CRA poc related use flag signalling */
1506
49
                ps_slice_header->s_stref_picset.ai1_used[ctr] =
1507
49
                    (curr_poc > cra_poc) ? (ref_poc_l1 >= cra_poc) : (slice_type != ISLICE);
1508
                /* (slice_type != ISLICE); */
1509
49
            }
1510
49
            if(!(ref_poc_l1 - prev_poc))
1511
0
            {
1512
0
                ctr -= 1;
1513
0
                i4_num_rpics_l1_excl_dup -= 1;
1514
0
            }
1515
49
            prev_poc = ref_poc_l1;
1516
49
            i++;
1517
49
        }
1518
2.76k
        ps_slice_header->s_stref_picset.i1_num_neg_pics = i4_num_rpics_l0_excl_dup;
1519
1520
2.76k
        ps_slice_header->s_stref_picset.i1_num_pos_pics = i4_num_rpics_l1_excl_dup;
1521
1522
2.76k
        if(IV_IDR_FRAME == ps_curr_inp->s_lap_out.i4_pic_type)
1523
470
        {
1524
470
            ps_slice_header->s_stref_picset.i1_num_neg_pics = 0;
1525
470
            ps_slice_header->s_stref_picset.i1_num_pos_pics = 0;
1526
470
        }
1527
1528
        /* not used so set to -1 */
1529
2.76k
        memset(&ps_slice_header->s_stref_picset.ai1_ref_idc[0], -1, MAX_DPB_SIZE);
1530
2.76k
    }
1531
    /* call the ME API to update the DPB of HME pyramids
1532
    Upadate list for reference bit-rate only */
1533
2.76k
    if(0 == i4_bridx)
1534
2.76k
    {
1535
2.76k
        ihevce_me_frame_dpb_update(
1536
2.76k
            ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
1537
2.76k
            num_ref_pics_list0,
1538
2.76k
            num_ref_pics_list1,
1539
2.76k
            &aps_ref_list[LIST_0][0],
1540
2.76k
            &aps_ref_list[LIST_1][0],
1541
2.76k
            i4_thrd_id);
1542
2.76k
    }
1543
1544
    /* Default list creation based on uses as ref pic for current pic flag */
1545
2.76k
    {
1546
2.76k
        WORD32 num_ref_pics_list_final = 0;
1547
2.76k
        WORD32 list_idx = 0;
1548
1549
        /* LIST 0 */
1550
        /* run a loop for num ref pics in list 0 */
1551
10.0k
        for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
1552
7.24k
        {
1553
            /* check for used as reference flag */
1554
7.24k
            if(1 == aps_ref_list[LIST_0][ctr]->i4_used_by_cur_pic_flag)
1555
7.24k
            {
1556
                /* copy the pointer to the actual valid list idx */
1557
7.24k
                aps_ref_list[LIST_0][list_idx] = aps_ref_list[LIST_0][ctr];
1558
1559
                /* increment the valid pic counters and idx */
1560
7.24k
                list_idx++;
1561
7.24k
                num_ref_pics_list_final++;
1562
7.24k
            }
1563
7.24k
        }
1564
1565
        /* finally store the number of pictures in List0 */
1566
2.76k
        num_ref_pics_list0 = num_ref_pics_list_final;
1567
1568
        /* LIST 1 */
1569
2.76k
        num_ref_pics_list_final = 0;
1570
2.76k
        list_idx = 0;
1571
1572
        /* run a loop for num ref pics in list 1 */
1573
2.81k
        for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
1574
49
        {
1575
            /* check for used as reference flag */
1576
49
            if(1 == aps_ref_list[LIST_1][ctr]->i4_used_by_cur_pic_flag)
1577
49
            {
1578
                /* copy the pointer to the actual valid list idx */
1579
49
                aps_ref_list[LIST_1][list_idx] = aps_ref_list[LIST_1][ctr];
1580
1581
                /* increment the valid pic counters and idx */
1582
49
                list_idx++;
1583
49
                num_ref_pics_list_final++;
1584
49
            }
1585
49
        }
1586
1587
        /* finally store the number of pictures in List1 */
1588
2.76k
        num_ref_pics_list1 = num_ref_pics_list_final;
1589
2.76k
    }
1590
    /*in case of single active ref picture on L0 and L1, then consider one of them weighted
1591
    and another non-weighted*/
1592
2.76k
    if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1593
2.15k
    {
1594
2.15k
        if(num_ref_pics_list0 > 2)
1595
1.54k
        {
1596
1.54k
            if(aps_ref_list[LIST_0][0]->i4_poc == aps_ref_list[LIST_0][1]->i4_poc)
1597
0
            {
1598
0
                i4_inc_L0_active_ref_pic = 1;
1599
0
            }
1600
1.54k
        }
1601
2.15k
    }
1602
615
    else
1603
615
    {
1604
615
        if(num_ref_pics_list0 >= 2 && num_ref_pics_list1 >= 2)
1605
4
        {
1606
4
            if(aps_ref_list[LIST_0][0]->i4_poc == aps_ref_list[LIST_0][1]->i4_poc)
1607
0
            {
1608
0
                i4_inc_L0_active_ref_pic = 1;
1609
0
            }
1610
1611
4
            if(aps_ref_list[LIST_1][0]->i4_poc == aps_ref_list[LIST_1][1]->i4_poc)
1612
0
            {
1613
0
                i4_inc_L1_active_ref_pic = 1;
1614
0
            }
1615
4
        }
1616
615
    }
1617
    /* append the reference pics in List1 and end of list0 */
1618
2.81k
    for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
1619
49
    {
1620
49
        aps_ref_list[LIST_0][num_ref_pics_list0 + ctr] = aps_ref_list[LIST_1][ctr];
1621
49
    }
1622
1623
    /* append the reference pics in List0 and end of list1 */
1624
10.0k
    for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
1625
7.24k
    {
1626
7.24k
        aps_ref_list[LIST_1][num_ref_pics_list1 + ctr] = aps_ref_list[LIST_0][ctr];
1627
7.24k
    }
1628
1629
    /* reference list modification for adding duplicate reference */
1630
2.76k
    {
1631
2.76k
        WORD32 i4_latest_idx = 0;
1632
2.76k
        recon_pic_buf_t *ps_ref_list_cur;
1633
2.76k
        recon_pic_buf_t *ps_ref_list_prev;
1634
        /*List 0*/
1635
2.76k
        ps_ref_list_cur = aps_ref_list[LIST_0][0];
1636
2.76k
        ps_ref_list_prev = ps_ref_list_cur;
1637
10.0k
        for(ctr = 0; ctr < (num_ref_pics_list0 + num_ref_pics_list1); ctr++)
1638
7.29k
        {
1639
7.29k
            if(ps_ref_list_cur->i4_poc != ps_ref_list_prev->i4_poc)
1640
5.00k
            {
1641
5.00k
                i4_latest_idx++;
1642
5.00k
            }
1643
7.29k
            ps_ref_list_prev = ps_ref_list_cur;
1644
7.29k
            ps_slice_header->s_rplm.i4_ref_poc_l0[ctr] = ps_ref_list_cur->i4_poc;
1645
7.29k
            ps_slice_header->s_rplm.i1_list_entry_l0[ctr] = i4_latest_idx;
1646
7.29k
            if((ctr + 1) < (num_ref_pics_list0 + num_ref_pics_list1))
1647
5.00k
            {
1648
5.00k
                ps_ref_list_cur = aps_ref_list[LIST_0][ctr + 1];
1649
5.00k
            }
1650
7.29k
        } /*end for*/
1651
1652
        /*LIST 1*/
1653
2.76k
        i4_latest_idx = 0;
1654
2.76k
        ps_ref_list_cur = aps_ref_list[LIST_1][0];
1655
2.76k
        ps_ref_list_prev = ps_ref_list_cur;
1656
10.0k
        for(ctr = 0; ctr < (num_ref_pics_list0 + num_ref_pics_list1); ctr++)
1657
7.29k
        {
1658
7.29k
            if(ps_ref_list_cur->i4_poc != ps_ref_list_prev->i4_poc)
1659
5.00k
            {
1660
5.00k
                i4_latest_idx++;
1661
5.00k
            }
1662
7.29k
            ps_ref_list_prev = ps_ref_list_cur;
1663
7.29k
            ps_slice_header->s_rplm.i4_ref_poc_l1[ctr] = ps_ref_list_cur->i4_poc;
1664
7.29k
            ps_slice_header->s_rplm.i1_list_entry_l1[ctr] = i4_latest_idx;
1665
7.29k
            if((ctr + 1) < (num_ref_pics_list0 + num_ref_pics_list1))
1666
5.00k
            {
1667
5.00k
                ps_ref_list_cur = aps_ref_list[LIST_1][ctr + 1];
1668
5.00k
            }
1669
7.29k
        } /*end for*/
1670
2.76k
    }
1671
1672
    /* set number of active references used for l0 and l1 in slice hdr */
1673
2.76k
    ps_slice_header->i1_num_ref_idx_active_override_flag = 1;
1674
2.76k
    ps_slice_header->i1_num_ref_idx_l0_active = num_ref_pics_list0 + num_ref_pics_list1;
1675
2.76k
    if(BSLICE == slice_type)
1676
36
    {
1677
        /* i1_num_ref_idx_l1_active applicable only for B pics */
1678
36
        ps_slice_header->i1_num_ref_idx_l1_active = num_ref_pics_list0 + num_ref_pics_list1;
1679
36
    }
1680
    /* popluate the slice header parameters with weights and offsets */
1681
2.76k
    {
1682
2.76k
        WORD32 i;
1683
1684
        /* populate the log 2 weight denom if weighted prediction is enabled */
1685
2.76k
        if(1 == wp_flag)
1686
0
        {
1687
0
            ps_slice_header->s_wt_ofst.i1_chroma_log2_weight_denom =
1688
0
                ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom;
1689
0
            ps_slice_header->s_wt_ofst.i1_luma_log2_weight_denom =
1690
0
                ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1691
0
        }
1692
1693
        /* populate the weights and offsets for all pics in L0 + L1 */
1694
10.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
1695
7.29k
        {
1696
            /* populate the weights and offsets if weighted prediction is enabled */
1697
7.29k
            if(1 == wp_flag)
1698
0
            {
1699
0
                ps_slice_header->s_wt_ofst.i1_luma_weight_l0_flag[i] =
1700
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.u1_luma_weight_enable_flag;
1701
1702
                /* if weights are enabled then copy to slice header */
1703
0
                if(1 == ps_slice_header->s_wt_ofst.i1_luma_weight_l0_flag[i])
1704
0
                {
1705
0
                    ps_slice_header->s_wt_ofst.i2_luma_weight_l0[i] =
1706
0
                        aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_weight;
1707
0
                    ps_slice_header->s_wt_ofst.i2_luma_offset_l0[i] =
1708
0
                        aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_offset;
1709
1710
0
                    {
1711
0
                        WORD16 i2_luma_weight =
1712
0
                            (aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_weight);
1713
1714
0
                        aps_ref_list[LIST_0][i]->i4_inv_luma_wt =
1715
0
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1716
1717
0
                        aps_ref_list[LIST_0][i]->i4_log2_wt_denom =
1718
0
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1719
0
                    }
1720
0
                }
1721
0
                else
1722
0
                {
1723
0
                    WORD16 i2_luma_weight = (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1724
1725
                    /* set to default values */
1726
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_weight = (i2_luma_weight);
1727
1728
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.i2_luma_offset = 0;
1729
1730
0
                    aps_ref_list[LIST_0][i]->i4_inv_luma_wt =
1731
0
                        ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1732
1733
0
                    aps_ref_list[LIST_0][i]->i4_log2_wt_denom =
1734
0
                        ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1735
0
                }
1736
1737
0
                ps_slice_header->s_wt_ofst.i1_chroma_weight_l0_flag[i] =
1738
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.u1_chroma_weight_enable_flag;
1739
1740
                /* if weights are enabled then copy to slice header */
1741
0
                if(1 == ps_slice_header->s_wt_ofst.i1_chroma_weight_l0_flag[i])
1742
0
                {
1743
0
                    ps_slice_header->s_wt_ofst.i2_chroma_weight_l0_cb[i] =
1744
0
                        aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_weight;
1745
0
                    ps_slice_header->s_wt_ofst.i2_chroma_offset_l0_cb[i] =
1746
0
                        aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_offset;
1747
1748
0
                    ps_slice_header->s_wt_ofst.i2_chroma_weight_l0_cr[i] =
1749
0
                        aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_weight;
1750
0
                    ps_slice_header->s_wt_ofst.i2_chroma_offset_l0_cr[i] =
1751
0
                        aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_offset;
1752
0
                }
1753
0
                else
1754
0
                {
1755
                    /* set to default values */
1756
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_weight =
1757
0
                        (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1758
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_weight =
1759
0
                        (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1760
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.i2_cb_offset = 0;
1761
0
                    aps_ref_list[LIST_0][i]->s_weight_offset.i2_cr_offset = 0;
1762
0
                }
1763
0
            }
1764
7.29k
        }
1765
1766
10.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
1767
7.29k
        {
1768
            /* populate the weights and offsets if weighted prediction is enabled */
1769
7.29k
            if(1 == wp_flag)
1770
0
            {
1771
0
                ps_slice_header->s_wt_ofst.i1_luma_weight_l1_flag[i] =
1772
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.u1_luma_weight_enable_flag;
1773
1774
                /* if weights are enabled then copy to slice header */
1775
0
                if(1 == ps_slice_header->s_wt_ofst.i1_luma_weight_l1_flag[i])
1776
0
                {
1777
0
                    ps_slice_header->s_wt_ofst.i2_luma_weight_l1[i] =
1778
0
                        aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_weight;
1779
0
                    ps_slice_header->s_wt_ofst.i2_luma_offset_l1[i] =
1780
0
                        aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_offset;
1781
1782
0
                    {
1783
0
                        WORD16 i2_luma_weight =
1784
0
                            (aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_weight);
1785
1786
0
                        aps_ref_list[LIST_1][i]->i4_inv_luma_wt =
1787
0
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1788
1789
0
                        aps_ref_list[LIST_1][i]->i4_log2_wt_denom =
1790
0
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1791
0
                    }
1792
0
                }
1793
0
                else
1794
0
                {
1795
0
                    WORD16 i2_luma_weight = (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1796
1797
                    /* set to default values */
1798
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_weight = (i2_luma_weight);
1799
1800
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.i2_luma_offset = 0;
1801
1802
0
                    aps_ref_list[LIST_1][i]->i4_inv_luma_wt =
1803
0
                        ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1804
1805
0
                    aps_ref_list[LIST_1][i]->i4_log2_wt_denom =
1806
0
                        ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1807
0
                }
1808
1809
0
                ps_slice_header->s_wt_ofst.i1_chroma_weight_l1_flag[i] =
1810
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.u1_chroma_weight_enable_flag;
1811
1812
                /* if weights are enabled then copy to slice header */
1813
0
                if(1 == ps_slice_header->s_wt_ofst.i1_chroma_weight_l1_flag[i])
1814
0
                {
1815
0
                    ps_slice_header->s_wt_ofst.i2_chroma_weight_l1_cb[i] =
1816
0
                        aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_weight;
1817
0
                    ps_slice_header->s_wt_ofst.i2_chroma_offset_l1_cb[i] =
1818
0
                        aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_offset;
1819
1820
0
                    ps_slice_header->s_wt_ofst.i2_chroma_weight_l1_cr[i] =
1821
0
                        aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_weight;
1822
0
                    ps_slice_header->s_wt_ofst.i2_chroma_offset_l1_cr[i] =
1823
0
                        aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_offset;
1824
0
                }
1825
0
                else
1826
0
                {
1827
                    /* set to default values */
1828
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_weight =
1829
0
                        (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1830
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_weight =
1831
0
                        (1 << ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom);
1832
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.i2_cb_offset = 0;
1833
0
                    aps_ref_list[LIST_1][i]->s_weight_offset.i2_cr_offset = 0;
1834
0
                }
1835
0
            }
1836
7.29k
        }
1837
2.76k
    }
1838
1839
    /* store the number of reference pics in the list for ME/MC etc */
1840
2.76k
    ps_enc_ctxt->i4_num_ref_l0 = num_ref_pics_list0;
1841
2.76k
    ps_enc_ctxt->i4_num_ref_l1 = num_ref_pics_list1;
1842
1843
2.76k
#define HME_USE_ONLY_2REF
1844
#ifndef HME_USE_ONLY_2REF
1845
    ps_enc_ctxt->i4_num_ref_l0_active = num_ref_pics_list0;
1846
    ps_enc_ctxt->i4_num_ref_l1_active = num_ref_pics_list1;
1847
#else
1848
2.76k
#if MULTI_REF_ENABLE == 1
1849
2.76k
    if(ps_curr_inp->s_lap_out.i4_quality_preset >= IHEVCE_QUALITY_P3)
1850
1.69k
    {
1851
1.69k
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1852
1.41k
        {
1853
1.41k
            if(ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6)
1854
194
            {
1855
194
                if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1856
0
                {
1857
0
                    ps_enc_ctxt->i4_num_ref_l0_active =
1858
0
                        MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25 + 1, num_ref_pics_list0);
1859
0
                }
1860
194
                else
1861
194
                {
1862
194
                    ps_enc_ctxt->i4_num_ref_l0_active =
1863
194
                        MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25, num_ref_pics_list0);
1864
1865
194
                    ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1866
194
                }
1867
194
            }
1868
1.22k
            else
1869
1.22k
            {
1870
1.22k
                if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1871
0
                {
1872
0
                    ps_enc_ctxt->i4_num_ref_l0_active = MIN(3, num_ref_pics_list0);
1873
0
                }
1874
1.22k
                else
1875
1.22k
                {
1876
1.22k
                    ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1877
1.22k
                    ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1878
1.22k
                }
1879
1.22k
            }
1880
1881
1.41k
            ps_enc_ctxt->i4_num_ref_l1_active = 0;
1882
1.41k
        }
1883
279
        else
1884
279
        {
1885
279
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1886
0
            {
1887
0
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1888
0
                ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1889
0
                ps_enc_ctxt->i4_num_ref_l1_active += i4_inc_L1_active_ref_pic;
1890
0
            }
1891
279
            else
1892
279
            {
1893
279
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(1, num_ref_pics_list0);
1894
279
                ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1895
1896
279
                ps_enc_ctxt->i4_num_ref_l1_active += i4_inc_L1_active_ref_pic;
1897
279
                ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1898
279
            }
1899
279
        }
1900
1.69k
    }
1901
1.07k
    else
1902
1.07k
    {
1903
1.07k
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1904
735
        {
1905
735
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1906
0
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1907
735
            else
1908
735
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1909
1910
735
            ps_enc_ctxt->i4_num_ref_l1_active = 0;
1911
735
        }
1912
336
        else
1913
336
        {
1914
336
            if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1915
0
            {
1916
0
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1917
0
                ps_enc_ctxt->i4_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1918
0
            }
1919
336
            else
1920
336
            {
1921
336
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1922
336
                ps_enc_ctxt->i4_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1923
336
            }
1924
336
        }
1925
1.07k
    }
1926
#else
1927
    if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1928
    {
1929
        if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1930
            ps_enc_ctxt->i4_num_ref_l0_active = MIN(3, num_ref_pics_list0);
1931
        else
1932
            ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1933
1934
        ps_enc_ctxt->i4_num_ref_l1_active = 0;
1935
    }
1936
    else
1937
    {
1938
        if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1939
        {
1940
            ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1941
            ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1942
        }
1943
        else
1944
        {
1945
            ps_enc_ctxt->i4_num_ref_l0_active = MIN(1, num_ref_pics_list0);
1946
            ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1947
        }
1948
    }
1949
#endif
1950
1951
2.76k
#endif
1952
1953
2.76k
    ps_slice_header->i1_num_ref_idx_l0_active = MAX(1, ps_enc_ctxt->i4_num_ref_l0_active);
1954
2.76k
    if(BSLICE == slice_type)
1955
36
    {
1956
        /* i1_num_ref_idx_l1_active applicable only for B pics */
1957
36
        ps_slice_header->i1_num_ref_idx_l1_active = MAX(1, ps_enc_ctxt->i4_num_ref_l1_active);
1958
36
    }
1959
2.76k
    if(1 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
1960
0
    {
1961
        /* If Interlace field is enabled,  p field following an cra I field should have only one ref frame */
1962
0
        WORD32 cra_second_poc = cra_poc + 1;
1963
1964
0
        if(curr_poc == cra_second_poc)
1965
0
        {
1966
            /*   set number of active references used for l0 and l1 for me  */
1967
0
            ps_enc_ctxt->i4_num_ref_l0_active = 1;
1968
0
            ps_enc_ctxt->i4_num_ref_l1_active = 0;
1969
1970
            /*   set number of active references used for l0 and l1 in slice hdr */
1971
0
            ps_slice_header->i1_num_ref_idx_active_override_flag = 1;
1972
0
            ps_slice_header->i1_num_ref_idx_l0_active =
1973
0
                ps_enc_ctxt->i4_num_ref_l0 + ps_enc_ctxt->i4_num_ref_l1;
1974
0
        }
1975
0
    }
1976
2.76k
    return;
1977
2.76k
}
1978
1979
/*!
1980
******************************************************************************
1981
* \if Function name : ihevce_get_frame_lambda_prms \endif
1982
*
1983
* \brief
1984
*    Function whihc calculates the Lambda params for current picture
1985
*
1986
* \param[in] ps_enc_ctxt : encoder ctxt pointer
1987
* \param[in] ps_cur_pic_ctxt : current pic ctxt
1988
* \param[in] i4_cur_frame_qp : current pic QP
1989
* \param[in] first_field : is first field flag
1990
* \param[in] i4_temporal_lyr_id : Current picture layer id
1991
*
1992
* \return
1993
*    None
1994
*
1995
* \author
1996
*  Ittiam
1997
*
1998
*****************************************************************************
1999
*/
2000
void ihevce_get_frame_lambda_prms(
2001
    enc_ctxt_t *ps_enc_ctxt,
2002
    pre_enc_me_ctxt_t *ps_cur_pic_ctxt,
2003
    WORD32 i4_cur_frame_qp,
2004
    WORD32 first_field,
2005
    WORD32 i4_is_ref_pic,
2006
    WORD32 i4_temporal_lyr_id,
2007
    double f_i_pic_lamda_modifier,
2008
    WORD32 i4_inst_id,
2009
    WORD32 i4_lambda_type)
2010
10.4k
{
2011
10.4k
    double lambda_modifier = CONST_LAMDA_MOD_VAL;
2012
10.4k
    double lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2013
10.4k
    double lambda = 0;
2014
10.4k
    double lambda_uv;
2015
10.4k
    WORD32 i4_use_const_lamda_modifier;
2016
2017
    /* initialize lambda based on frm qp, slice type, num b and temporal id */
2018
    /* This lamba calculation mimics the jctvc doc (TODO add doc number     */
2019
2020
10.4k
    WORD32 num_b_frms =
2021
10.4k
        (1 << ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers) - 1;
2022
10.4k
    WORD32 chroma_qp = (ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format == IV_YUV_422SP_UV)
2023
10.4k
                           ? MIN(i4_cur_frame_qp, 51)
2024
10.4k
                           : gai1_ihevc_chroma_qp_scale[i4_cur_frame_qp + MAX_QP_BD_OFFSET];
2025
2026
10.4k
    WORD32 i4_qp_bdoffset =
2027
10.4k
        6 * (ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8);
2028
10.4k
    WORD32 slice_type = ps_cur_pic_ctxt->s_slice_hdr.i1_slice_type;
2029
2030
10.4k
    (void)first_field;
2031
10.4k
    (void)i4_is_ref_pic;
2032
10.4k
    (void)i4_temporal_lyr_id;
2033
10.4k
    i4_use_const_lamda_modifier = USE_CONSTANT_LAMBDA_MODIFIER;
2034
10.4k
    i4_use_const_lamda_modifier = i4_use_const_lamda_modifier ||
2035
10.4k
                                  ((ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2036
10.4k
                                    (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER)) &&
2037
0
                                   ((ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2038
0
                                     (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION)) ||
2039
0
                                    (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2040
0
                                     (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_1)) ||
2041
0
                                    (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2042
0
                                     (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_2)) ||
2043
0
                                    (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2044
0
                                     (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_PSYRDOPT_3))));
2045
2046
    /* lambda modifier is the dependent on slice type and temporal id  */
2047
10.4k
    if(ISLICE == slice_type)
2048
2.21k
    {
2049
2.21k
        double temporal_correction_islice = 1.0 - 0.05 * num_b_frms;
2050
2.21k
        temporal_correction_islice = MAX(0.5, temporal_correction_islice);
2051
2052
2.21k
        lambda_modifier = 0.57 * temporal_correction_islice;
2053
2.21k
        lambda_uv_modifier = lambda_modifier;
2054
2.21k
        if(i4_use_const_lamda_modifier)
2055
0
        {
2056
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = f_i_pic_lamda_modifier;
2057
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = f_i_pic_lamda_modifier;
2058
0
        }
2059
2.21k
        else
2060
2.21k
        {
2061
2.21k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2062
2.21k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2063
2.21k
        }
2064
2.21k
    }
2065
8.27k
    else if(PSLICE == slice_type)
2066
8.12k
    {
2067
8.12k
        if(first_field)
2068
6.61k
            lambda_modifier = 0.442;  //0.442*0.8;
2069
1.50k
        else
2070
1.50k
            lambda_modifier = 0.442;
2071
8.12k
        lambda_uv_modifier = lambda_modifier;
2072
8.12k
        if(i4_use_const_lamda_modifier)
2073
0
        {
2074
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = CONST_LAMDA_MOD_VAL;
2075
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2076
0
        }
2077
8.12k
        else
2078
8.12k
        {
2079
8.12k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2080
8.12k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2081
8.12k
        }
2082
8.12k
    }
2083
154
    else
2084
154
    {
2085
        /* BSLICE */
2086
154
        if(1 == i4_is_ref_pic)
2087
51
        {
2088
51
            lambda_modifier = 0.3536;
2089
51
        }
2090
103
        else if(2 == i4_is_ref_pic)
2091
0
        {
2092
0
            lambda_modifier = 0.45;
2093
0
        }
2094
103
        else
2095
103
        {
2096
103
            lambda_modifier = 0.68;
2097
103
        }
2098
154
        lambda_uv_modifier = lambda_modifier;
2099
154
        if(i4_use_const_lamda_modifier)
2100
0
        {
2101
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = CONST_LAMDA_MOD_VAL;
2102
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2103
0
        }
2104
154
        else
2105
154
        {
2106
154
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2107
154
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2108
154
        }
2109
        /* TODO: Disable lambda modification for interlace encode to match HM runs */
2110
        //if(0 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
2111
154
        {
2112
            /* modify b lambda further based on temporal id */
2113
154
            if(i4_temporal_lyr_id)
2114
153
            {
2115
153
                lambda_modifier *= CLIP3((((double)(i4_cur_frame_qp - 12)) / 6.0), 2.00, 4.00);
2116
153
                lambda_uv_modifier *= CLIP3((((double)(chroma_qp - 12)) / 6.0), 2.00, 4.00);
2117
153
            }
2118
154
        }
2119
154
    }
2120
10.4k
    if(i4_use_const_lamda_modifier)
2121
0
    {
2122
0
        if(ISLICE == slice_type)
2123
0
        {
2124
0
            lambda_modifier = f_i_pic_lamda_modifier;
2125
0
            lambda_uv_modifier = f_i_pic_lamda_modifier;
2126
0
        }
2127
0
        else
2128
0
        {
2129
0
            lambda_modifier = CONST_LAMDA_MOD_VAL;
2130
0
            lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2131
0
        }
2132
0
    }
2133
2134
10.4k
    switch(i4_lambda_type)
2135
10.4k
    {
2136
7.72k
    case 0:
2137
7.72k
    {
2138
7.72k
        i4_qp_bdoffset = 0;
2139
2140
7.72k
        lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2141
7.72k
        lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bdoffset - 12)) / 3.0));
2142
2143
        /* modify the base lambda according to lambda modifier */
2144
7.72k
        lambda *= lambda_modifier;
2145
7.72k
        lambda_uv *= lambda_uv_modifier;
2146
2147
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2148
7.72k
            (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2149
2150
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2151
7.72k
            (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2152
2153
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2154
7.72k
            (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2155
2156
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2157
7.72k
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2158
7.72k
        if(i4_use_const_lamda_modifier)
2159
0
        {
2160
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2161
0
                (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2162
2163
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2164
0
                (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2165
2166
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2167
0
                (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2168
0
        }
2169
7.72k
        else
2170
7.72k
        {
2171
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2172
7.72k
                (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2173
2174
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2175
7.72k
                (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2176
2177
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2178
7.72k
                (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2179
7.72k
        }
2180
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2181
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf;
2182
2183
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2184
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf;
2185
2186
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2187
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf;
2188
2189
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2190
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf;
2191
2192
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2193
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf;
2194
2195
7.72k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2196
7.72k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf;
2197
2198
7.72k
        break;
2199
0
    }
2200
0
    case 1:
2201
0
    {
2202
0
        lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2203
0
        lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bdoffset - 12)) / 3.0));
2204
2205
        /* modify the base lambda according to lambda modifier */
2206
0
        lambda *= lambda_modifier;
2207
0
        lambda_uv *= lambda_uv_modifier;
2208
2209
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2210
0
            (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2211
2212
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2213
0
            (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2214
2215
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2216
0
            (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2217
2218
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2219
0
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2220
0
        if(i4_use_const_lamda_modifier)
2221
0
        {
2222
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2223
0
                (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2224
2225
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2226
0
                (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2227
2228
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2229
0
                (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2230
0
        }
2231
0
        else
2232
0
        {
2233
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2234
0
                (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2235
2236
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2237
0
                (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2238
2239
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2240
0
                (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2241
0
        }
2242
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2243
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf;
2244
2245
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2246
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf;
2247
2248
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2249
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf;
2250
2251
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2252
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf;
2253
2254
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2255
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf;
2256
2257
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2258
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf;
2259
2260
0
        break;
2261
0
    }
2262
2.76k
    case 2:
2263
2.76k
    {
2264
2.76k
        lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2265
2.76k
        lambda_uv = pow(2.0, (((double)(chroma_qp + i4_qp_bdoffset - 12)) / 3.0));
2266
2267
        /* modify the base lambda according to lambda modifier */
2268
2.76k
        lambda *= lambda_modifier;
2269
2.76k
        lambda_uv *= lambda_uv_modifier;
2270
2271
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2272
2.76k
            (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2273
2274
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2275
2.76k
            (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2276
2277
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2278
2.76k
            (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2279
2280
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2281
2.76k
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2282
2283
2.76k
        if(i4_use_const_lamda_modifier)
2284
0
        {
2285
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2286
0
                (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2287
2288
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2289
0
                (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2290
2291
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2292
0
                (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2293
0
        }
2294
2.76k
        else
2295
2.76k
        {
2296
2.76k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2297
2.76k
                (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2298
2299
2.76k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2300
2.76k
                (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2301
2302
2.76k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2303
2.76k
                (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2304
2.76k
        }
2305
        /* lambda corresponding to 8- bit, for metrics based on 8- bit ( Example 8bit SAD in encloop)*/
2306
2307
2.76k
        lambda = pow(2.0, (((double)(i4_cur_frame_qp - 12)) / 3.0));
2308
2.76k
        lambda_uv = pow(2.0, (((double)(chroma_qp - 12)) / 3.0));
2309
2310
        /* modify the base lambda according to lambda modifier */
2311
2.76k
        lambda *= lambda_modifier;
2312
2.76k
        lambda_uv *= lambda_uv_modifier;
2313
2314
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2315
2.76k
            (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2316
2317
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2318
2.76k
            (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2319
2320
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2321
2.76k
            (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2322
2323
2.76k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2324
2.76k
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2325
2.76k
        if(i4_use_const_lamda_modifier)
2326
0
        {
2327
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2328
0
                (WORD32)((sqrt(lambda)) * (1 << LAMBDA_Q_SHIFT));
2329
2330
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2331
0
                (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2332
2333
0
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2334
0
                (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2335
0
        }
2336
2.76k
        else
2337
2.76k
        {
2338
2.76k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2339
2.76k
                (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2340
2341
2.76k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2342
2.76k
                (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2343
2344
2.76k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2345
2.76k
                (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2346
2.76k
        }
2347
2348
2.76k
        break;
2349
0
    }
2350
0
    default:
2351
0
    {
2352
        /* Intended to be a barren wasteland! */
2353
0
        ASSERT(0);
2354
0
    }
2355
10.4k
    }
2356
2357
    /* Assign the final lambdas after up shifting to its q format */
2358
2359
    /* closed loop ssd lambda is same as final lambda */
2360
2361
    /* --- Initialized the lambda for SATD computations --- */
2362
10.4k
    if(i4_use_const_lamda_modifier)
2363
0
    {
2364
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2365
0
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2366
2367
0
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2368
0
            (WORD32)((sqrt(lambda)) * (1 << (LAMBDA_Q_SHIFT)));
2369
0
    }
2370
10.4k
    else
2371
10.4k
    {
2372
10.4k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2373
10.4k
            (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2374
2375
10.4k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2376
10.4k
            (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2377
10.4k
    }
2378
10.4k
}
2379
2380
/*!
2381
******************************************************************************
2382
* \if Function name : ihevce_update_qp_L1_sad_based \endif
2383
*
2384
* \brief
2385
*    Function which recalculates qp in case of scene cut based on L1 satd/act
2386
*
2387
* \param[in] ps_enc_ctxt : encoder ctxt pointer
2388
* \param[in] ps_cur_pic_ctxt : current pic ctxt
2389
* \param[in] i4_cur_frame_qp : current pic QP
2390
* \param[in] first_field : is first field flag
2391
* \param[in] i4_temporal_lyr_id : Current picture layer id
2392
*
2393
* \return
2394
*    None
2395
*
2396
* \author
2397
*  Ittiam
2398
*
2399
*****************************************************************************
2400
*/
2401
void ihevce_update_qp_L1_sad_based(
2402
    enc_ctxt_t *ps_enc_ctxt,
2403
    ihevce_lap_enc_buf_t *ps_curr_inp,
2404
    ihevce_lap_enc_buf_t *ps_prev_inp,
2405
    pre_enc_me_ctxt_t *ps_curr_out,
2406
    WORD32 i4_is_last_thread)
2407
2.76k
{
2408
2.76k
    WORD32 i4_l1_ht, i4_l1_wd;
2409
2.76k
    ihevce_ed_blk_t *ps_ed_4x4 = ps_curr_out->ps_layer1_buf;
2410
2.76k
    WORD32 best_satd_16x16;
2411
    //LWORD64 acc_satd = 0;
2412
2.76k
    LWORD64 acc_sad = 0; /*SAD accumulated to compare with coarse me sad*/
2413
2.76k
    WORD32 i4_tot_4x4block_l1_x, i4_tot_4x4block_l1_y;
2414
2.76k
    WORD32 i4_tot_ctb_l1_x, i4_tot_ctb_l1_y;
2415
2.76k
    WORD32 i;
2416
2.76k
    WORD32 i4_act_factor;
2417
2.76k
    UWORD8 u1_cu_possible_qp;
2418
2.76k
    WORD32 i4_q_scale_mod;
2419
2.76k
    LWORD64 i8_best_satd_16x16;
2420
2.76k
    LWORD64 i8_frame_satd_by_act_L1_accum;
2421
2.76k
    LWORD64 i8_frame_acc_sadt_L1, i8_frame_acc_sadt_L1_squared;
2422
2.76k
    WORD32 i4_new_frame_qp = 0, i4_qp_for_I_pic = 0;
2423
2.76k
    LWORD64 pre_intra_satd_act_evaluated = 0;
2424
2.76k
    ihevce_ed_ctb_l1_t *ps_ed_ctb_l1 = ps_curr_out->ps_ed_ctb_l1;
2425
2.76k
    WORD32 i4_j;
2426
2.76k
    double scale_factor_cmplx_change_detection;
2427
2.76k
    WORD32 i4_cmplx_change_detection_thrsh;
2428
2.76k
    long double ld_frame_avg_satd_L1;
2429
2430
2.76k
    if(i4_is_last_thread)
2431
2.76k
    {
2432
2.76k
        ihevce_decomp_pre_intra_master_ctxt_t *ps_master_ctxt =
2433
2.76k
            (ihevce_decomp_pre_intra_master_ctxt_t *)
2434
2.76k
                ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt;
2435
2.76k
        ihevce_decomp_pre_intra_ctxt_t *ps_ctxt = ps_master_ctxt->aps_decomp_pre_intra_thrd_ctxt[0];
2436
2437
2.76k
        i4_l1_wd = ps_ctxt->as_layers[1].i4_actual_wd;
2438
2.76k
        i4_l1_ht = ps_ctxt->as_layers[1].i4_actual_ht;
2439
2440
2.76k
        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2441
233
           (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2442
0
        {
2443
0
            i8_frame_acc_sadt_L1 = -1;
2444
0
        }
2445
2.76k
        else
2446
2.76k
        {
2447
            /*the accumulation of intra satd and calculation of new qp happens for all thread
2448
    It must be made sure every thread returns same value of intra satd and qp*/
2449
2.76k
            i8_frame_acc_sadt_L1 = ihevce_decomp_pre_intra_get_frame_satd(
2450
2.76k
                ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt, &i4_l1_wd, &i4_l1_ht);
2451
2.76k
        }
2452
2453
2.76k
#if USE_SQRT_AVG_OF_SATD_SQR
2454
2.76k
        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2455
233
           (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2456
0
        {
2457
0
            i8_frame_acc_sadt_L1_squared = 0x7fffffff;
2458
0
        }
2459
2.76k
        else
2460
2.76k
        {
2461
2.76k
            i8_frame_acc_sadt_L1_squared = ihevce_decomp_pre_intra_get_frame_satd_squared(
2462
2.76k
                ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt, &i4_l1_wd, &i4_l1_ht);
2463
2.76k
        }
2464
#else
2465
        i8_frame_acc_sadt_L1_squared = i8_frame_acc_sadt_L1;
2466
#endif
2467
2.76k
        if((i4_l1_wd * i4_l1_ht) > (245760 /*640 * 384*/))
2468
0
        {
2469
0
            scale_factor_cmplx_change_detection =
2470
0
                (double)0.12 * ((i4_l1_wd * i4_l1_ht) / (640.0 * 384.0));
2471
0
            i4_cmplx_change_detection_thrsh =
2472
0
                (WORD32)(HME_HIGH_SAD_BLK_THRESH * (1 - scale_factor_cmplx_change_detection));
2473
0
        }
2474
2.76k
        else
2475
2.76k
        {
2476
2.76k
            scale_factor_cmplx_change_detection =
2477
2.76k
                (double)0.12 * ((640.0 * 384.0) / (i4_l1_wd * i4_l1_ht));
2478
2.76k
            i4_cmplx_change_detection_thrsh =
2479
2.76k
                (WORD32)(HME_HIGH_SAD_BLK_THRESH * (1 + scale_factor_cmplx_change_detection));
2480
2.76k
        }
2481
2.76k
        i4_tot_4x4block_l1_x =
2482
2.76k
            ((i4_l1_wd + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) /
2483
2.76k
            4;  //((i4_l1_wd + 31) & 0xFFFFFFE0)/4;//(i4_l1_wd + (i4_l1_wd % 32 )) / 4;
2484
2.76k
        i4_tot_4x4block_l1_y =
2485
2.76k
            ((i4_l1_ht + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) /
2486
2.76k
            4;  //((i4_l1_ht + 31) & 0xFFFFFFE0)/4;//(i4_l1_ht + (i4_l1_ht % 32 )) / 4;
2487
2.76k
        ld_frame_avg_satd_L1 =
2488
2.76k
            (WORD32)log(
2489
2.76k
                1 + (long double)i8_frame_acc_sadt_L1_squared /
2490
2.76k
                        ((long double)((i4_tot_4x4block_l1_x * i4_tot_4x4block_l1_y) >> 2))) /
2491
2.76k
            log(2.0);
2492
        /* L1 satd accumalated for computing qp */
2493
2.76k
        i8_frame_satd_by_act_L1_accum = 0;
2494
2.76k
        i4_tot_ctb_l1_x =
2495
2.76k
            ((i4_l1_wd + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) / (MAX_CTB_SIZE >> 1);
2496
2.76k
        i4_tot_ctb_l1_y =
2497
2.76k
            ((i4_l1_ht + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) / (MAX_CTB_SIZE >> 1);
2498
2499
17.7k
        for(i = 0; i < (i4_tot_ctb_l1_x * i4_tot_ctb_l1_y); i += 1)
2500
14.9k
        {
2501
254k
            for(i4_j = 0; i4_j < 16; i4_j++)
2502
239k
            {
2503
239k
                if(ps_ed_ctb_l1->i4_best_satd_8x8[i4_j] != -1)
2504
205k
                {
2505
205k
                    ASSERT(ps_ed_ctb_l1->i4_best_satd_8x8[i4_j] >= 0);
2506
205k
                    ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
2507
2508
205k
                    if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2509
6.51k
                       (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2510
0
                    {
2511
0
                        best_satd_16x16 = 0;
2512
0
                    }
2513
205k
                    else
2514
205k
                    {
2515
205k
                        best_satd_16x16 = ps_ed_ctb_l1->i4_best_satd_8x8[i4_j];
2516
205k
                    }
2517
2518
205k
                    acc_sad += (WORD32)ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j];
2519
                    //acc_satd += (WORD32)best_satd_16x16;
2520
205k
                    u1_cu_possible_qp = ihevce_cu_level_qp_mod(
2521
205k
                        32,
2522
205k
                        best_satd_16x16,
2523
205k
                        ld_frame_avg_satd_L1,
2524
205k
                        REF_MOD_STRENGTH,  // To be changed later
2525
205k
                        &i4_act_factor,
2526
205k
                        &i4_q_scale_mod,
2527
205k
                        &ps_enc_ctxt->s_rc_quant);
2528
205k
                    i8_best_satd_16x16 = best_satd_16x16 << QP_LEVEL_MOD_ACT_FACTOR;
2529
2530
205k
                    if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2531
6.51k
                       (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2532
0
                    {
2533
0
                        i4_act_factor = (1 << QP_LEVEL_MOD_ACT_FACTOR);
2534
0
                    }
2535
2536
205k
                    if(0 != i4_act_factor)
2537
205k
                    {
2538
205k
                        i8_frame_satd_by_act_L1_accum +=
2539
205k
                            ((WORD32)(i8_best_satd_16x16 / i4_act_factor));
2540
                        /*Accumulate SAD for those regions which will undergo evaluation in L0 stage*/
2541
205k
                        if(ps_ed_4x4->intra_or_inter != 2)
2542
196k
                            pre_intra_satd_act_evaluated +=
2543
196k
                                ((WORD32)(i8_best_satd_16x16 / i4_act_factor));
2544
205k
                    }
2545
205k
                }
2546
239k
                ps_ed_4x4 += 4;
2547
239k
            }
2548
14.9k
            ps_ed_ctb_l1 += 1;
2549
14.9k
        }
2550
        /** store the L1 satd in context struct
2551
    Note: this variable is common across all thread. it must be made sure all threads write same value*/
2552
2.76k
        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2553
233
           (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2554
0
        {
2555
0
            i8_frame_satd_by_act_L1_accum = ps_prev_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum;
2556
0
            ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum = i8_frame_satd_by_act_L1_accum;
2557
0
            ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated = -1;
2558
0
        }
2559
2.76k
        else
2560
2.76k
        {
2561
2.76k
            ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum = i8_frame_satd_by_act_L1_accum;
2562
2.76k
            ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated =
2563
2.76k
                pre_intra_satd_act_evaluated;
2564
2.76k
        }
2565
2566
2.76k
        ps_curr_inp->s_rc_lap_out.i8_pre_intra_satd = i8_frame_acc_sadt_L1;
2567
        /*accumulate raw intra sad without subtracting non coded sad*/
2568
2.76k
        ps_curr_inp->s_rc_lap_out.i8_raw_pre_intra_sad = acc_sad;
2569
2.76k
    }
2570
    /*update pre-enc qp using data from L1 to use better qp in L0 in case of cbr mode*/
2571
2.76k
    if(i4_is_last_thread)
2572
2.76k
    {
2573
        /* acquire mutex lock for rate control calls */
2574
2.76k
        osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2575
2.76k
        {
2576
2.76k
            LWORD64 i8_est_L0_satd_by_act;
2577
2.76k
            WORD32 i4_cur_q_scale;
2578
2.76k
            if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != CONST_QP)
2579
1.97k
            {
2580
                /*RCTODO :This needs to be reviewed in the context of 10/12 bit encoding as the Qp seems to be sub-optimal*/
2581
1.97k
                if(ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass != 2)
2582
1.97k
                    i4_cur_q_scale =
2583
1.97k
                        ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
2584
1.97k
                            [ps_curr_out->i4_curr_frm_qp];  // + ps_enc_ctxt->s_rc_quant.i1_qp_offset];
2585
0
                else
2586
0
                    i4_cur_q_scale = ps_enc_ctxt->s_rc_quant
2587
0
                                         .pi4_qp_to_qscale[MAX(ps_curr_out->i4_curr_frm_qp, 0)];
2588
1.97k
            }
2589
797
            else
2590
797
                i4_cur_q_scale =
2591
797
                    ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
2592
797
                        [ps_curr_out->i4_curr_frm_qp + ps_enc_ctxt->s_rc_quant.i1_qp_offset];
2593
2594
2.76k
            i4_cur_q_scale = (i4_cur_q_scale + (1 << (QSCALE_Q_FAC_3 - 1))) >> QSCALE_Q_FAC_3;
2595
2596
2.76k
            i8_est_L0_satd_by_act = ihevce_get_L0_satd_based_on_L1(
2597
2.76k
                i8_frame_satd_by_act_L1_accum,
2598
2.76k
                ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered,
2599
2.76k
                i4_cur_q_scale);
2600
            /*HEVC_RC query rate control for qp*/
2601
2.76k
            if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
2602
1.97k
            {
2603
1.97k
                i4_new_frame_qp = ihevce_get_L0_est_satd_based_scd_qp(
2604
1.97k
                    ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
2605
1.97k
                    &ps_curr_inp->s_rc_lap_out,
2606
1.97k
                    i8_est_L0_satd_by_act,
2607
1.97k
                    8.00);
2608
1.97k
            }
2609
797
            else
2610
797
                i4_new_frame_qp = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms
2611
797
                                      .as_tgt_params[ps_enc_ctxt->i4_resolution_id]
2612
797
                                      .ai4_frame_qp[0];
2613
2.76k
            i4_new_frame_qp = CLIP3(i4_new_frame_qp, 1, 51);
2614
2.76k
            i4_qp_for_I_pic = CLIP3(i4_qp_for_I_pic, 1, 51);
2615
2.76k
            ps_curr_inp->s_rc_lap_out.i4_L1_qp = i4_new_frame_qp;
2616
            /*I frame qp = qp-3 due to effect of lambda modifier*/
2617
2.76k
            i4_qp_for_I_pic = i4_new_frame_qp - 3;
2618
2619
            /*use new qp get possible qp even for inter pictures assuming default offset*/
2620
2.76k
            if(ps_curr_inp->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
2621
2.29k
               ps_curr_inp->s_lap_out.i4_pic_type != IV_I_FRAME)
2622
2.18k
            {
2623
2.18k
                i4_new_frame_qp += ps_curr_inp->s_lap_out.i4_temporal_lyr_id + 1;
2624
2.18k
            }
2625
2626
            /*accumulate the L1 ME sad using skip sad value based on qp*/
2627
            /*accumulate this only for last thread as it ll be guranteed that L1 ME sad is completely populated*/
2628
            /*The lambda modifier in encoder is tuned in such a way that the qp offsets according to lambda modifer are as follows
2629
                Note: These qp offset only account for lambda modifier, Hence this should be applied over qp offset that is already there due to picture type
2630
                relative lambda scale(these lambda diff are mapped into qp difference which is applied over and obove the qp offset)
2631
                Qi =  Iqp                         1
2632
                Qp =  Iqp                         1
2633
                Qb =  Iqp + 1.55                  1.48
2634
                Qb1 = Iqp + 3.1                   2.05
2635
                Qb2 = Iqp + 3.1                   2.05*/
2636
2637
            /*ihevce_compute_offsets_from_rc(ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],ai4_offsets,&ps_curr_inp->s_lap_out);*/
2638
2639
2.76k
            if(ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME ||
2640
2.65k
               ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME)
2641
579
            {
2642
579
                i4_new_frame_qp = i4_new_frame_qp - 3;
2643
579
            }
2644
2.18k
            else if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
2645
2.15k
            {
2646
2.15k
                i4_new_frame_qp = i4_new_frame_qp - 2;
2647
2.15k
            }
2648
2.76k
            if(ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2649
36
               ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 1)
2650
13
            {
2651
13
                i4_new_frame_qp = i4_new_frame_qp + 2;
2652
13
            }
2653
2.75k
            else if(
2654
2.75k
                ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2655
23
                ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 2)
2656
23
            {
2657
23
                i4_new_frame_qp = i4_new_frame_qp + 6;
2658
23
            }
2659
2.73k
            else if(
2660
2.73k
                ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2661
0
                ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 3)
2662
0
            {
2663
0
                i4_new_frame_qp = i4_new_frame_qp + 7;
2664
0
            }
2665
2666
2.76k
            i4_new_frame_qp = CLIP3(i4_new_frame_qp, 1, 51);
2667
2.76k
            i4_qp_for_I_pic = CLIP3(i4_qp_for_I_pic, 1, 51);
2668
2669
2.76k
            {
2670
2.76k
                calc_l1_level_hme_intra_sad_different_qp(
2671
2.76k
                    ps_enc_ctxt, ps_curr_out, ps_curr_inp, i4_tot_ctb_l1_x, i4_tot_ctb_l1_y);
2672
2673
                /** frame accumulated SAD over entire frame after accounting for dead zone SAD, this is least of intra or inter*/
2674
                /*ihevce_accum_hme_sad_subgop_rc(ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],&ps_curr_inp->s_lap_out);    */
2675
2.76k
                ihevce_rc_register_L1_analysis_data(
2676
2.76k
                    ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
2677
2.76k
                    &ps_curr_inp->s_rc_lap_out,
2678
2.76k
                    i8_est_L0_satd_by_act,
2679
2.76k
                    ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad
2680
2.76k
                        [i4_new_frame_qp],  //since the sad passed will be used to calc complexity it should be non coded sad subtracted sad
2681
2.76k
                    ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_new_frame_qp]);
2682
2683
2.76k
                ihevce_coarse_me_get_rc_param(
2684
2.76k
                    ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
2685
2.76k
                    &ps_curr_out->i8_acc_frame_coarse_me_cost,
2686
2.76k
                    &ps_curr_out->i8_acc_frame_coarse_me_sad,
2687
2.76k
                    &ps_curr_out->i8_acc_num_blks_high_sad,
2688
2.76k
                    &ps_curr_out->i8_total_blks,
2689
2.76k
                    ps_curr_inp->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene);
2690
2691
2.76k
                if(ps_curr_out->i8_total_blks)
2692
2.15k
                {
2693
2.15k
                    ps_curr_out->i4_complexity_percentage = (WORD32)(
2694
2.15k
                        (ps_curr_out->i8_acc_num_blks_high_sad * 100) /
2695
2.15k
                        (ps_curr_out->i8_total_blks));
2696
2.15k
                }
2697
                /*not for Const QP mode*/
2698
2.76k
                if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
2699
1.97k
                {
2700
1.97k
                    if(ps_curr_inp->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene &&
2701
1.97k
                       ps_curr_out->i8_total_blks &&
2702
1.50k
                       (((float)(ps_curr_out->i8_acc_num_blks_high_sad * 100) /
2703
1.50k
                         (ps_curr_out->i8_total_blks)) > (i4_cmplx_change_detection_thrsh)))
2704
19
                    {
2705
19
                        ps_curr_out->i4_is_high_complex_region = 1;
2706
19
                    }
2707
1.95k
                    else
2708
1.95k
                    {
2709
1.95k
                        ps_curr_out->i4_is_high_complex_region = 0;
2710
1.95k
                    }
2711
1.97k
                }
2712
2.76k
                ps_curr_inp->s_rc_lap_out.i8_frame_acc_coarse_me_cost =
2713
2.76k
                    ps_curr_out->i8_acc_frame_coarse_me_cost;
2714
                /*check for I only reset case and Non I SCD*/
2715
2.76k
                ihevce_rc_check_non_lap_scd(
2716
2.76k
                    ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0], &ps_curr_inp->s_rc_lap_out);
2717
2.76k
            }
2718
2.76k
        }
2719
        /* release mutex lock after rate control calls */
2720
2.76k
        osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2721
2.76k
    }
2722
2.76k
}
2723
2724
/*!
2725
******************************************************************************
2726
* \if Function name : ihevce_frame_init \endif
2727
*
2728
* \brief
2729
*    Pre encode Frame processing slave thread entry point function
2730
*
2731
* \param[in] Frame processing thread context pointer
2732
*
2733
* \return
2734
*    None
2735
*
2736
* \author
2737
*  Ittiam
2738
*
2739
*****************************************************************************
2740
*/
2741
void ihevce_frame_init(
2742
    enc_ctxt_t *ps_enc_ctxt,
2743
    pre_enc_me_ctxt_t *ps_curr_inp_prms,
2744
    me_enc_rdopt_ctxt_t *ps_cur_out_me_prms,
2745
    WORD32 i4_cur_frame_qp,
2746
    WORD32 i4_me_frm_id,
2747
    WORD32 i4_thrd_id)
2748
2.98k
{
2749
2.98k
    ihevce_lap_enc_buf_t *ps_curr_inp;
2750
2.98k
    WORD32 first_field = 1;
2751
2.98k
    me_master_ctxt_t *ps_master_ctxt;
2752
2753
2.98k
    (void)i4_thrd_id;
2754
2.98k
    (void)ps_cur_out_me_prms;
2755
2.98k
    ps_curr_inp = ps_curr_inp_prms->ps_curr_inp;
2756
2757
2.98k
    ps_master_ctxt = (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
2758
2759
    /* get frame level lambda params */
2760
2.98k
    ihevce_get_frame_lambda_prms(
2761
2.98k
        ps_enc_ctxt,
2762
2.98k
        ps_curr_inp_prms,
2763
2.98k
        i4_cur_frame_qp,
2764
2.98k
        first_field,
2765
2.98k
        ps_curr_inp->s_lap_out.i4_is_ref_pic,
2766
2.98k
        ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
2767
2.98k
        ps_curr_inp->s_lap_out.f_i_pic_lamda_modifier,
2768
2.98k
        0,
2769
2.98k
        ENC_LAMBDA_TYPE);
2770
2771
2.98k
    if(1 == ps_curr_inp_prms->i4_frm_proc_valid_flag)
2772
2.76k
    {
2773
2.76k
        UWORD8 i1_cu_qp_delta_enabled_flag =
2774
2.76k
            ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_cu_level_rc;
2775
2776
        /* picture level init of ME */
2777
2.76k
        ihevce_me_frame_init(
2778
2.76k
            ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
2779
2.76k
            ps_cur_out_me_prms,
2780
2.76k
            ps_enc_ctxt->ps_stat_prms,
2781
2.76k
            &ps_enc_ctxt->s_frm_ctb_prms,
2782
2.76k
            &ps_curr_inp_prms->as_lambda_prms[0],
2783
2.76k
            ps_enc_ctxt->i4_num_ref_l0,
2784
2.76k
            ps_enc_ctxt->i4_num_ref_l1,
2785
2.76k
            ps_enc_ctxt->i4_num_ref_l0_active,
2786
2.76k
            ps_enc_ctxt->i4_num_ref_l1_active,
2787
2.76k
            &ps_cur_out_me_prms->aps_ref_list[0][LIST_0][0],
2788
2.76k
            &ps_cur_out_me_prms->aps_ref_list[0][LIST_1][0],
2789
2.76k
            ps_cur_out_me_prms->aps_ref_list[0],
2790
2.76k
            &ps_enc_ctxt->s_func_selector,
2791
2.76k
            ps_curr_inp,
2792
2.76k
            ps_curr_inp_prms->pv_me_lyr_ctxt,
2793
2.76k
            i4_me_frm_id,
2794
2.76k
            i4_thrd_id,
2795
2.76k
            i4_cur_frame_qp,
2796
2.76k
            ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
2797
2.76k
            i1_cu_qp_delta_enabled_flag,
2798
2.76k
            ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]->pv_dep_mngr_encloop_dep_me);
2799
2800
        /* -------------------------------------------------------- */
2801
        /* Preparing Job Queue for ME and each instance of enc_loop */
2802
        /* -------------------------------------------------------- */
2803
2.76k
        ihevce_prepare_job_queue(ps_enc_ctxt, ps_curr_inp, i4_me_frm_id);
2804
2805
        /* Dep. Mngr : Reset the num ctb processed in every row  for ENC sync */
2806
2.76k
        ihevce_dmgr_rst_row_row_sync(
2807
2.76k
            ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]->pv_dep_mngr_encloop_dep_me);
2808
2.76k
    }
2809
2.98k
}
2810
2811
/****************************************************************************
2812
Function Name : ihevce_rc_close
2813
Description   : closing the Rate control by passing the stored data in to the stat file for 2 pass encoding.
2814
Inputs        :
2815
Globals       :
2816
Processing    :
2817
Outputs       :
2818
Returns       :
2819
Issues        :
2820
Revision History:
2821
DD MM YYYY   Author(s)       Changes (Describe the changes made)
2822
*****************************************************************************/
2823
2824
void ihevce_rc_close(
2825
    enc_ctxt_t *ps_enc_ctxt,
2826
    WORD32 i4_enc_frm_id_rc,
2827
    WORD32 i4_store_retrive,
2828
    WORD32 i4_update_cnt,
2829
    WORD32 i4_bit_rate_idx)
2830
218
{
2831
218
    rc_bits_sad_t s_rc_frame_stat;
2832
218
    WORD32 out_buf_id;
2833
218
    WORD32 i4_pic_type, k;
2834
218
    WORD32 cur_qp;
2835
218
    ihevce_lap_output_params_t s_lap_out;
2836
218
    rc_lap_out_params_t s_rc_lap_out;
2837
2838
436
    for(k = 0; k < i4_update_cnt; k++)  //ELP_RC
2839
218
    {
2840
218
        ihevce_rc_store_retrive_update_info(
2841
218
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i4_bit_rate_idx],
2842
218
            &s_rc_frame_stat,
2843
218
            i4_enc_frm_id_rc,
2844
218
            i4_bit_rate_idx,
2845
218
            2,
2846
218
            &out_buf_id,
2847
218
            &i4_pic_type,
2848
218
            &cur_qp,
2849
218
            (void *)&s_lap_out,
2850
218
            (void *)&s_rc_lap_out);
2851
2852
218
        ihevce_rc_update_pic_info(
2853
218
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i4_bit_rate_idx],
2854
218
            (s_rc_frame_stat.u4_total_texture_bits +
2855
218
             s_rc_frame_stat.u4_total_header_bits),  //pass total bits
2856
218
            s_rc_frame_stat.u4_total_header_bits,
2857
218
            s_rc_frame_stat.u4_total_sad,
2858
218
            s_rc_frame_stat.u4_total_intra_sad,
2859
218
            (IV_PICTURE_CODING_TYPE_T)i4_pic_type,
2860
218
            cur_qp,
2861
218
            0,
2862
218
            s_rc_frame_stat.i4_qp_normalized_8x8_cu_sum,
2863
218
            s_rc_frame_stat.i4_8x8_cu_sum,
2864
218
            s_rc_frame_stat.i8_sad_by_qscale,
2865
218
            &s_lap_out,
2866
218
            &s_rc_lap_out,
2867
218
            out_buf_id,
2868
218
            s_rc_frame_stat.u4_open_loop_intra_sad,
2869
218
            s_rc_frame_stat.i8_total_ssd_frame,
2870
218
            i4_enc_frm_id_rc);  //ps_curr_out->i4_inp_timestamp_low)
2871
218
        i4_enc_frm_id_rc++;
2872
218
        i4_enc_frm_id_rc = (i4_enc_frm_id_rc % ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
2873
218
    }
2874
218
}
2875
2876
/*!
2877
******************************************************************************
2878
* \if Function name : ihevce_enc_frm_proc_slave_thrd \endif
2879
*
2880
* \brief
2881
*    Enocde Frame processing slave thread entry point function
2882
*
2883
* \param[in] Frame processing thread context pointer
2884
*
2885
* \return
2886
*    None
2887
*
2888
* \author
2889
*  Ittiam
2890
*
2891
*****************************************************************************
2892
*/
2893
WORD32 ihevce_enc_frm_proc_slave_thrd(void *pv_frm_proc_thrd_ctxt)
2894
218
{
2895
218
    frm_proc_thrd_ctxt_t *ps_thrd_ctxt;
2896
218
    enc_ctxt_t *ps_enc_ctxt;
2897
218
    WORD32 i4_me_end_flag, i4_enc_end_flag;
2898
218
    WORD32 i4_thrd_id;
2899
218
    ihevce_hle_ctxt_t *ps_hle_ctxt;
2900
218
    WORD32 i4_num_bitrates;  //number of bit-rates instances running
2901
218
    WORD32 i;  //ctr
2902
218
    void *pv_dep_mngr_prev_frame_me_done;
2903
218
    void *pv_dep_mngr_prev_frame_done;
2904
218
    WORD32 i4_resolution_id;
2905
218
    WORD32 i4_enc_frm_id_rc = 0;
2906
218
    WORD32 i4_enc_frm_id = 0;
2907
218
    WORD32 i4_me_frm_id = 0;
2908
2909
218
    ps_thrd_ctxt = (frm_proc_thrd_ctxt_t *)pv_frm_proc_thrd_ctxt;
2910
218
    ps_hle_ctxt = ps_thrd_ctxt->ps_hle_ctxt;
2911
218
    ps_enc_ctxt = (enc_ctxt_t *)ps_thrd_ctxt->pv_enc_ctxt; /*Changed for mres*/
2912
218
    i4_thrd_id = ps_thrd_ctxt->i4_thrd_id;
2913
218
    i4_me_end_flag = 0;
2914
218
    i4_enc_end_flag = 0;
2915
218
    i4_num_bitrates = ps_enc_ctxt->i4_num_bitrates;
2916
218
    i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
2917
2918
    /*pv_dep_mngr_prev_frame_me_done  =
2919
        ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_me_done;*/
2920
2921
3.20k
    while((0 == i4_me_end_flag) && (0 == i4_enc_end_flag))
2922
2.98k
    {
2923
2.98k
        WORD32 result;
2924
2.98k
        WORD32 ai4_in_buf_id[MAX_NUM_ME_PARALLEL];
2925
2.98k
        me_enc_rdopt_ctxt_t *ps_curr_out_me;
2926
2927
2.98k
        if(1 == ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel)
2928
2.98k
        {
2929
2.98k
            pv_dep_mngr_prev_frame_me_done =
2930
2.98k
                ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[0];
2931
2.98k
        }
2932
0
        else
2933
0
        {
2934
0
            pv_dep_mngr_prev_frame_me_done =
2935
0
                ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i4_me_frm_id];
2936
0
        }
2937
2938
        /* Wait till the previous frame ME is completly done*/
2939
2.98k
        {
2940
2.98k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_me_done, ps_thrd_ctxt->i4_thrd_id);
2941
2.98k
        }
2942
2943
        /****** Lock the critical section ******/
2944
2.98k
        if(NULL != ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id])
2945
2.98k
        {
2946
2.98k
            result = osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id]);
2947
2948
2.98k
            if(OSAL_SUCCESS != result)
2949
0
                return 0;
2950
2.98k
        }
2951
2952
2.98k
        {
2953
            /************************************/
2954
            /****** ENTER CRITICAL SECTION ******/
2955
            /************************************/
2956
2957
            /* First slave getting the mutex lock will act as master and does ME init
2958
            * of current frame and other slaves skip it
2959
            */
2960
2.98k
            if(ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] == 0)
2961
2.98k
            {
2962
2.98k
                WORD32 i4_ref_cur_qp;  //current frame Qp for reference bit-rate instance
2963
2.98k
                ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
2964
2965
2.98k
                if(0 == i4_me_end_flag)
2966
2.98k
                {
2967
                    /* ------- get the input prms buffer from pre encode que ------------ */
2968
2.98k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] =
2969
2.98k
                        (pre_enc_me_ctxt_t *)ihevce_q_get_filled_buff(
2970
2.98k
                            (void *)ps_enc_ctxt,
2971
2.98k
                            IHEVCE_PRE_ENC_ME_Q,
2972
2.98k
                            &ai4_in_buf_id[i4_me_frm_id],
2973
2.98k
                            BUFF_QUE_BLOCKING_MODE);
2974
                    /*always buffer must be available*/
2975
2.98k
                    ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] != NULL);
2976
2977
2.98k
                    ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] = 0;
2978
2979
                    /* ------- get the input prms buffer from L0 IPE queue ------------ */
2980
2.98k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] =
2981
2.98k
                        (pre_enc_L0_ipe_encloop_ctxt_t *)ihevce_q_get_filled_buff(
2982
2.98k
                            (void *)ps_enc_ctxt,
2983
2.98k
                            IHEVCE_L0_IPE_ENC_Q,
2984
2.98k
                            &ps_enc_ctxt->s_multi_thrd.ai4_in_frm_l0_ipe_id[i4_me_frm_id],
2985
2.98k
                            BUFF_QUE_BLOCKING_MODE);
2986
2987
                    /*always buffer must be available*/
2988
2.98k
                    ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] != NULL);
2989
2990
                    /* ------- get the free buffer from me_enc que ------------ */
2991
2.98k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] =
2992
2.98k
                        (me_enc_rdopt_ctxt_t *)ihevce_q_get_free_buff(
2993
2.98k
                            ps_enc_ctxt,
2994
2.98k
                            IHEVCE_ME_ENC_RDOPT_Q,
2995
2.98k
                            &ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id],
2996
2.98k
                            BUFF_QUE_BLOCKING_MODE);
2997
2998
                    /*always buffer must be available*/
2999
2.98k
                    ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] != NULL);
3000
2.98k
                }
3001
2.98k
                if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3002
2.98k
                   NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] &&
3003
2.98k
                   NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id])
3004
2.98k
                {
3005
2.98k
                    ps_curr_inp =
3006
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3007
3008
2.98k
                    ps_curr_out_me = ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id];
3009
3010
2.98k
                    ps_curr_out_me->ps_curr_inp_from_l0_ipe_prms =
3011
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id];
3012
3013
                    /*initialization of curr out me*/
3014
2.98k
                    ps_curr_out_me->ps_curr_inp_from_me_prms =
3015
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id];
3016
3017
2.98k
                    ps_curr_out_me->curr_inp_from_me_buf_id = ai4_in_buf_id[i4_me_frm_id];
3018
3019
2.98k
                    ps_curr_out_me->i4_buf_id =
3020
2.98k
                        ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id];
3021
3022
2.98k
                    ps_curr_out_me->ps_curr_inp =
3023
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3024
3025
2.98k
                    ps_curr_out_me->curr_inp_buf_id =
3026
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->curr_inp_buf_id;
3027
3028
2.98k
                    ps_curr_out_me->curr_inp_from_l0_ipe_buf_id =
3029
2.98k
                        ps_enc_ctxt->s_multi_thrd.ai4_in_frm_l0_ipe_id[i4_me_frm_id];
3030
3031
2.98k
                    ps_curr_out_me->i4_frm_proc_valid_flag =
3032
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3033
2.98k
                            ->i4_frm_proc_valid_flag;
3034
3035
2.98k
                    ps_curr_out_me->i4_end_flag =
3036
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_end_flag;
3037
3038
                    /* do the processing if input frm data is valid */
3039
2.98k
                    if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
3040
2.76k
                    {
3041
                        /* slice header will be populated in pre-enocde stage */
3042
2.76k
                        memcpy(
3043
2.76k
                            &ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]
3044
2.76k
                                 ->s_slice_hdr,
3045
2.76k
                            &ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3046
2.76k
                                 ->s_slice_hdr,
3047
2.76k
                            sizeof(slice_header_t));
3048
3049
2.76k
                        if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3050
2.76k
                               ->i4_frm_proc_valid_flag)
3051
2.76k
                        {
3052
2.76k
                            WORD32 ctr;
3053
2.76k
                            recon_pic_buf_t *ps_frm_recon;
3054
5.53k
                            for(i = 0; i < i4_num_bitrates; i++)
3055
2.76k
                            {
3056
                                /* run a loop to free the non used reference pics */
3057
                                /* This is done here because its assured that recon buf
3058
                                * between app and encode loop is set as produced
3059
                                */
3060
2.76k
                                {
3061
2.76k
                                    WORD32 i4_free_id;
3062
2.76k
                                    i4_free_id = ihevce_find_free_indx(
3063
2.76k
                                        ps_enc_ctxt->pps_recon_buf_q[i],
3064
2.76k
                                        ps_enc_ctxt->ai4_num_buf_recon_q[i]);
3065
3066
2.76k
                                    if(i4_free_id != -1)
3067
1.93k
                                    {
3068
1.93k
                                        ps_enc_ctxt->pps_recon_buf_q[i][i4_free_id]->i4_is_free = 1;
3069
1.93k
                                        ps_enc_ctxt->pps_recon_buf_q[i][i4_free_id]->i4_poc = -1;
3070
1.93k
                                    }
3071
2.76k
                                }
3072
3073
2.76k
                                ps_frm_recon = NULL;
3074
7.88k
                                for(ctr = 0; ctr < ps_enc_ctxt->ai4_num_buf_recon_q[i]; ctr++)
3075
7.88k
                                {
3076
7.88k
                                    if(ps_enc_ctxt->pps_recon_buf_q[i][ctr]->i4_is_free)
3077
2.76k
                                    {
3078
2.76k
                                        ps_frm_recon = ps_enc_ctxt->pps_recon_buf_q[i][ctr];
3079
2.76k
                                        break;
3080
2.76k
                                    }
3081
7.88k
                                }
3082
2.76k
                                ASSERT(ps_frm_recon != NULL);
3083
3084
2.76k
                                ps_frm_recon->i4_is_free = 0;
3085
2.76k
                                ps_frm_recon->i4_non_ref_free_flag = 0;
3086
2.76k
                                ps_frm_recon->i4_topfield_first =
3087
2.76k
                                    ps_curr_inp->s_input_buf.i4_topfield_first;
3088
2.76k
                                ps_frm_recon->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
3089
2.76k
                                ps_frm_recon->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
3090
2.76k
                                ps_frm_recon->i4_display_num =
3091
2.76k
                                    ps_curr_inp->s_lap_out.i4_display_num;
3092
2.76k
                                ps_frm_recon->i4_idr_gop_num =
3093
2.76k
                                    ps_curr_inp->s_lap_out.i4_idr_gop_num;
3094
2.76k
                                ps_frm_recon->i4_bottom_field =
3095
2.76k
                                    ps_curr_inp->s_input_buf.i4_bottom_field;
3096
2.76k
                                ps_frm_recon->i4_is_reference =
3097
2.76k
                                    ps_curr_inp->s_lap_out.i4_is_ref_pic;
3098
3099
2.76k
                                {
3100
2.76k
                                    WORD32 sei_hash_enabled;
3101
2.76k
#ifndef DISABLE_SEI
3102
2.76k
                                    sei_hash_enabled = (ps_enc_ctxt->ps_stat_prms->s_out_strm_prms
3103
2.76k
                                             .i4_sei_enable_flag == 1) &&
3104
591
                                        (ps_enc_ctxt->ps_stat_prms->s_out_strm_prms
3105
591
                                             .i4_decoded_pic_hash_sei_flag != 0);
3106
#else
3107
                                    sei_hash_enabled = 0;
3108
#endif
3109
                                    /* Deblock a picture for all reference frames unconditionally. */
3110
                                    /* Deblock non ref if psnr compute or save recon is enabled    */
3111
2.76k
                                    ps_frm_recon->i4_deblk_pad_hpel_cur_pic =
3112
2.76k
                                        ps_frm_recon->i4_is_reference ||
3113
23
                                        (ps_enc_ctxt->ps_stat_prms->i4_save_recon) ||
3114
23
                                        (1 == sei_hash_enabled);
3115
2.76k
                                }
3116
3117
2.76k
                                ps_frm_recon->s_yuv_buf_desc.i4_y_ht =
3118
2.76k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht;
3119
2.76k
                                ps_frm_recon->s_yuv_buf_desc.i4_uv_ht =
3120
2.76k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht >>
3121
2.76k
                                    ((ps_enc_ctxt->s_runtime_src_prms.i4_chr_format ==
3122
2.76k
                                      IV_YUV_422SP_UV)
3123
2.76k
                                         ? 0
3124
2.76k
                                         : 1);
3125
2.76k
                                ps_frm_recon->s_yuv_buf_desc.i4_y_wd =
3126
2.76k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd;
3127
2.76k
                                ps_frm_recon->s_yuv_buf_desc.i4_uv_wd =
3128
2.76k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd;
3129
2.76k
                                ps_frm_recon->s_yuv_buf_desc.i4_y_strd =
3130
2.76k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd +
3131
2.76k
                                    (PAD_HORZ << 1);
3132
2.76k
                                ps_frm_recon->s_yuv_buf_desc.i4_uv_strd =
3133
2.76k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd +
3134
2.76k
                                    (PAD_HORZ << 1);
3135
3136
                                /* reset the row_frm dep mngr for ME reverse sync for reference bitrate */
3137
2.76k
                                if(i == 0)
3138
2.76k
                                {
3139
2.76k
                                    ihevce_dmgr_map_rst_sync(ps_frm_recon->pv_dep_mngr_recon);
3140
2.76k
                                }
3141
3142
2.76k
                                ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i] =
3143
2.76k
                                    ps_frm_recon;
3144
2.76k
                            }
3145
2.76k
                        }
3146
                        /* Reference buffer management and reference list creation */
3147
                        /* This needs to be created for each bit-rate since the reconstructed output is
3148
                        different for all bit-rates. ME uses only 0th instnace ref list */
3149
5.53k
                        for(i = i4_num_bitrates - 1; i >= 0; i--)
3150
2.76k
                        {
3151
2.76k
                            ihevce_manage_ref_pics(
3152
2.76k
                                ps_enc_ctxt,
3153
2.76k
                                ps_curr_inp,
3154
2.76k
                                &ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]
3155
2.76k
                                     ->s_slice_hdr,
3156
2.76k
                                i4_me_frm_id,
3157
2.76k
                                i4_thrd_id,
3158
2.76k
                                i); /* bitrate instance ID */
3159
2.76k
                        }
3160
                        /*query of qp to be moved just before encoding starts*/
3161
2.76k
                        i4_ref_cur_qp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3162
2.76k
                                            ->i4_curr_frm_qp;
3163
                        /* The Qp populated in Pre enc stage needs to overwritten with Qp
3164
                        queried from rate control*/
3165
2.76k
                    }
3166
218
                    else
3167
218
                    {
3168
218
                        i4_ref_cur_qp = 0;
3169
218
                    }
3170
3171
                    /* call the core encoding loop */
3172
2.98k
                    ihevce_frame_init(
3173
2.98k
                        ps_enc_ctxt,
3174
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id],
3175
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id],
3176
2.98k
                        i4_ref_cur_qp,
3177
2.98k
                        i4_me_frm_id,
3178
2.98k
                        i4_thrd_id);
3179
2.98k
                }
3180
3181
2.98k
                ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] = 1;
3182
2.98k
            }
3183
2.98k
        }
3184
3185
        /************************************/
3186
        /******  EXIT CRITICAL SECTION ******/
3187
        /************************************/
3188
3189
        /****** Unlock the critical section ******/
3190
2.98k
        if(NULL != ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id])
3191
2.98k
        {
3192
2.98k
            result = osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id]);
3193
2.98k
            if(OSAL_SUCCESS != result)
3194
0
                return 0;
3195
2.98k
        }
3196
3197
2.98k
        if((1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
3198
0
           (1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3199
0
                     ->ps_curr_inp->s_lap_out.i4_first_frm_new_res))
3200
0
        {
3201
            /* Reset the enc frame rc id whenver change in resolution happens */
3202
0
            i4_enc_frm_id_rc = 0;
3203
0
        }
3204
3205
        /*update end flag for each thread */
3206
2.98k
        i4_me_end_flag = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_end_flag;
3207
2.98k
        if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3208
2.98k
           NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] &&
3209
2.98k
           NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id])
3210
2.98k
        {
3211
2.98k
            pre_enc_me_ctxt_t *ps_curr_inp_prms;
3212
2.98k
            pre_enc_L0_ipe_encloop_ctxt_t *ps_curr_L0_IPE_inp_prms;
3213
2.98k
            ihevce_lap_enc_buf_t *ps_curr_inp;
3214
3215
            /* get the current  buffer pointer  */
3216
2.98k
            ps_curr_inp_prms = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id];
3217
2.98k
            ps_curr_L0_IPE_inp_prms =
3218
2.98k
                ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id];
3219
2.98k
            ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3220
2.98k
            if(i4_thrd_id == 0)
3221
2.98k
            {
3222
2.98k
                PROFILE_START(&ps_hle_ctxt->profile_enc_me[ps_enc_ctxt->i4_resolution_id]);
3223
2.98k
            }
3224
3225
            /* -------------------------------------------------- */
3226
            /*    Motion estimation (enc layer) of entire frame   */
3227
            /* -------------------------------------------------- */
3228
2.98k
            if((i4_me_end_flag == 0) &&
3229
2.76k
               (1 ==
3230
2.76k
                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_frm_proc_valid_flag))
3231
2.76k
            {
3232
                /* Init i4_is_prev_frame_reference for the next P-frame */
3233
2.76k
                me_master_ctxt_t *ps_master_ctxt =
3234
2.76k
                    (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3235
3236
                /* get the current thread ctxt pointer */
3237
2.76k
                me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3238
3239
2.76k
                me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3240
3241
2.76k
                if(ISLICE != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3242
2.76k
                                 ->s_slice_hdr.i1_slice_type)
3243
2.18k
                {
3244
2.18k
                    ihevce_me_process(
3245
2.18k
                        ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
3246
2.18k
                        ps_curr_inp,
3247
2.18k
                        ps_curr_inp_prms->ps_ctb_analyse,
3248
2.18k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id],
3249
2.18k
                        ps_curr_inp_prms->plf_intra_8x8_cost,
3250
2.18k
                        ps_curr_L0_IPE_inp_prms->ps_ipe_analyse_ctb,
3251
2.18k
                        ps_curr_L0_IPE_inp_prms,
3252
2.18k
                        ps_curr_inp_prms->pv_me_lyr_ctxt,
3253
2.18k
                        &ps_enc_ctxt->s_multi_thrd,
3254
2.18k
                        ((ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel == 1) ? 0 : 1),
3255
2.18k
                        i4_thrd_id,
3256
2.18k
                        i4_me_frm_id);
3257
2.18k
                }
3258
579
                else
3259
579
                {
3260
                    /* Init i4_is_prev_frame_reference for the next P-frame */
3261
579
                    me_master_ctxt_t *ps_master_ctxt =
3262
579
                        (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3263
3264
                    /* get the current thread ctxt pointer */
3265
579
                    me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3266
3267
579
                    me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3268
3269
579
                    multi_thrd_ctxt_t *ps_multi_thrd_ctxt = &ps_enc_ctxt->s_multi_thrd;
3270
3271
579
                    if(ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel != 1)
3272
0
                    {
3273
0
                        ps_frm_ctxt->i4_is_prev_frame_reference = 0;
3274
0
                    }
3275
579
                    else
3276
579
                    {
3277
579
                        ps_frm_ctxt->i4_is_prev_frame_reference =
3278
579
                            ps_multi_thrd_ctxt->aps_cur_inp_me_prms[i4_me_frm_id]
3279
579
                                ->ps_curr_inp->s_lap_out.i4_is_ref_pic;
3280
579
                    }
3281
579
                }
3282
2.76k
            }
3283
2.98k
            if(i4_thrd_id == 0)
3284
2.98k
            {
3285
2.98k
                PROFILE_STOP(&ps_hle_ctxt->profile_enc_me[ps_enc_ctxt->i4_resolution_id], NULL);
3286
2.98k
            }
3287
2.98k
        }
3288
        /************************************/
3289
        /******  ENTER CRITICAL SECTION *****/
3290
        /************************************/
3291
2.98k
        {
3292
2.98k
            WORD32 result_frame_init;
3293
2.98k
            void *pv_mutex_handle_frame_init;
3294
3295
            /* Create mutex for locking non-reentrant sections      */
3296
2.98k
            pv_mutex_handle_frame_init =
3297
2.98k
                ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i4_me_frm_id];
3298
3299
            /****** Lock the critical section ******/
3300
2.98k
            if(NULL != pv_mutex_handle_frame_init)
3301
2.98k
            {
3302
2.98k
                result_frame_init = osal_mutex_lock(pv_mutex_handle_frame_init);
3303
3304
2.98k
                if(OSAL_SUCCESS != result_frame_init)
3305
0
                    return 0;
3306
2.98k
            }
3307
2.98k
        }
3308
3309
2.98k
        if(0 == ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id])
3310
2.98k
        {
3311
            /* ------- set buffer produced from me_enc que ------------ */
3312
2.98k
            ihevce_q_set_buff_prod(
3313
2.98k
                ps_enc_ctxt,
3314
2.98k
                IHEVCE_ME_ENC_RDOPT_Q,
3315
2.98k
                ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id]);
3316
3317
2.98k
            ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id] = 1;
3318
2.98k
        }
3319
2.98k
        if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3320
2.98k
           NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id])
3321
2.98k
        {
3322
2.98k
            ihevce_lap_enc_buf_t *ps_curr_inp;
3323
3324
2.98k
            WORD32 first_field = 1;
3325
3326
            /* Increment the counter to keep track of no of threads exiting the current mutex*/
3327
2.98k
            ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id]++;
3328
3329
2.98k
            ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3330
            /* Last slave thread will reset the master done frame init flag and set the prev
3331
            * frame me done flag for curr frame
3332
            */
3333
2.98k
            if(ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id] ==
3334
2.98k
               ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
3335
2.98k
            {
3336
2.98k
                ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id] = 0;
3337
3338
2.98k
                ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] = 0;
3339
3340
                /* Update Dyn. Vert. Search prms for P Pic. */
3341
2.98k
                if(IV_P_FRAME == ps_curr_inp->s_lap_out.i4_pic_type)
3342
2.32k
                {
3343
2.32k
                    WORD32 i4_idx_dvsr_p = ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p;
3344
                    /* Sanity Check */
3345
2.32k
                    ASSERT(ps_curr_inp->s_lap_out.i4_pic_type < IV_IP_FRAME);
3346
3347
                    /*  Frame END processing for Dynamic Vertival Search    */
3348
2.32k
                    ihevce_l0_me_frame_end(
3349
2.32k
                        ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
3350
2.32k
                        i4_idx_dvsr_p,
3351
2.32k
                        ps_curr_inp->s_lap_out.i4_display_num,
3352
2.32k
                        i4_me_frm_id);
3353
3354
2.32k
                    ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p++;
3355
2.32k
                    if(ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p == NUM_SG_INTERLEAVED)
3356
2.32k
                    {
3357
2.32k
                        ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p = 0;
3358
2.32k
                    }
3359
2.32k
                }
3360
2.98k
                if(1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3361
2.98k
                            ->i4_frm_proc_valid_flag)
3362
2.76k
                {
3363
                    /* Init i4_is_prev_frame_reference for the next P-frame */
3364
2.76k
                    me_master_ctxt_t *ps_master_ctxt =
3365
2.76k
                        (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3366
3367
                    /* get the current thread ctxt pointer */
3368
2.76k
                    me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3369
3370
2.76k
                    me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3371
3372
2.76k
                    ps_frm_ctxt->ps_curr_descr->aps_layers[0]->i4_non_ref_free = 1;
3373
2.76k
                }
3374
2.98k
                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] = NULL;
3375
2.98k
                ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] = NULL;
3376
2.98k
                ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] = NULL;
3377
2.98k
                ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id] = 0;
3378
2.98k
                ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] = 0;
3379
3380
                /* Set me processing done for curr frame in the dependency manager */
3381
2.98k
                ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_me_done);
3382
2.98k
            }
3383
2.98k
        }
3384
        /************************************/
3385
        /******  EXIT CRITICAL SECTION ******/
3386
        /************************************/
3387
3388
2.98k
        {
3389
2.98k
            void *pv_mutex_handle_frame_init;
3390
3391
            /* Create mutex for locking non-reentrant sections      */
3392
2.98k
            pv_mutex_handle_frame_init =
3393
2.98k
                ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i4_me_frm_id];
3394
            /****** Unlock the critical section ******/
3395
2.98k
            if(NULL != pv_mutex_handle_frame_init)
3396
2.98k
            {
3397
2.98k
                result = osal_mutex_unlock(pv_mutex_handle_frame_init);
3398
2.98k
                if(OSAL_SUCCESS != result)
3399
0
                    return 0;
3400
2.98k
            }
3401
2.98k
        }
3402
        /* -------------------------------------------- */
3403
        /*        Encode Loop of entire frame           */
3404
        /* -------------------------------------------- */
3405
2.98k
        ASSERT(ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel <= MAX_NUM_ENC_LOOP_PARALLEL);
3406
3407
2.98k
        if(1 == ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel)
3408
2.98k
        {
3409
2.98k
            pv_dep_mngr_prev_frame_done = ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[0];
3410
2.98k
        }
3411
0
        else
3412
0
        {
3413
0
            pv_dep_mngr_prev_frame_done =
3414
0
                ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i4_enc_frm_id];
3415
0
        }
3416
        /* Wait till the prev frame enc loop is completed*/
3417
2.98k
        {
3418
2.98k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_done, ps_thrd_ctxt->i4_thrd_id);
3419
2.98k
        }
3420
3421
        /************************************/
3422
        /****** ENTER CRITICAL SECTION ******/
3423
        /************************************/
3424
2.98k
        {
3425
2.98k
            WORD32 result_frame_init;
3426
2.98k
            void *pv_mutex_handle_frame_init;
3427
3428
            /* Create mutex for locking non-reentrant sections      */
3429
2.98k
            pv_mutex_handle_frame_init =
3430
2.98k
                ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i4_enc_frm_id];
3431
3432
            /****** Lock the critical section ******/
3433
2.98k
            if(NULL != pv_mutex_handle_frame_init)
3434
2.98k
            {
3435
2.98k
                result_frame_init = osal_mutex_lock(pv_mutex_handle_frame_init);
3436
3437
2.98k
                if(OSAL_SUCCESS != result_frame_init)
3438
0
                    return 0;
3439
2.98k
            }
3440
2.98k
        }
3441
3442
2.98k
        {
3443
2.98k
            ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
3444
2.98k
            pre_enc_me_ctxt_t *ps_curr_inp_from_me = NULL;
3445
2.98k
            me_enc_rdopt_ctxt_t *ps_curr_inp_enc = NULL;
3446
2.98k
            pre_enc_L0_ipe_encloop_ctxt_t *ps_curr_L0_IPE_inp_prms = NULL;
3447
2.98k
            recon_pic_buf_t *(*aps_ref_list)[HEVCE_MAX_REF_PICS * 2];
3448
2.98k
            WORD32 ai4_cur_qp[IHEVCE_MAX_NUM_BITRATES] = { 0 };
3449
2.98k
            WORD32 i4_field_pic = ps_enc_ctxt->s_runtime_src_prms.i4_field_pic;
3450
2.98k
            WORD32 first_field = 1;
3451
2.98k
            WORD32 result_frame_init;
3452
2.98k
            void *pv_mutex_handle_frame_init;
3453
3454
            /* Create mutex for locking non-reentrant sections      */
3455
2.98k
            pv_mutex_handle_frame_init =
3456
2.98k
                ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i4_enc_frm_id];
3457
3458
            //aquire and initialize -> output and recon buffers
3459
2.98k
            if(ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] == 0)
3460
2.98k
            {
3461
2.98k
                WORD32
3462
2.98k
                    i4_bitrate_ctr;  //bit-rate instance counter (for loop variable) [0->reference bit-rate, 1,2->auxiliarty bit-rates]
3463
                /* ------- get the input prms buffer from me que ------------ */
3464
2.98k
                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] =
3465
2.98k
                    (me_enc_rdopt_ctxt_t *)ihevce_q_get_filled_buff(
3466
2.98k
                        ps_enc_ctxt,
3467
2.98k
                        IHEVCE_ME_ENC_RDOPT_Q,
3468
2.98k
                        &ps_enc_ctxt->s_multi_thrd.i4_enc_in_buf_id[i4_enc_frm_id],
3469
2.98k
                        BUFF_QUE_BLOCKING_MODE);
3470
2.98k
                i4_enc_end_flag =
3471
2.98k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->i4_end_flag;
3472
3473
2.98k
                ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL);
3474
3475
2.98k
                if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
3476
2.98k
                {
3477
2.98k
                    ps_curr_inp =
3478
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->ps_curr_inp;
3479
2.98k
                    ps_curr_inp_from_me =
3480
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3481
2.98k
                            ->ps_curr_inp_from_me_prms;
3482
2.98k
                    ps_curr_inp_enc = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id];
3483
2.98k
                    ps_curr_L0_IPE_inp_prms =
3484
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3485
2.98k
                            ->ps_curr_inp_from_l0_ipe_prms;
3486
3487
5.97k
                    for(i4_bitrate_ctr = 0; i4_bitrate_ctr < i4_num_bitrates; i4_bitrate_ctr++)
3488
2.98k
                    {
3489
2.98k
                        iv_enc_recon_data_buffs_t
3490
2.98k
                            *ps_recon_out[MAX_NUM_ENC_LOOP_PARALLEL][IHEVCE_MAX_NUM_BITRATES] = {
3491
2.98k
                                { NULL }
3492
2.98k
                            };
3493
2.98k
                        frm_proc_ent_cod_ctxt_t *ps_curr_out[MAX_NUM_ENC_LOOP_PARALLEL]
3494
2.98k
                                                            [IHEVCE_MAX_NUM_BITRATES] = { { NULL } };
3495
3496
                        /* ------- get free output buffer from Frame buffer que ---------- */
3497
                        /* There is a separate queue for each bit-rate instnace. The output
3498
                    buffer is acquired from the corresponding queue based on the
3499
                    bitrate instnace */
3500
2.98k
                        ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr] =
3501
2.98k
                            (frm_proc_ent_cod_ctxt_t *)ihevce_q_get_free_buff(
3502
2.98k
                                (void *)ps_enc_ctxt,
3503
2.98k
                                IHEVCE_FRM_PRS_ENT_COD_Q +
3504
2.98k
                                    i4_bitrate_ctr, /*decides the buffer queue */
3505
2.98k
                                &ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i4_bitrate_ctr],
3506
2.98k
                                BUFF_QUE_BLOCKING_MODE);
3507
2.98k
                        ps_enc_ctxt->s_multi_thrd.is_out_buf_freed[i4_enc_frm_id][i4_bitrate_ctr] =
3508
2.98k
                            0;
3509
2.98k
                        ps_enc_ctxt->s_multi_thrd
3510
2.98k
                            .ps_curr_out_enc_grp[i4_enc_frm_id][i4_bitrate_ctr] =
3511
2.98k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr];
3512
                        //ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_enc_order_num = ps_curr_inp->s_lap_out.i4_enc_order_num;
3513
                        /*registered User Data Call*/
3514
2.98k
#ifndef DISABLE_SEI
3515
2.98k
                        if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_payload_enable_flag)
3516
0
                        {
3517
0
                            ihevce_fill_sei_payload(
3518
0
                                ps_enc_ctxt,
3519
0
                                ps_curr_inp,
3520
0
                                ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]);
3521
0
                        }
3522
3523
2.98k
#endif
3524
                        /*derive end flag and input valid flag in output buffer */
3525
2.98k
                        if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id])
3526
2.98k
                        {
3527
2.98k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_end_flag =
3528
2.98k
                                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3529
2.98k
                                    ->i4_end_flag;
3530
2.98k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_frm_proc_valid_flag =
3531
2.98k
                                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3532
2.98k
                                    ->i4_frm_proc_valid_flag;
3533
3534
2.98k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_out_flush_flag =
3535
2.98k
                                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3536
2.98k
                                    ->ps_curr_inp->s_lap_out.i4_out_flush_flag;
3537
2.98k
                        }
3538
3539
                        /*derive other parameters in output buffer */
3540
2.98k
                        if(NULL != ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr] &&
3541
2.98k
                           (NULL != ps_curr_inp_from_me) &&
3542
2.98k
                           (1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag) &&
3543
2.76k
                           (i4_enc_end_flag == 0))
3544
2.76k
                        {
3545
                            /* copy the time stamps from inp to entropy inp */
3546
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_inp_timestamp_low =
3547
2.76k
                                ps_curr_inp_from_me->i4_inp_timestamp_low;
3548
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_inp_timestamp_high =
3549
2.76k
                                ps_curr_inp_from_me->i4_inp_timestamp_high;
3550
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->pv_app_frm_ctxt =
3551
2.76k
                                ps_curr_inp_from_me->pv_app_frm_ctxt;
3552
3553
                            /*copy slice header params from temp structure to output buffer */
3554
2.76k
                            memcpy(
3555
2.76k
                                &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->s_slice_hdr,
3556
2.76k
                                &ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3557
2.76k
                                     ->s_slice_hdr,
3558
2.76k
                                sizeof(slice_header_t));
3559
3560
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3561
2.76k
                                ->s_slice_hdr.pu4_entry_point_offset =
3562
2.76k
                                &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3563
2.76k
                                     ->ai4_entry_point_offset[0];
3564
3565
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_slice_nal_type =
3566
2.76k
                                ps_curr_inp_from_me->i4_slice_nal_type;
3567
3568
                            /* populate sps, vps and pps pointers for the entropy input params */
3569
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_pps =
3570
2.76k
                                &ps_enc_ctxt->as_pps[i4_bitrate_ctr];
3571
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_sps =
3572
2.76k
                                &ps_enc_ctxt->as_sps[i4_bitrate_ctr];
3573
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_vps =
3574
2.76k
                                &ps_enc_ctxt->as_vps[i4_bitrate_ctr];
3575
3576
2.76k
#ifndef DISABLE_SEI
3577
                            /* SEI header will be populated in pre-enocde stage */
3578
2.76k
                            memcpy(
3579
2.76k
                                &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->s_sei,
3580
2.76k
                                &ps_curr_inp_from_me->s_sei,
3581
2.76k
                                sizeof(sei_params_t));
3582
3583
2.76k
#endif
3584
                            /*AUD and EOS presnt flags are populated*/
3585
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i1_aud_present_flag =
3586
2.76k
                                ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_aud_enable_flags;
3587
3588
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i1_eos_present_flag =
3589
2.76k
                                ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_eos_enable_flags;
3590
3591
                            /* Information required for SEI Picture timing info */
3592
2.76k
                            {
3593
2.76k
                                ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_display_num =
3594
2.76k
                                    ps_curr_inp->s_lap_out.i4_display_num;
3595
2.76k
                            }
3596
3597
                            /* The Qp populated in Pre enc stage needs to overwritten with Qp
3598
                        queried from rate control*/
3599
2.76k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3600
2.76k
                                ->s_slice_hdr.i1_slice_qp_delta =
3601
2.76k
                                (WORD8)ps_curr_inp_from_me->i4_curr_frm_qp -
3602
2.76k
                                ps_enc_ctxt->as_pps[i4_bitrate_ctr].i1_pic_init_qp;
3603
2.76k
                        }
3604
3605
                        /* ------- get a filled descriptor from output Que ------------ */
3606
2.98k
                        if(/*(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag) &&*/
3607
2.98k
                           (ps_enc_ctxt->ps_stat_prms->i4_save_recon != 0))
3608
0
                        {
3609
                            /*swaping of buf_id for 0th and reference bitrate location, as encoder
3610
                        assumes always 0th loc for reference bitrate and app must receive in
3611
                        the configured order*/
3612
0
                            WORD32 i4_recon_buf_id = i4_bitrate_ctr;
3613
0
                            if(i4_bitrate_ctr == 0)
3614
0
                            {
3615
0
                                i4_recon_buf_id = ps_enc_ctxt->i4_ref_mbr_id;
3616
0
                            }
3617
0
                            else if(i4_bitrate_ctr == ps_enc_ctxt->i4_ref_mbr_id)
3618
0
                            {
3619
0
                                i4_recon_buf_id = 0;
3620
0
                            }
3621
3622
                            /* ------- get free Recon buffer from Frame buffer que ---------- */
3623
                            /* There is a separate queue for each bit-rate instnace. The recon
3624
                        buffer is acquired from the corresponding queue based on the
3625
                        bitrate instnace */
3626
0
                            ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr] =
3627
0
                                (iv_enc_recon_data_buffs_t *)ihevce_q_get_filled_buff(
3628
0
                                    (void *)ps_enc_ctxt,
3629
0
                                    IHEVCE_RECON_DATA_Q +
3630
0
                                        i4_recon_buf_id, /*decides the buffer queue */
3631
0
                                    &ps_enc_ctxt->s_multi_thrd
3632
0
                                         .recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr],
3633
0
                                    BUFF_QUE_BLOCKING_MODE);
3634
3635
0
                            ps_enc_ctxt->s_multi_thrd
3636
0
                                .is_recon_dumped[i4_enc_frm_id][i4_bitrate_ctr] = 0;
3637
0
                            ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr] =
3638
0
                                ps_enc_ctxt->s_multi_thrd
3639
0
                                    .ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr];
3640
3641
0
                            ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_end_flag =
3642
0
                                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3643
0
                                    ->i4_end_flag;
3644
0
                        }
3645
3646
2.98k
                    }  //bitrate ctr
3647
2.98k
                }
3648
2.98k
            }
3649
2.98k
            if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
3650
2.98k
            {
3651
2.98k
                ps_curr_inp =
3652
2.98k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->ps_curr_inp;
3653
2.98k
                ps_curr_inp_from_me = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3654
2.98k
                                          ->ps_curr_inp_from_me_prms;
3655
2.98k
                ps_curr_inp_enc = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id];
3656
2.98k
                ps_curr_L0_IPE_inp_prms =
3657
2.98k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3658
2.98k
                        ->ps_curr_inp_from_l0_ipe_prms;
3659
2.98k
            }
3660
2.98k
            if((NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]) &&
3661
2.98k
               ((1 == ps_curr_inp_enc->i4_frm_proc_valid_flag) &&
3662
2.76k
                (ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] == 0)))
3663
2.76k
            {
3664
5.53k
                for(i = 0; i < i4_num_bitrates; i++)
3665
2.76k
                {
3666
2.76k
                    aps_ref_list = ps_curr_inp_enc->aps_ref_list[i];
3667
                    /* acquire mutex lock for rate control calls */
3668
2.76k
                    osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
3669
3670
                    /*utlize the satd data from pre enc stage to get more accurate estimate SAD for I pic*/
3671
2.76k
                    if(ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME ||
3672
2.65k
                       ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME)
3673
579
                    {
3674
579
                        ihevce_rc_update_cur_frm_intra_satd(
3675
579
                            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3676
579
                            ps_curr_inp_from_me->i8_frame_acc_satd_cost,
3677
579
                            ps_enc_ctxt->i4_active_enc_frame_id);
3678
579
                    }
3679
3680
                    /*pels assuming satd/act is obtained for entire frame*/
3681
2.76k
                    ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered =
3682
2.76k
                        ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
3683
2.76k
                        ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
3684
3685
                    /*Service pending request to change average bitrate if any*/
3686
2.76k
                    {
3687
2.76k
                        LWORD64 i8_new_bitrate =
3688
2.76k
                            ihevce_rc_get_new_bitrate(ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3689
2.76k
                        LWORD64 i8_new_peak_bitrate = ihevce_rc_get_new_peak_bitrate(
3690
2.76k
                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3691
2.76k
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3692
2.76k
                            ->i8_buf_level_bitrate_change = -1;
3693
2.76k
                        if((i8_new_bitrate != -1) &&
3694
191
                           (i8_new_peak_bitrate != -1)) /*-1 indicates no pending request*/
3695
191
                        {
3696
191
                            LWORD64 buffer_level = ihevce_rc_change_avg_bitrate(
3697
191
                                ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3698
191
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3699
191
                                ->i8_buf_level_bitrate_change = buffer_level;
3700
191
                        }
3701
2.76k
                    }
3702
3703
2.76k
                    if((1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
3704
0
                       (1 == ps_curr_inp->s_lap_out.i4_first_frm_new_res))
3705
0
                    {
3706
                        /* Whenver change in resolution happens change the buffer level */
3707
0
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3708
0
                            ->i8_buf_level_bitrate_change = 0;
3709
0
                    }
3710
2.76k
#if 1  //KISH ELP
3711
2.76k
                    {
3712
2.76k
                        rc_bits_sad_t as_rc_frame_stat[IHEVCE_MAX_NUM_BITRATES];
3713
3714
2.76k
                        if(ps_enc_ctxt->ai4_rc_query[i] ==
3715
2.76k
                           ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)  //KISH
3716
2.55k
                        {
3717
2.55k
                            WORD32 out_buf_id[IHEVCE_MAX_NUM_BITRATES];
3718
2.55k
                            WORD32 i4_pic_type;
3719
2.55k
                            WORD32 cur_qp[IHEVCE_MAX_NUM_BITRATES];
3720
2.55k
                            ihevce_lap_output_params_t s_lap_out;
3721
3722
2.55k
                            rc_lap_out_params_t s_rc_lap_out;
3723
2.55k
                            WORD32 i4_suppress_bpic_update;
3724
3725
2.55k
                            ihevce_rc_store_retrive_update_info(
3726
2.55k
                                (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3727
2.55k
                                &as_rc_frame_stat[i],
3728
2.55k
                                ps_enc_ctxt->i4_active_enc_frame_id,
3729
2.55k
                                i,
3730
2.55k
                                2,
3731
2.55k
                                &out_buf_id[i],
3732
2.55k
                                &i4_pic_type,
3733
2.55k
                                &cur_qp[i],
3734
2.55k
                                (void *)&s_lap_out,
3735
2.55k
                                (void *)&s_rc_lap_out);
3736
3737
2.55k
                            i4_suppress_bpic_update =
3738
2.55k
                                (WORD32)(s_rc_lap_out.i4_rc_temporal_lyr_id > 1);
3739
                            /*RC inter face update before update to happen only for ELP disabled */
3740
2.55k
                            if(1 == ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
3741
2.55k
                            {
3742
                                /* SGI & Enc Loop Parallelism related changes*/
3743
2.55k
                                ihevce_rc_interface_update(
3744
2.55k
                                    (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3745
2.55k
                                    (IV_PICTURE_CODING_TYPE_T)s_rc_lap_out.i4_rc_pic_type,
3746
2.55k
                                    &s_rc_lap_out,
3747
2.55k
                                    cur_qp[i],
3748
2.55k
                                    i4_enc_frm_id_rc);
3749
2.55k
                            }
3750
3751
2.55k
                            ihevce_rc_update_pic_info(
3752
2.55k
                                (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3753
2.55k
                                (as_rc_frame_stat[i].u4_total_texture_bits +
3754
2.55k
                                 as_rc_frame_stat[i].u4_total_header_bits),  //pass total bits
3755
2.55k
                                as_rc_frame_stat[i].u4_total_header_bits,
3756
2.55k
                                as_rc_frame_stat[i].u4_total_sad,
3757
2.55k
                                as_rc_frame_stat[i].u4_total_intra_sad,
3758
2.55k
                                (IV_PICTURE_CODING_TYPE_T)i4_pic_type,
3759
2.55k
                                cur_qp[i],
3760
2.55k
                                i4_suppress_bpic_update,
3761
2.55k
                                as_rc_frame_stat[i].i4_qp_normalized_8x8_cu_sum,
3762
2.55k
                                as_rc_frame_stat[i].i4_8x8_cu_sum,
3763
2.55k
                                as_rc_frame_stat[i].i8_sad_by_qscale,
3764
2.55k
                                &s_lap_out,
3765
2.55k
                                &s_rc_lap_out,
3766
2.55k
                                out_buf_id[i],
3767
2.55k
                                as_rc_frame_stat[i].u4_open_loop_intra_sad,
3768
2.55k
                                as_rc_frame_stat[i].i8_total_ssd_frame,
3769
2.55k
                                ps_enc_ctxt
3770
2.55k
                                    ->i4_active_enc_frame_id);  //ps_curr_out->i4_inp_timestamp_low)
3771
3772
                            //DBG_PRINTF("\n Sad = %d \t total bits = %d ", s_rc_frame_stat.u4_total_sad, (s_rc_frame_stat.u4_total_texture_bits + s_rc_frame_stat.u4_total_header_bits));
3773
                            /*populate qp for pre enc*/
3774
3775
                            //g_count--;
3776
2.55k
                            ps_enc_ctxt->ai4_rc_query[i]--;
3777
3778
2.55k
                            if(i == (i4_num_bitrates - 1))
3779
2.55k
                            {
3780
2.55k
                                ihevce_rc_cal_pre_enc_qp(
3781
2.55k
                                    (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3782
3783
2.55k
                                ps_enc_ctxt->i4_active_enc_frame_id++;
3784
2.55k
                                ps_enc_ctxt->i4_active_enc_frame_id =
3785
2.55k
                                    (ps_enc_ctxt->i4_active_enc_frame_id %
3786
2.55k
                                     ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
3787
2.55k
                            }
3788
2.55k
                        }
3789
2.76k
                    }
3790
2.76k
#endif
3791
2.76k
                    if(ps_enc_ctxt->ai4_rc_query[i] < ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
3792
2.76k
                    {
3793
                        /*HEVC_RC query rate control for qp*/
3794
2.76k
                        ai4_cur_qp[i] = ihevce_rc_get_pic_quant(
3795
2.76k
                            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3796
2.76k
                            &ps_curr_inp->s_rc_lap_out,
3797
2.76k
                            ENC_GET_QP,
3798
2.76k
                            i4_enc_frm_id_rc,
3799
2.76k
                            0,
3800
2.76k
                            &ps_curr_inp->s_lap_out.ai4_frame_bits_estimated[i]);
3801
3802
2.76k
                        ps_curr_inp->s_rc_lap_out.i4_orig_rc_qp = ai4_cur_qp[i];
3803
3804
2.76k
                        ps_enc_ctxt->s_multi_thrd.i4_in_frame_rc_enabled = 0;
3805
2.76k
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3806
2.76k
                            ->i4_sub_pic_level_rc = 0;
3807
2.76k
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3808
2.76k
                            ->ai4_frame_bits_estimated =
3809
2.76k
                            ps_curr_inp->s_lap_out.ai4_frame_bits_estimated[i];
3810
3811
2.76k
                        {
3812
2.76k
                            ps_enc_ctxt->ai4_rc_query[i]++;
3813
2.76k
                        }
3814
2.76k
                    }
3815
3816
                    /* SGI & Enc Loop Parallelism related changes*/
3817
2.76k
                    ihevce_rc_interface_update(
3818
2.76k
                        (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3819
2.76k
                        (IV_PICTURE_CODING_TYPE_T)ps_curr_inp->s_lap_out.i4_pic_type,
3820
2.76k
                        &ps_curr_inp->s_rc_lap_out,
3821
2.76k
                        ai4_cur_qp[i],
3822
2.76k
                        i4_enc_frm_id_rc);
3823
3824
                    //DBG_PRINTF("HEVC_QP = %d  MPEG2_QP = %d\n",cur_qp,gu1_HEVCToMpeg2Quant[cur_qp]);//i_model_print
3825
3826
                    /* release mutex lock after rate control calls */
3827
2.76k
                    osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
3828
3829
2.76k
                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3830
2.76k
                        ->s_slice_hdr.i1_slice_qp_delta =
3831
2.76k
                        (WORD8)ai4_cur_qp[i] - ps_enc_ctxt->as_pps[i].i1_pic_init_qp;
3832
3833
2.76k
                    ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i] = ai4_cur_qp[i];
3834
3835
                    /* For interlace pictures, first_field depends on topfield_first and bottom field */
3836
2.76k
                    if(i4_field_pic)
3837
0
                    {
3838
0
                        first_field =
3839
0
                            (ps_curr_inp->s_input_buf.i4_topfield_first ^
3840
0
                             ps_curr_inp->s_input_buf.i4_bottom_field);
3841
0
                    }
3842
                    /* get frame level lambda params */
3843
2.76k
                    ihevce_get_frame_lambda_prms(
3844
2.76k
                        ps_enc_ctxt,
3845
2.76k
                        ps_curr_inp_from_me,
3846
2.76k
                        ai4_cur_qp[i],
3847
2.76k
                        first_field,
3848
2.76k
                        ps_curr_inp->s_lap_out.i4_is_ref_pic,
3849
2.76k
                        ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
3850
2.76k
                        ps_curr_inp->s_lap_out.f_i_pic_lamda_modifier,
3851
2.76k
                        i,
3852
2.76k
                        ENC_LOOP_LAMBDA_TYPE);
3853
3854
2.76k
#if ADAPT_COLOCATED_FROM_L0_FLAG
3855
2.76k
                    ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i]->i4_frame_qp =
3856
2.76k
                        ai4_cur_qp[i];
3857
2.76k
#endif
3858
2.76k
                }  //bitrate counter ends
3859
3860
                /* Reset the Dependency Mngrs local to EncLoop., ie CU_TopRight and Dblk */
3861
2.76k
                ihevce_enc_loop_dep_mngr_frame_reset(
3862
2.76k
                    ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt, i4_enc_frm_id);
3863
2.76k
            }
3864
3865
2.98k
            {
3866
                /*Set the master done flag for frame init so that other
3867
                * threads can skip it
3868
                */
3869
2.98k
                ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 1;
3870
2.98k
            }
3871
3872
            /************************************/
3873
            /******  EXIT CRITICAL SECTION ******/
3874
            /************************************/
3875
3876
            /****** Unlock the critical section ******/
3877
2.98k
            if(NULL != pv_mutex_handle_frame_init)
3878
2.98k
            {
3879
2.98k
                result_frame_init = osal_mutex_unlock(pv_mutex_handle_frame_init);
3880
2.98k
                if(OSAL_SUCCESS != result_frame_init)
3881
0
                    return 0;
3882
2.98k
            }
3883
2.98k
            ps_enc_ctxt->s_multi_thrd.i4_encode = 1;
3884
2.98k
            ps_enc_ctxt->s_multi_thrd.i4_num_re_enc = 0;
3885
            /************************************/
3886
            /******  Do Enc loop process   ******/
3887
            /************************************/
3888
            /* Each thread will run the enc-loop.
3889
            Each thread will initialize it's own enc_loop context and do the processing.
3890
            Each thread will run all the bit-rate instances one after another */
3891
2.98k
            if((i4_enc_end_flag == 0) &&
3892
2.76k
               (NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]) &&
3893
2.76k
               (1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3894
2.76k
                         ->i4_frm_proc_valid_flag))
3895
2.76k
            {
3896
2.76k
                while(1)
3897
2.76k
                {
3898
2.76k
                    ctb_enc_loop_out_t *ps_ctb_enc_loop_frm[IHEVCE_MAX_NUM_BITRATES];
3899
2.76k
                    cu_enc_loop_out_t *ps_cu_enc_loop_frm[IHEVCE_MAX_NUM_BITRATES];
3900
2.76k
                    tu_enc_loop_out_t *ps_tu_frm[IHEVCE_MAX_NUM_BITRATES];
3901
2.76k
                    pu_t *ps_pu_frm[IHEVCE_MAX_NUM_BITRATES];
3902
2.76k
                    UWORD8 *pu1_frm_coeffs[IHEVCE_MAX_NUM_BITRATES];
3903
2.76k
                    me_master_ctxt_t *ps_master_me_ctxt =
3904
2.76k
                        (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3905
2.76k
                    ihevce_enc_loop_master_ctxt_t *ps_master_ctxt =
3906
2.76k
                        (ihevce_enc_loop_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt;
3907
3908
5.53k
                    for(i = 0; i < i4_num_bitrates; i++)
3909
2.76k
                    {
3910
2.76k
                        if(i4_thrd_id == 0)
3911
2.76k
                        {
3912
2.76k
                            PROFILE_START(
3913
2.76k
                                &ps_hle_ctxt->profile_enc[ps_enc_ctxt->i4_resolution_id][i]);
3914
2.76k
                        }
3915
2.76k
                        if(NULL != ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id])
3916
2.76k
                        {
3917
2.76k
                            ps_ctb_enc_loop_frm[i] =
3918
2.76k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3919
2.76k
                                    ->ps_frm_ctb_data;
3920
2.76k
                            ps_cu_enc_loop_frm[i] =
3921
2.76k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3922
2.76k
                                    ->ps_frm_cu_data;
3923
2.76k
                            ps_tu_frm[i] =
3924
2.76k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3925
2.76k
                                    ->ps_frm_tu_data;
3926
2.76k
                            ps_pu_frm[i] =
3927
2.76k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3928
2.76k
                                    ->ps_frm_pu_data;
3929
2.76k
                            pu1_frm_coeffs[i] = (UWORD8 *)ps_enc_ctxt->s_multi_thrd
3930
2.76k
                                                    .ps_curr_out_enc_grp[i4_enc_frm_id][i]
3931
2.76k
                                                    ->pv_coeff_data;
3932
2.76k
                        }
3933
                        /*derive reference picture list based on ping or pong instnace */
3934
2.76k
                        aps_ref_list = ps_curr_inp_enc->aps_ref_list[i];
3935
3936
                        /* Always consider chroma cost when computing cost for derived instance */
3937
2.76k
                        ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id]->i4_consider_chroma_cost =
3938
2.76k
                            1;
3939
3940
                        /*************************
3941
                        * MULTI BITRATE CODE START
3942
                        **************************/
3943
2.76k
                        if(i4_num_bitrates > 1)
3944
0
                        {
3945
0
                            ihevce_mbr_quality_tool_set_configuration(
3946
0
                                ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id],
3947
0
                                ps_enc_ctxt->ps_stat_prms);
3948
0
                        }
3949
                        /************************
3950
                        * MULTI BITRATE CODE END
3951
                        *************************/
3952
                        /* picture level init of Encode loop module */
3953
2.76k
                        ihevce_enc_loop_frame_init(
3954
2.76k
                            ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
3955
2.76k
                            ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i],
3956
2.76k
                            aps_ref_list,
3957
2.76k
                            ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i],
3958
2.76k
                            &ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3959
2.76k
                                 ->s_slice_hdr,
3960
2.76k
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_pps,
3961
2.76k
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_sps,
3962
2.76k
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_vps,
3963
2.76k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i1_weighted_pred_flag,
3964
2.76k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i1_weighted_bipred_flag,
3965
2.76k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom,
3966
2.76k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom,
3967
2.76k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_poc,
3968
2.76k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_display_num,
3969
2.76k
                            ps_enc_ctxt,
3970
2.76k
                            ps_curr_inp_enc,
3971
2.76k
                            i,
3972
2.76k
                            i4_thrd_id,
3973
2.76k
                            i4_enc_frm_id,  // update this to enc_loop_ctxt struct
3974
2.76k
                            i4_num_bitrates,
3975
2.76k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_quality_preset,
3976
2.76k
                            ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3977
2.76k
                                ->pv_dep_mngr_encloop_dep_me);
3978
3979
2.76k
                        ihevce_enc_loop_process(
3980
2.76k
                            ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
3981
2.76k
                            ps_curr_inp,
3982
2.76k
                            ps_curr_inp_from_me->ps_ctb_analyse,
3983
2.76k
                            ps_curr_L0_IPE_inp_prms->ps_ipe_analyse_ctb,
3984
2.76k
                            ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i],
3985
2.76k
                            ps_curr_inp_enc->ps_cur_ctb_cu_tree,
3986
2.76k
                            ps_ctb_enc_loop_frm[i],
3987
2.76k
                            ps_cu_enc_loop_frm[i],
3988
2.76k
                            ps_tu_frm[i],
3989
2.76k
                            ps_pu_frm[i],
3990
2.76k
                            pu1_frm_coeffs[i],
3991
2.76k
                            &ps_enc_ctxt->s_frm_ctb_prms,
3992
2.76k
                            &ps_curr_inp_from_me->as_lambda_prms[i],
3993
2.76k
                            &ps_enc_ctxt->s_multi_thrd,
3994
2.76k
                            i4_thrd_id,
3995
2.76k
                            i4_enc_frm_id,
3996
2.76k
                            ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass);
3997
2.76k
                        if(i4_thrd_id == 0)
3998
2.76k
                        {
3999
2.76k
                            PROFILE_STOP(
4000
2.76k
                                &ps_hle_ctxt->profile_enc[ps_enc_ctxt->i4_resolution_id][i], NULL);
4001
2.76k
                        }
4002
2.76k
                    }  //loop over bitrate ends
4003
2.76k
                    {
4004
2.76k
                        break;
4005
2.76k
                    }
4006
2.76k
                } /*end of while(ps_enc_ctxt->s_multi_thrd.ai4_encode[i4_enc_frm_id] == 1)*/
4007
2.76k
            }
4008
4009
            /************************************/
4010
            /****** ENTER CRITICAL SECTION ******/
4011
            /************************************/
4012
4013
            /****** Lock the critical section ******/
4014
2.98k
            if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4015
2.98k
            {
4016
2.98k
                result = osal_mutex_lock(
4017
2.98k
                    ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4018
4019
2.98k
                if(OSAL_SUCCESS != result)
4020
0
                    return 0;
4021
2.98k
            }
4022
2.98k
            if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
4023
2.98k
            {
4024
                /* Increment the counter to keep track of no of threads exiting the current mutex*/
4025
2.98k
                ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id]++;
4026
4027
                /* If the end frame is reached force the last slave to enter the next critical section*/
4028
2.98k
                if(i4_enc_end_flag == 1)
4029
218
                {
4030
218
                    if(ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4031
218
                       ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds - 1)
4032
218
                    {
4033
218
                        ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] =
4034
218
                            ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
4035
218
                    }
4036
218
                }
4037
4038
2.98k
                {
4039
                    /*Last slave thread comming out of enc loop will execute next critical section*/
4040
2.98k
                    if(ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] ==
4041
2.98k
                       ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
4042
2.98k
                    {
4043
2.98k
                        iv_enc_recon_data_buffs_t *ps_recon_out_temp = NULL;
4044
2.98k
                        recon_pic_buf_t *ps_frm_recon_temp = NULL;
4045
2.98k
                        ihevce_lap_enc_buf_t *ps_curr_inp;
4046
2.98k
                        rc_lap_out_params_t *ps_rc_lap_out_next_encode;
4047
4048
2.98k
                        WORD32 ai4_act_qp[IHEVCE_MAX_NUM_BITRATES];
4049
2.98k
                        ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] = 0;
4050
4051
2.98k
                        ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
4052
2.98k
                                          ->ps_curr_inp;
4053
4054
5.97k
                        for(i = 0; i < i4_num_bitrates; i++)
4055
2.98k
                        {
4056
2.98k
                            {
4057
2.98k
                                WORD32 j, i4_avg_QP;
4058
2.98k
                                ihevce_enc_loop_master_ctxt_t *ps_master_ctxt =
4059
2.98k
                                    (ihevce_enc_loop_master_ctxt_t *)
4060
2.98k
                                        ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt;
4061
2.98k
                                ihevce_enc_loop_ctxt_t *ps_ctxt, *ps_ctxt_temp;
4062
2.98k
                                ihevce_enc_loop_ctxt_t *ps_ctxt_last_thrd;
4063
2.98k
                                LWORD64 i8_total_cu_bits_into_qscale = 0, i8_total_cu_bits = 0;
4064
2.98k
                                UWORD32 total_frame_intra_sad = 0;
4065
2.98k
                                UWORD32 total_frame_inter_sad = 0;
4066
2.98k
                                UWORD32 total_frame_sad = 0;
4067
4068
2.98k
                                LWORD64 total_frame_intra_cost = 0;
4069
2.98k
                                LWORD64 total_frame_inter_cost = 0;
4070
2.98k
                                LWORD64 total_frame_cost = 0;
4071
4072
2.98k
                                ps_ctxt_last_thrd =
4073
2.98k
                                    ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id];
4074
2.98k
                                if(ps_enc_ctxt->s_multi_thrd.i4_in_frame_rc_enabled)
4075
0
                                {
4076
0
                                    WORD32 i4_total_ctb =
4077
0
                                        ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4078
0
                                        ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert;
4079
4080
0
                                    ai4_act_qp[i] =
4081
0
                                        ps_enc_ctxt->s_multi_thrd
4082
0
                                            .ai4_curr_qp_acc[ps_ctxt_last_thrd->i4_enc_frm_id][i] /
4083
0
                                        i4_total_ctb;
4084
0
                                }
4085
2.98k
                                else
4086
2.98k
                                {
4087
2.98k
                                    ai4_act_qp[i] =
4088
2.98k
                                        ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i];
4089
2.98k
                                }
4090
4091
2.98k
                                ps_enc_ctxt->s_multi_thrd
4092
2.98k
                                    .ai4_curr_qp_acc[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4093
4094
                                /*Reset all the values of sub pic rc to default after the frame is completed */
4095
2.98k
                                {
4096
2.98k
                                    ps_enc_ctxt->s_multi_thrd
4097
2.98k
                                        .ai4_acc_ctb_ctr[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4098
2.98k
                                    ps_enc_ctxt->s_multi_thrd
4099
2.98k
                                        .ai4_ctb_ctr[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4100
4101
2.98k
                                    ps_enc_ctxt->s_multi_thrd
4102
2.98k
                                        .ai4_threshold_reached[ps_ctxt_last_thrd->i4_enc_frm_id][i] =
4103
2.98k
                                        0;
4104
4105
2.98k
                                    ps_enc_ctxt->s_multi_thrd
4106
2.98k
                                        .ai4_curr_qp_estimated[ps_ctxt_last_thrd->i4_enc_frm_id][i] =
4107
2.98k
                                        (1 << QP_LEVEL_MOD_ACT_FACTOR);
4108
4109
2.98k
                                    ps_enc_ctxt->s_multi_thrd
4110
2.98k
                                        .af_acc_hdr_bits_scale_err[ps_ctxt_last_thrd->i4_enc_frm_id]
4111
2.98k
                                                                  [i] = 0;
4112
2.98k
                                }
4113
5.97k
                                for(j = 0; j < ps_master_ctxt->i4_num_proc_thrds; j++)
4114
2.98k
                                {
4115
                                    /* ENC_LOOP state structure */
4116
2.98k
                                    ps_ctxt = ps_master_ctxt->aps_enc_loop_thrd_ctxt[j];
4117
4118
2.98k
                                    total_frame_intra_sad +=
4119
2.98k
                                        ps_ctxt
4120
2.98k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4121
2.98k
                                                                          ->i4_enc_frm_id][i]
4122
2.98k
                                            ->u4_frame_intra_sad_acc;
4123
2.98k
                                    total_frame_inter_sad +=
4124
2.98k
                                        ps_ctxt
4125
2.98k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4126
2.98k
                                                                          ->i4_enc_frm_id][i]
4127
2.98k
                                            ->u4_frame_inter_sad_acc;
4128
2.98k
                                    total_frame_sad +=
4129
2.98k
                                        ps_ctxt
4130
2.98k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4131
2.98k
                                                                          ->i4_enc_frm_id][i]
4132
2.98k
                                            ->u4_frame_sad_acc;
4133
4134
2.98k
                                    total_frame_intra_cost +=
4135
2.98k
                                        ps_ctxt
4136
2.98k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4137
2.98k
                                                                          ->i4_enc_frm_id][i]
4138
2.98k
                                            ->i8_frame_intra_cost_acc;
4139
2.98k
                                    total_frame_inter_cost +=
4140
2.98k
                                        ps_ctxt
4141
2.98k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4142
2.98k
                                                                          ->i4_enc_frm_id][i]
4143
2.98k
                                            ->i8_frame_inter_cost_acc;
4144
2.98k
                                    total_frame_cost +=
4145
2.98k
                                        ps_ctxt
4146
2.98k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4147
2.98k
                                                                          ->i4_enc_frm_id][i]
4148
2.98k
                                            ->i8_frame_cost_acc;
4149
                                    /*Reset thrd id flag once the frame is completed */
4150
2.98k
                                    ps_enc_ctxt->s_multi_thrd
4151
2.98k
                                        .ai4_thrd_id_valid_flag[ps_ctxt_last_thrd->i4_enc_frm_id][i]
4152
2.98k
                                                               [j] = -1;
4153
2.98k
                                }
4154
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4155
2.98k
                                    ->s_pic_level_info.u4_frame_sad = total_frame_sad;
4156
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4157
2.98k
                                    ->s_pic_level_info.u4_frame_intra_sad = total_frame_intra_sad;
4158
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4159
2.98k
                                    ->s_pic_level_info.u4_frame_inter_sad = total_frame_inter_sad;
4160
4161
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4162
2.98k
                                    ->s_pic_level_info.i8_frame_cost = total_frame_cost;
4163
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4164
2.98k
                                    ->s_pic_level_info.i8_frame_intra_cost = total_frame_intra_cost;
4165
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4166
2.98k
                                    ->s_pic_level_info.i8_frame_inter_cost = total_frame_inter_cost;
4167
2.98k
                            }
4168
2.98k
                            ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] = 1;
4169
2.98k
                            ps_recon_out_temp =
4170
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i];
4171
2.98k
                            ps_frm_recon_temp =
4172
2.98k
                                ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i];
4173
4174
                            /* end of frame processing only if current input is valid */
4175
2.98k
                            if(1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
4176
2.98k
                                        ->i4_frm_proc_valid_flag)
4177
2.76k
                            {
4178
2.76k
#ifndef DISABLE_SEI
4179
                                /* Calculate the SEI Hash if enabled */
4180
2.76k
                                if(0 !=
4181
2.76k
                                   ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4182
2.76k
                                       ->s_sei.i1_decoded_pic_hash_sei_flag)
4183
0
                                {
4184
0
                                    void *pv_y_buf;
4185
0
                                    void *pv_u_buf;
4186
4187
0
                                    {
4188
0
                                        pv_y_buf = ps_frm_recon_temp->s_yuv_buf_desc.pv_y_buf;
4189
0
                                        pv_u_buf = ps_frm_recon_temp->s_yuv_buf_desc.pv_u_buf;
4190
0
                                    }
4191
4192
0
                                    ihevce_populate_hash_sei(
4193
0
                                        &ps_enc_ctxt->s_multi_thrd
4194
0
                                             .ps_curr_out_enc_grp[i4_enc_frm_id][i]
4195
0
                                             ->s_sei,
4196
0
                                        ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms
4197
0
                                            .i4_internal_bit_depth,
4198
0
                                        pv_y_buf,
4199
0
                                        ps_frm_recon_temp->s_yuv_buf_desc.i4_y_wd,
4200
0
                                        ps_frm_recon_temp->s_yuv_buf_desc.i4_y_ht,
4201
0
                                        ps_frm_recon_temp->s_yuv_buf_desc.i4_y_strd,
4202
0
                                        pv_u_buf,
4203
0
                                        ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_wd,
4204
0
                                        ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_ht,
4205
0
                                        ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_strd,
4206
0
                                        0,
4207
0
                                        0);
4208
0
                                }
4209
2.76k
#endif
4210
                                /* Sending qp, poc and pic-type to entropy thread for printing on console */
4211
2.76k
                                if(ps_enc_ctxt->ps_stat_prms->i4_log_dump_level != 0)
4212
0
                                {
4213
0
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4214
0
                                        ->i4_qp =
4215
0
                                        ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i];
4216
0
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4217
0
                                        ->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
4218
0
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4219
0
                                        ->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
4220
0
                                }
4221
4222
2.76k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4223
2.76k
                                    ->i4_is_I_scenecut =
4224
2.76k
                                    ((ps_curr_inp->s_lap_out.i4_scene_type == 1) &&
4225
0
                                     (ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME ||
4226
0
                                      ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME));
4227
4228
2.76k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4229
2.76k
                                    ->i4_is_non_I_scenecut =
4230
2.76k
                                    ((ps_curr_inp->s_lap_out.i4_scene_type ==
4231
2.76k
                                      SCENE_TYPE_SCENE_CUT) &&
4232
0
                                     (ps_enc_ctxt->s_multi_thrd
4233
0
                                          .ps_curr_out_enc_grp[i4_enc_frm_id][i]
4234
0
                                          ->i4_is_I_scenecut == 0));
4235
4236
                                /*ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->i4_is_I_only_scd   = ps_curr_inp->s_lap_out.i4_is_I_only_scd;
4237
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->i4_is_non_I_scd    = ps_curr_inp->s_lap_out.i4_is_non_I_scd;
4238
4239
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->i4_is_model_valid    = ps_curr_inp->s_lap_out.i4_is_model_valid;*/
4240
4241
                                /* -------------------------------------------- */
4242
                                /*        MSE Computation for PSNR              */
4243
                                /* -------------------------------------------- */
4244
2.76k
                                if(ps_enc_ctxt->ps_stat_prms->i4_log_dump_level != 0)
4245
0
                                {
4246
0
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4247
0
                                        ->i4_qp =
4248
0
                                        ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i];
4249
0
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4250
0
                                        ->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
4251
0
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4252
0
                                        ->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
4253
0
                                }
4254
4255
                                /* if non reference B picture */
4256
2.76k
                                if(0 == ps_frm_recon_temp->i4_is_reference)
4257
23
                                {
4258
23
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4259
23
                                        ->i4_pic_type += 2;
4260
23
                                }
4261
4262
2.76k
#define FORCE_EXT_REF_PIC 0
4263
4264
                                /* -------------------------------------------- */
4265
                                /*        Dumping of recon to App Queue         */
4266
                                /* -------------------------------------------- */
4267
2.76k
                                if(1 == ps_enc_ctxt->ps_stat_prms->i4_save_recon)
4268
0
                                {
4269
0
                                    {
4270
0
                                        WORD32 i, j;
4271
0
                                        UWORD8 *pu1_recon;
4272
0
                                        UWORD8 *pu1_chrm_buf_u;
4273
0
                                        UWORD8 *pu1_chrm_buf_v;
4274
0
                                        UWORD8 *pu1_curr_recon;
4275
4276
0
                                        pu1_recon =
4277
0
                                            (UWORD8 *)ps_frm_recon_temp->s_yuv_buf_desc.pv_y_buf;
4278
4279
                                        /** Copying Luma into recon buffer  **/
4280
0
                                        pu1_curr_recon = (UWORD8 *)ps_recon_out_temp->pv_y_buf;
4281
4282
0
                                        for(j = 0; j < ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht;
4283
0
                                            j++)
4284
0
                                        {
4285
0
                                            memcpy(
4286
0
                                                pu1_curr_recon,
4287
0
                                                pu1_recon,
4288
0
                                                ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd);
4289
4290
0
                                            pu1_recon +=
4291
0
                                                ps_frm_recon_temp->s_yuv_buf_desc.i4_y_strd;
4292
0
                                            pu1_curr_recon +=
4293
0
                                                ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
4294
0
                                        }
4295
4296
                                        /* recon chroma is converted from Semiplanar to Planar for dumping */
4297
0
                                        pu1_recon =
4298
0
                                            (UWORD8 *)ps_frm_recon_temp->s_yuv_buf_desc.pv_u_buf;
4299
0
                                        pu1_chrm_buf_u = (UWORD8 *)ps_recon_out_temp->pv_cb_buf;
4300
0
                                        pu1_chrm_buf_v =
4301
0
                                            pu1_chrm_buf_u +
4302
0
                                            ((ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd >> 1) *
4303
0
                                             ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht);
4304
4305
0
                                        for(j = 0; j < ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
4306
0
                                            j++)
4307
0
                                        {
4308
0
                                            for(i = 0;
4309
0
                                                i<ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd>> 1;
4310
0
                                                i++)
4311
0
                                            {
4312
0
                                                *pu1_chrm_buf_u++ = *pu1_recon++;
4313
0
                                                *pu1_chrm_buf_v++ = *pu1_recon++;
4314
0
                                            }
4315
4316
0
                                            pu1_recon -=
4317
0
                                                ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd;
4318
0
                                            pu1_recon +=
4319
0
                                                ps_frm_recon_temp->s_yuv_buf_desc.i4_uv_strd;
4320
0
                                        }
4321
4322
                                        /* set the POC and number of bytes in Y & UV buf */
4323
0
                                        ps_recon_out_temp->i4_poc = ps_frm_recon_temp->i4_poc;
4324
0
                                        ps_recon_out_temp->i4_y_pixels =
4325
0
                                            ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
4326
0
                                            ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
4327
0
                                        ps_recon_out_temp->i4_uv_pixels =
4328
0
                                            ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd *
4329
0
                                            ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht;
4330
0
                                    }
4331
0
                                }
4332
2.76k
                                ps_frm_recon_temp->i4_non_ref_free_flag = 1;
4333
                                /* -------------------------------------------- */
4334
                                /*        End of picture updates                */
4335
                                /* -------------------------------------------- */
4336
2.76k
                            }
4337
4338
                            /* After the MSE (or PSNR) computation is done we will update
4339
                    these data in output buffer structure and then signal entropy
4340
                    thread that the buffer is produced. */
4341
2.98k
                            if(ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] == 1)
4342
2.98k
                            {
4343
                                /* set the output buffer as produced */
4344
2.98k
                                ihevce_q_set_buff_prod(
4345
2.98k
                                    (void *)ps_enc_ctxt,
4346
2.98k
                                    IHEVCE_FRM_PRS_ENT_COD_Q + i,
4347
2.98k
                                    ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i]);
4348
4349
2.98k
                                ps_enc_ctxt->s_multi_thrd.is_out_buf_freed[i4_enc_frm_id][i] = 1;
4350
2.98k
                                ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] = 0;
4351
2.98k
                            }
4352
4353
2.98k
                        }  //bit-rate counter ends
4354
                        /* -------------------------------------------- */
4355
                        /*        Frame level RC update                 */
4356
                        /* -------------------------------------------- */
4357
                        /* Query enc_loop to get the Parameters for Rate control */
4358
2.98k
                        if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
4359
2.76k
                        {
4360
2.76k
                            frm_proc_ent_cod_ctxt_t *ps_curr_out = NULL;
4361
                            /*HEVC_RC*/
4362
2.76k
                            rc_bits_sad_t as_rc_frame_stat[IHEVCE_MAX_NUM_BITRATES];
4363
2.76k
                            osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4364
4365
5.53k
                            for(i = 0; i < i4_num_bitrates; i++)
4366
2.76k
                            {
4367
                                /*each bit-rate RC params are collated by master thread */
4368
2.76k
                                ihevce_enc_loop_get_frame_rc_prms(
4369
2.76k
                                    ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
4370
2.76k
                                    &as_rc_frame_stat[i],
4371
2.76k
                                    i,
4372
2.76k
                                    i4_enc_frm_id);
4373
4374
                                /*update bits estimate on rd opt thread so that mismatch between rdopt and entropy can be taken care of*/
4375
2.76k
                                ps_curr_out =
4376
2.76k
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i];
4377
4378
2.76k
                                ps_rc_lap_out_next_encode =
4379
2.76k
                                    (rc_lap_out_params_t *)
4380
2.76k
                                        ps_curr_inp->s_rc_lap_out.ps_rc_lap_out_next_encode;
4381
4382
2.76k
                                ps_curr_out->i4_is_end_of_idr_gop = 0;
4383
4384
2.76k
                                if(NULL != ps_rc_lap_out_next_encode)
4385
0
                                {
4386
0
                                    if(ps_rc_lap_out_next_encode->i4_rc_pic_type == IV_IDR_FRAME)
4387
0
                                    {
4388
                                        /*If the next pic is IDR, then signal end of gopf for current frame*/
4389
0
                                        ps_curr_out->i4_is_end_of_idr_gop = 1;
4390
0
                                    }
4391
0
                                }
4392
2.76k
                                else if(NULL == ps_rc_lap_out_next_encode)
4393
2.76k
                                {
4394
                                    /*If the lap out next is NULL, then end of sequence reached*/
4395
2.76k
                                    ps_curr_out->i4_is_end_of_idr_gop = 1;
4396
2.76k
                                }
4397
4398
2.76k
                                if(NULL == ps_curr_out)
4399
0
                                {
4400
0
                                    DBG_PRINTF("error in getting curr out in encode loop\n");
4401
0
                                }
4402
4403
                                //DBG_PRINTF("\nRDOPT head = %d RDOPT text = %d\n",s_rc_frame_stat.u4_total_header_bits,s_rc_frame_stat.u4_total_texture_bits);
4404
                                /* acquire mutex lock for rate control calls */
4405
4406
                                /* Note : u4_total_intra_sad coming out of enc_loop */
4407
                                /* will not be accurate becos of intra gating       */
4408
                                /* need to access the importance of this sad in RC  */
4409
4410
                                //Store the rc update parameters for deterministic Enc loop parallelism
4411
4412
2.76k
                                {
4413
2.76k
                                    ihevce_rc_store_retrive_update_info(
4414
2.76k
                                        (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4415
2.76k
                                        &as_rc_frame_stat[i],
4416
2.76k
                                        i4_enc_frm_id_rc,
4417
2.76k
                                        i,
4418
2.76k
                                        1,
4419
2.76k
                                        &ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i],
4420
2.76k
                                        &ps_curr_inp->s_lap_out.i4_pic_type,
4421
2.76k
                                        &ai4_act_qp[i],
4422
2.76k
                                        (void *)&ps_curr_inp->s_lap_out,
4423
2.76k
                                        (void *)&ps_curr_inp->s_rc_lap_out);  // STORE
4424
2.76k
                                }
4425
2.76k
                            }
4426
4427
                            /* release mutex lock after rate control calls */
4428
2.76k
                            osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4429
2.76k
                        }
4430
2.98k
                        if((ps_enc_ctxt->ps_stat_prms->i4_save_recon != 0) /*&&
4431
2.98k
                                                                   (1 == ps_curr_inp->s_input_buf.s_input_buf.i4_inp_frm_data_valid_flag)*/)
4432
0
                        {
4433
0
                            WORD32 i4_bitrate_ctr;
4434
0
                            for(i4_bitrate_ctr = 0; i4_bitrate_ctr < i4_num_bitrates;
4435
0
                                i4_bitrate_ctr++)
4436
0
                            {
4437
                                /*swaping of buf_id for 0th and reference bitrate location, as encoder
4438
                        assumes always 0th loc for reference bitrate and app must receive in
4439
                        the configured order*/
4440
0
                                WORD32 i4_recon_buf_id = i4_bitrate_ctr;
4441
0
                                if(i4_bitrate_ctr == 0)
4442
0
                                {
4443
0
                                    i4_recon_buf_id = ps_enc_ctxt->i4_ref_mbr_id;
4444
0
                                }
4445
0
                                else if(i4_bitrate_ctr == ps_enc_ctxt->i4_ref_mbr_id)
4446
0
                                {
4447
0
                                    i4_recon_buf_id = 0;
4448
0
                                }
4449
4450
                                /* Call back to Apln. saying recon buffer is produced */
4451
0
                                ps_hle_ctxt->ihevce_output_recon_fill_done(
4452
0
                                    ps_hle_ctxt->pv_recon_cb_handle,
4453
0
                                    ps_enc_ctxt->s_multi_thrd
4454
0
                                        .ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr],
4455
0
                                    i4_recon_buf_id, /* br instance */
4456
0
                                    i4_resolution_id /* res_intance */);
4457
4458
                                /* --- release the current recon buffer ---- */
4459
0
                                ihevce_q_rel_buf(
4460
0
                                    (void *)ps_enc_ctxt,
4461
0
                                    (IHEVCE_RECON_DATA_Q + i4_recon_buf_id),
4462
0
                                    ps_enc_ctxt->s_multi_thrd
4463
0
                                        .recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr]);
4464
4465
0
                                ps_enc_ctxt->s_multi_thrd
4466
0
                                    .is_recon_dumped[i4_enc_frm_id][i4_bitrate_ctr] = 1;
4467
0
                            }
4468
0
                        }
4469
4470
2.98k
                        if(i4_enc_end_flag == 1)
4471
218
                        {
4472
218
                            if(ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] == 0)
4473
218
                            {
4474
                                /* release the pre_enc/enc queue buffer */
4475
218
                                ihevce_q_rel_buf(
4476
218
                                    (void *)ps_enc_ctxt,
4477
218
                                    IHEVCE_PRE_ENC_ME_Q,
4478
218
                                    ps_curr_inp_enc->curr_inp_from_me_buf_id);
4479
4480
218
                                ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] = 1;
4481
218
                            }
4482
218
                        }
4483
                        /* release encoder owned input buffer*/
4484
2.98k
                        ihevce_q_rel_buf(
4485
2.98k
                            (void *)ps_enc_ctxt,
4486
2.98k
                            IHEVCE_INPUT_DATA_CTRL_Q,
4487
2.98k
                            ps_curr_inp_enc->curr_inp_buf_id);
4488
                        /* release the pre_enc/enc queue buffer */
4489
2.98k
                        ihevce_q_rel_buf(
4490
2.98k
                            ps_enc_ctxt,
4491
2.98k
                            IHEVCE_PRE_ENC_ME_Q,
4492
2.98k
                            ps_curr_inp_enc->curr_inp_from_me_buf_id);
4493
4494
2.98k
                        ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] = 1;
4495
4496
                        /* release the pre_enc/enc queue buffer */
4497
2.98k
                        ihevce_q_rel_buf(
4498
2.98k
                            ps_enc_ctxt,
4499
2.98k
                            IHEVCE_L0_IPE_ENC_Q,
4500
2.98k
                            ps_curr_inp_enc->curr_inp_from_l0_ipe_buf_id);
4501
4502
2.98k
                        ps_enc_ctxt->s_multi_thrd.is_L0_ipe_in_buf_freed[i4_enc_frm_id] = 1;
4503
                        /* release the me/enc queue buffer */
4504
2.98k
                        ihevce_q_rel_buf(
4505
2.98k
                            ps_enc_ctxt,
4506
2.98k
                            IHEVCE_ME_ENC_RDOPT_Q,
4507
2.98k
                            ps_enc_ctxt->s_multi_thrd.i4_enc_in_buf_id[i4_enc_frm_id]);
4508
4509
                        /* reset the pointers to NULL */
4510
2.98k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] = NULL;
4511
2.98k
                        ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 0;
4512
5.97k
                        for(i = 0; i < i4_num_bitrates; i++)
4513
2.98k
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i] = NULL;
4514
4515
                        /* Set the prev_frame_done variable to 1 to indicate that
4516
                *prev frame is done */
4517
2.98k
                        ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_done);
4518
2.98k
                    }
4519
2.98k
                }
4520
2.98k
            }
4521
0
            else
4522
0
            {
4523
                /* Increment the counter to keep track of no of threads exiting the current mutex*/
4524
0
                ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id]++;
4525
                /*Last slave thread comming out of enc loop will execute next critical section*/
4526
0
                if(ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] ==
4527
0
                   ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
4528
0
                {
4529
0
                    ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] = 0;
4530
4531
                    /* reset the pointers to NULL */
4532
0
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] = NULL;
4533
4534
0
                    ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 0;
4535
4536
0
                    for(i = 0; i < i4_num_bitrates; i++)
4537
0
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i] = NULL;
4538
4539
                    /* Set the prev_frame_done variable to 1 to indicate that
4540
                        *prev frame is done
4541
                        */
4542
0
                    ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_done);
4543
0
                }
4544
0
            }
4545
4546
            /* Toggle the ping pong flag of the thread exiting curr frame*/
4547
            /*ps_enc_ctxt->s_multi_thrd.ping_pong[ps_thrd_ctxt->i4_thrd_id] =
4548
                !ps_enc_ctxt->s_multi_thrd.ping_pong[ps_thrd_ctxt->i4_thrd_id];*/
4549
2.98k
        }
4550
4551
        /************************************/
4552
        /******  EXIT CRITICAL SECTION ******/
4553
        /************************************/
4554
        /****** Unlock the critical section ******/
4555
2.98k
        if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4556
2.98k
        {
4557
2.98k
            result = osal_mutex_unlock(
4558
2.98k
                ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4559
2.98k
            if(OSAL_SUCCESS != result)
4560
0
                return 0;
4561
2.98k
        }
4562
4563
2.98k
        if((0 == i4_me_end_flag) && (0 == i4_enc_end_flag))
4564
2.76k
        {
4565
2.76k
            i4_enc_frm_id++;
4566
2.76k
            i4_enc_frm_id_rc++;
4567
4568
2.76k
            if(i4_enc_frm_id == NUM_ME_ENC_BUFS)
4569
2.76k
            {
4570
2.76k
                i4_enc_frm_id = 0;
4571
2.76k
            }
4572
4573
2.76k
            if(i4_enc_frm_id_rc == ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
4574
2.76k
            {
4575
2.76k
                i4_enc_frm_id_rc = 0;
4576
2.76k
            }
4577
2.76k
            i4_me_frm_id++;
4578
4579
2.76k
            if(i4_me_frm_id == NUM_ME_ENC_BUFS)
4580
2.76k
                i4_me_frm_id = 0;
4581
2.76k
        }
4582
2.98k
        if(1 == ps_enc_ctxt->s_multi_thrd.i4_force_end_flag)
4583
0
        {
4584
0
            i4_me_end_flag = 1;
4585
0
            i4_enc_end_flag = 1;
4586
0
        }
4587
2.98k
    }
4588
4589
    /****** Lock the critical section ******/
4590
4591
218
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4592
218
    {
4593
218
        WORD32 result;
4594
4595
218
        result =
4596
218
            osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4597
4598
218
        if(OSAL_SUCCESS != result)
4599
0
            return 0;
4600
218
    }
4601
4602
218
    if(ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4603
218
       (ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds - 1))
4604
218
    {
4605
218
        if(1 != ps_enc_ctxt->s_multi_thrd.i4_force_end_flag)
4606
218
        {
4607
218
            osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4608
436
            for(i = 0; i < ps_enc_ctxt->i4_num_bitrates; i++)
4609
218
            {
4610
218
                ihevce_rc_close(
4611
218
                    ps_enc_ctxt,
4612
218
                    ps_enc_ctxt->i4_active_enc_frame_id,
4613
218
                    2,
4614
218
                    MIN(ps_enc_ctxt->ai4_rc_query[i], ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc),
4615
218
                    i);
4616
218
            }
4617
218
            osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4618
218
        }
4619
218
    }
4620
4621
218
    ps_enc_ctxt->s_multi_thrd.num_thrds_done++;
4622
4623
    /****** UnLock the critical section ******/
4624
218
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4625
218
    {
4626
218
        WORD32 result;
4627
4628
218
        result =
4629
218
            osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4630
4631
218
        if(OSAL_SUCCESS != result)
4632
0
            return 0;
4633
218
    }
4634
4635
    /****** Lock the critical section ******/
4636
218
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4637
218
    {
4638
218
        WORD32 result;
4639
218
        result =
4640
218
            osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4641
4642
218
        if(OSAL_SUCCESS != result)
4643
0
            return 0;
4644
218
    }
4645
218
    if((ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4646
218
        ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) &&
4647
218
       (ps_enc_ctxt->s_multi_thrd.i4_force_end_flag))
4648
0
    {
4649
0
        WORD32 num_bufs_preenc_me_que, num_bufs_L0_ipe_enc;
4650
0
        WORD32 buf_id_ctr, frm_id_ctr;
4651
0
        frm_proc_ent_cod_ctxt_t *ps_curr_out_enc_ent[IHEVCE_MAX_NUM_BITRATES];
4652
0
        WORD32 out_buf_id_enc_ent[IHEVCE_MAX_NUM_BITRATES];
4653
4654
0
        if(ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel > 1)
4655
0
        {
4656
0
            num_bufs_preenc_me_que = (MAX_L0_IPE_ENC_STAGGER - 1) + MIN_L1_L0_STAGGER_NON_SEQ +
4657
0
                                     NUM_BUFS_DECOMP_HME +
4658
0
                                     ps_enc_ctxt->ps_stat_prms->s_lap_prms.i4_rc_look_ahead_pics;
4659
4660
0
            num_bufs_L0_ipe_enc = MAX_L0_IPE_ENC_STAGGER;
4661
0
        }
4662
0
        else
4663
0
        {
4664
0
            num_bufs_preenc_me_que = (MIN_L0_IPE_ENC_STAGGER - 1) + MIN_L1_L0_STAGGER_NON_SEQ +
4665
0
                                     NUM_BUFS_DECOMP_HME +
4666
0
                                     ps_enc_ctxt->ps_stat_prms->s_lap_prms.i4_rc_look_ahead_pics;
4667
4668
0
            num_bufs_L0_ipe_enc = MIN_L0_IPE_ENC_STAGGER;
4669
0
        }
4670
0
        for(buf_id_ctr = 0; buf_id_ctr < num_bufs_preenc_me_que; buf_id_ctr++)
4671
0
        {
4672
            /* release encoder owned input buffer*/
4673
0
            ihevce_q_rel_buf((void *)ps_enc_ctxt, IHEVCE_PRE_ENC_ME_Q, buf_id_ctr);
4674
0
        }
4675
0
        for(buf_id_ctr = 0; buf_id_ctr < num_bufs_L0_ipe_enc; buf_id_ctr++)
4676
0
        {
4677
            /* release encoder owned input buffer*/
4678
0
            ihevce_q_rel_buf((void *)ps_enc_ctxt, IHEVCE_L0_IPE_ENC_Q, buf_id_ctr);
4679
0
        }
4680
0
        for(frm_id_ctr = 0; frm_id_ctr < NUM_ME_ENC_BUFS; frm_id_ctr++)
4681
0
        {
4682
0
            for(i = 0; i < ps_enc_ctxt->i4_num_bitrates; i++)
4683
0
            {
4684
0
                if(NULL != ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[frm_id_ctr][i])
4685
0
                {
4686
0
                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[frm_id_ctr][i]
4687
0
                        ->i4_frm_proc_valid_flag = 0;
4688
0
                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[frm_id_ctr][i]->i4_end_flag = 1;
4689
                    /* set the output buffer as produced */
4690
0
                    ihevce_q_set_buff_prod(
4691
0
                        (void *)ps_enc_ctxt,
4692
0
                        IHEVCE_FRM_PRS_ENT_COD_Q + i,
4693
0
                        ps_enc_ctxt->s_multi_thrd.out_buf_id[frm_id_ctr][i]);
4694
0
                }
4695
0
            }
4696
0
        }
4697
0
        for(buf_id_ctr = 0; buf_id_ctr < NUM_FRMPROC_ENTCOD_BUFS;
4698
0
            buf_id_ctr++) /*** Set buffer produced for NUM_FRMPROC_ENTCOD_BUFS buffers for entropy to exit ***/
4699
0
        {
4700
0
            for(i = 0; i < ps_enc_ctxt->i4_num_bitrates; i++)
4701
0
            {
4702
0
                ps_curr_out_enc_ent[i] = (frm_proc_ent_cod_ctxt_t *)ihevce_q_get_free_buff(
4703
0
                    (void *)ps_enc_ctxt,
4704
0
                    IHEVCE_FRM_PRS_ENT_COD_Q + i, /*decides the buffer queue */
4705
0
                    &out_buf_id_enc_ent[i],
4706
0
                    BUFF_QUE_NON_BLOCKING_MODE);
4707
0
                if(NULL != ps_curr_out_enc_ent[i])
4708
0
                {
4709
0
                    ps_curr_out_enc_ent[i]->i4_frm_proc_valid_flag = 0;
4710
0
                    ps_curr_out_enc_ent[i]->i4_end_flag = 1;
4711
                    /* set the output buffer as produced */
4712
0
                    ihevce_q_set_buff_prod(
4713
0
                        (void *)ps_enc_ctxt, IHEVCE_FRM_PRS_ENT_COD_Q + i, out_buf_id_enc_ent[i]);
4714
0
                }
4715
0
            }
4716
0
        }
4717
0
    }
4718
4719
    /* The last thread coming out of Enc. Proc. */
4720
    /* Release all the Recon buffers the application might have queued in */
4721
218
    if((ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4722
218
        ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) &&
4723
218
       (ps_enc_ctxt->ps_stat_prms->i4_save_recon != 0) &&
4724
0
       (ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done == 0))
4725
0
    {
4726
0
        WORD32 i4_bitrate_ctr;
4727
4728
0
        for(i4_bitrate_ctr = 0; i4_bitrate_ctr < i4_num_bitrates; i4_bitrate_ctr++)
4729
0
        {
4730
0
            WORD32 end_flag = 0;
4731
0
            while(0 == end_flag)
4732
0
            {
4733
                /*swaping of buf_id for 0th and reference bitrate location, as encoder
4734
                assumes always 0th loc for reference bitrate and app must receive in
4735
                the configured order*/
4736
0
                WORD32 i4_recon_buf_id = i4_bitrate_ctr;
4737
0
                if(i4_bitrate_ctr == 0)
4738
0
                {
4739
0
                    i4_recon_buf_id = ps_enc_ctxt->i4_ref_mbr_id;
4740
0
                }
4741
0
                else if(i4_bitrate_ctr == ps_enc_ctxt->i4_ref_mbr_id)
4742
0
                {
4743
0
                    i4_recon_buf_id = 0;
4744
0
                }
4745
4746
                /* ------- get free Recon buffer from Frame buffer que ---------- */
4747
                /* There is a separate queue for each bit-rate instnace. The recon
4748
                buffer is acquired from the corresponding queue based on the
4749
                bitrate instnace */
4750
0
                ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr] =
4751
0
                    (iv_enc_recon_data_buffs_t *)ihevce_q_get_filled_buff(
4752
0
                        (void *)ps_enc_ctxt,
4753
0
                        IHEVCE_RECON_DATA_Q + i4_recon_buf_id, /*decides the buffer queue */
4754
0
                        &ps_enc_ctxt->s_multi_thrd.recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr],
4755
0
                        BUFF_QUE_BLOCKING_MODE);
4756
4757
                /* Update the end_flag from application */
4758
0
                end_flag = ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]
4759
0
                               ->i4_is_last_buf;
4760
4761
0
                ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_end_flag =
4762
0
                    1;
4763
0
                ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_y_pixels =
4764
0
                    0;
4765
0
                ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_uv_pixels =
4766
0
                    0;
4767
4768
                /* Call back to Apln. saying recon buffer is produced */
4769
0
                ps_hle_ctxt->ihevce_output_recon_fill_done(
4770
0
                    ps_hle_ctxt->pv_recon_cb_handle,
4771
0
                    ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i4_bitrate_ctr],
4772
0
                    i4_recon_buf_id, /* br instance */
4773
0
                    i4_resolution_id /* res_intance */);
4774
4775
                /* --- release the current recon buffer ---- */
4776
0
                ihevce_q_rel_buf(
4777
0
                    (void *)ps_enc_ctxt,
4778
0
                    (IHEVCE_RECON_DATA_Q + i4_recon_buf_id),
4779
0
                    ps_enc_ctxt->s_multi_thrd.recon_buf_id[i4_enc_frm_id][i4_bitrate_ctr]);
4780
0
            }
4781
0
        }
4782
        /* Set the recon free done flag */
4783
0
        ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done = 1;
4784
0
    }
4785
4786
    /****** UnLock the critical section ******/
4787
218
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4788
218
    {
4789
218
        WORD32 result;
4790
218
        result =
4791
218
            osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4792
4793
218
        if(OSAL_SUCCESS != result)
4794
0
            return 0;
4795
218
    }
4796
4797
218
    return (0);
4798
218
}
4799
4800
/*!
4801
******************************************************************************
4802
* \if Function name : ihevce_set_pre_enc_prms \endif
4803
*
4804
* \brief
4805
*    Set CTB parameters
4806
*    Set ME params
4807
*    Set pps, sps, vps, vui params
4808
*    Do RC init
4809
*
4810
* \param[in] Encoder context pointer
4811
*
4812
* \return
4813
*    None
4814
*
4815
* \author
4816
*  Ittiam
4817
*
4818
*****************************************************************************
4819
*/
4820
void ihevce_set_pre_enc_prms(enc_ctxt_t *ps_enc_ctxt)
4821
218
{
4822
218
    WORD32 i;
4823
218
    WORD32 i4_num_instance,
4824
218
        i4_resolution_id = ps_enc_ctxt->i4_resolution_id;  //number of bit-rate instances
4825
4826
218
    i4_num_instance = ps_enc_ctxt->i4_num_bitrates;
4827
4828
#if PIC_ALIGN_CTB_SIZE
4829
4830
    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd =
4831
        ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width +
4832
        SET_CTB_ALIGN(
4833
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width,
4834
            ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
4835
4836
    ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4837
        ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4838
4839
    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht =
4840
        ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height +
4841
        SET_CTB_ALIGN(
4842
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height,
4843
            ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
4844
4845
    ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4846
        ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4847
#else  // PIC_ALIGN_CTB_SIZE
4848
    /* Allign the frame width to min CU size */
4849
218
    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd =
4850
218
        ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width +
4851
218
        SET_CTB_ALIGN(
4852
218
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width,
4853
218
            ps_enc_ctxt->s_frm_ctb_prms.i4_min_cu_size);
4854
4855
218
    ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4856
218
        ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4857
4858
218
    if((ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd %
4859
218
        ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size) != 0)
4860
127
        ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4861
127
            ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz + 1;
4862
4863
    /* Allign the frame hieght to min CU size */
4864
218
    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht =
4865
218
        ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height +
4866
218
        SET_CTB_ALIGN(
4867
218
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height,
4868
218
            ps_enc_ctxt->s_frm_ctb_prms.i4_min_cu_size);
4869
4870
218
    ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4871
218
        ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4872
4873
218
    if((ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht %
4874
218
        ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size) != 0)
4875
134
        ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4876
134
            ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert + 1;
4877
4878
218
#endif  // PIC_ALIGN_CTB_SIZE
4879
4880
218
    ps_enc_ctxt->s_frm_ctb_prms.i4_max_cus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4881
218
                                                    ps_enc_ctxt->s_frm_ctb_prms.i4_num_cus_in_ctb;
4882
4883
218
    ps_enc_ctxt->s_frm_ctb_prms.i4_max_pus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4884
218
                                                    ps_enc_ctxt->s_frm_ctb_prms.i4_num_pus_in_ctb;
4885
4886
218
    ps_enc_ctxt->s_frm_ctb_prms.i4_max_tus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4887
218
                                                    ps_enc_ctxt->s_frm_ctb_prms.i4_num_tus_in_ctb;
4888
218
    ihevce_coarse_me_set_resolution(
4889
218
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
4890
218
        1,
4891
218
        &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd,
4892
218
        &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht);
4893
4894
    /*if Resolution need to be changed dynamically then needs to go to encode group */
4895
218
    ihevce_me_set_resolution(
4896
218
        ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
4897
218
        1,
4898
218
        &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd,
4899
218
        &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht);
4900
218
    i4_num_instance = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
4901
218
                          .i4_num_bitrate_instances;
4902
436
    for(i = 0; i < i4_num_instance; i++)
4903
218
    {
4904
218
        WORD32 i4_id;
4905
        /*swaping of buf_id for 0th and reference bitrate location, as encoder
4906
        assumes always 0th loc for reference bitrate and app must receive in
4907
        the configured order*/
4908
218
        if(i == 0)
4909
218
        {
4910
218
            i4_id = ps_enc_ctxt->i4_ref_mbr_id;
4911
218
        }
4912
0
        else if(i == ps_enc_ctxt->i4_ref_mbr_id)
4913
0
        {
4914
0
            i4_id = 0;
4915
0
        }
4916
0
        else
4917
0
        {
4918
0
            i4_id = i;
4919
0
        }
4920
        /* populate vps based on encoder configuration and tools */
4921
218
        ihevce_populate_vps(
4922
218
            ps_enc_ctxt,
4923
218
            &ps_enc_ctxt->as_vps[i],
4924
218
            &ps_enc_ctxt->s_runtime_src_prms,
4925
218
            &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4926
218
            &ps_enc_ctxt->s_runtime_coding_prms,
4927
218
            &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4928
218
            ps_enc_ctxt->ps_stat_prms,
4929
218
            i4_resolution_id);
4930
4931
        /* populate sps based on encoder configuration and tools */
4932
218
        ihevce_populate_sps(
4933
218
            ps_enc_ctxt,
4934
218
            &ps_enc_ctxt->as_sps[i],
4935
218
            &ps_enc_ctxt->as_vps[i],
4936
218
            &ps_enc_ctxt->s_runtime_src_prms,
4937
218
            &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4938
218
            &ps_enc_ctxt->s_runtime_coding_prms,
4939
218
            &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4940
218
            &ps_enc_ctxt->s_frm_ctb_prms,
4941
218
            ps_enc_ctxt->ps_stat_prms,
4942
218
            i4_resolution_id);
4943
4944
        /* populate pps based on encoder configuration and tools */
4945
218
        ihevce_populate_pps(
4946
218
            &ps_enc_ctxt->as_pps[i],
4947
218
            &ps_enc_ctxt->as_sps[i],
4948
218
            &ps_enc_ctxt->s_runtime_src_prms,
4949
218
            &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4950
218
            &ps_enc_ctxt->s_runtime_coding_prms,
4951
218
            &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4952
218
            ps_enc_ctxt->ps_stat_prms,
4953
218
            i4_id,
4954
218
            i4_resolution_id,
4955
218
            ps_enc_ctxt->ps_tile_params_base,
4956
218
            &ps_enc_ctxt->ai4_column_width_array[0],
4957
218
            &ps_enc_ctxt->ai4_row_height_array[0]);
4958
4959
        // if(ps_enc_ctxt->as_sps[i].i1_vui_parameters_present_flag == 1)
4960
218
        {
4961
218
            WORD32 error_code = ihevce_populate_vui(
4962
218
                                    &ps_enc_ctxt->as_sps[i].s_vui_parameters,
4963
218
                                    &ps_enc_ctxt->as_sps[i],
4964
218
                                    &ps_enc_ctxt->s_runtime_src_prms,
4965
218
                                    &ps_enc_ctxt->ps_stat_prms->s_vui_sei_prms,
4966
218
                                    i4_resolution_id,
4967
218
                                    &ps_enc_ctxt->s_runtime_tgt_params,
4968
218
                                    ps_enc_ctxt->ps_stat_prms,
4969
218
                                    i4_id);
4970
218
            if (error_code)
4971
0
            {
4972
0
                ((ihevce_hle_ctxt_t *)ps_enc_ctxt->pv_hle_ctxt)->i4_error_code = error_code;
4973
0
                return;
4974
0
            }
4975
218
        }
4976
218
    }
4977
4978
218
    osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4979
    /* run the loop over all bit-rate instnaces */
4980
436
    for(i = 0; i < i4_num_instance; i++)
4981
218
    {
4982
        /*HEVC_RC Do one time initialization of rate control*/
4983
218
        ihevce_rc_init(
4984
218
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4985
218
            &ps_enc_ctxt->s_runtime_src_prms,
4986
218
            &ps_enc_ctxt->s_runtime_tgt_params,
4987
218
            &ps_enc_ctxt->s_rc_quant,
4988
218
            &ps_enc_ctxt->ps_stat_prms->s_sys_api,
4989
218
            &ps_enc_ctxt->ps_stat_prms->s_lap_prms,
4990
218
            ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
4991
4992
218
        ihevce_vbv_complaince_init_level(
4993
218
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4994
218
            &ps_enc_ctxt->as_sps[i].s_vui_parameters);
4995
218
    }
4996
218
    osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4997
218
}
4998
4999
/*!
5000
******************************************************************************
5001
* \if Function name : ihevce_pre_enc_init \endif
5002
*
5003
* \brief
5004
*   set out_buf params
5005
*   Calculate end_flag if flushmode on
5006
*   Slice initialization
5007
*   Populate SIE params
5008
*   reference list creation
5009
*
5010
* \param[in] Encoder context pointer
5011
*
5012
* \return
5013
*    None
5014
*
5015
* \author
5016
*  Ittiam
5017
*
5018
*****************************************************************************
5019
*/
5020
void ihevce_pre_enc_init(
5021
    enc_ctxt_t *ps_enc_ctxt,
5022
    ihevce_lap_enc_buf_t *ps_curr_inp,
5023
    pre_enc_me_ctxt_t *ps_curr_out,
5024
    WORD32 *pi4_end_flag_ret,
5025
    WORD32 *pi4_cur_qp_ret,
5026
    WORD32 *pi4_decomp_lyr_idx,
5027
    WORD32 i4_ping_pong)
5028
2.76k
{
5029
2.76k
    WORD32 end_flag = 0;
5030
2.76k
    WORD32 cur_qp;
5031
    //recon_pic_buf_t *ps_frm_recon;
5032
2.76k
    WORD32 first_field = 1;
5033
2.76k
    WORD32 i4_field_pic = ps_enc_ctxt->s_runtime_src_prms.i4_field_pic;
5034
2.76k
    WORD32 i4_decomp_lyrs_idx = 0;
5035
2.76k
    WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
5036
2.76k
    WORD32 slice_type = ISLICE;
5037
2.76k
    WORD32 nal_type;
5038
2.76k
    WORD32 min_cu_size;
5039
5040
2.76k
    WORD32 stasino_enabled;
5041
5042
    /* copy the time stamps from inp to entropy inp */
5043
2.76k
    ps_curr_out->i4_inp_timestamp_low = ps_curr_inp->s_input_buf.i4_inp_timestamp_low;
5044
2.76k
    ps_curr_out->i4_inp_timestamp_high = ps_curr_inp->s_input_buf.i4_inp_timestamp_high;
5045
2.76k
    ps_curr_out->pv_app_frm_ctxt = ps_curr_inp->s_input_buf.pv_app_frm_ctxt;
5046
5047
    /* get the min cu size from config params */
5048
2.76k
    min_cu_size = ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_min_log2_cu_size;
5049
5050
2.76k
    min_cu_size = 1 << min_cu_size;
5051
5052
2.76k
    ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd =
5053
2.76k
        ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd +
5054
2.76k
        SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd, min_cu_size);
5055
5056
2.76k
    ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht =
5057
2.76k
        ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht +
5058
2.76k
        SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht, min_cu_size);
5059
5060
2.76k
    ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd =
5061
2.76k
        ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd +
5062
2.76k
        SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd, min_cu_size);
5063
5064
2.76k
    if(IV_YUV_420SP_UV == ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format)
5065
2.76k
    {
5066
2.76k
        ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht =
5067
2.76k
            ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht +
5068
2.76k
            SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht, (min_cu_size >> 1));
5069
2.76k
    }
5070
0
    else if(IV_YUV_422SP_UV == ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format)
5071
0
    {
5072
0
        ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht =
5073
0
            ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht +
5074
0
            SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht, min_cu_size);
5075
0
    }
5076
5077
    /* update the END flag from LAP out */
5078
2.76k
    end_flag = ps_curr_inp->s_lap_out.i4_end_flag;
5079
2.76k
    ps_curr_out->i4_end_flag = end_flag;
5080
2.76k
    ps_enc_ctxt->s_multi_thrd.i4_last_pic_flag = end_flag;
5081
5082
    /* ----------------------------------------------------------------------*/
5083
    /*  Slice initialization for current frame; Required for entropy context */
5084
    /* ----------------------------------------------------------------------*/
5085
2.76k
    {
5086
2.76k
        WORD32 cur_poc = ps_curr_inp->s_lap_out.i4_poc;
5087
5088
        /* max merge candidates derived based on quality preset for now */
5089
2.76k
        WORD32 max_merge_candidates = 2;
5090
5091
        /* pocs less than random acess poc tagged for discard as they */
5092
        /* could be refering to pics before the cra.                  */
5093
5094
        /* CRA case: as the leading pictures can refer the picture precedes the associated
5095
        IRAP(CRA) in decoding order, hence make it Random access skipped leading pictures (RASL)*/
5096
5097
2.76k
        if((1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_enable_temporal_scalability) &&
5098
0
           (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers ==
5099
0
            ps_curr_inp->s_lap_out.i4_temporal_lyr_id))  //TEMPORALA_SCALABILITY CHANGES
5100
0
        {
5101
0
            if(ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5102
0
            {
5103
0
                nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5104
0
                               ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RASL_R : NAL_RASL_N)
5105
0
                               : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TSA_R : NAL_TSA_N);
5106
0
            }
5107
            /* IDR case: as the leading pictures can't refer the picture precedes the associated
5108
            IRAP(IDR) in decoding order, hence make it Random access decodable leading pictures (RADL)*/
5109
0
            else
5110
0
            {
5111
0
                nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5112
0
                               ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RADL_R : NAL_RADL_N)
5113
0
                               : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TSA_R : NAL_TSA_N);
5114
0
            }
5115
0
        }
5116
2.76k
        else
5117
2.76k
        {
5118
2.76k
            if(ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5119
225
            {
5120
225
                nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5121
225
                               ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RASL_R : NAL_RASL_N)
5122
225
                               : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TRAIL_R : NAL_TRAIL_N);
5123
225
            }
5124
            /* IDR case: as the leading pictures can't refer the picture precedes the associated
5125
            IRAP(IDR) in decoding order, hence make it Random access decodable leading pictures (RADL)*/
5126
2.54k
            else
5127
2.54k
            {
5128
2.54k
                nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5129
2.54k
                               ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RADL_R : NAL_RADL_N)
5130
2.54k
                               : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TRAIL_R : NAL_TRAIL_N);
5131
2.54k
            }
5132
2.76k
        }
5133
5134
2.76k
        switch(ps_curr_inp->s_lap_out.i4_pic_type)
5135
2.76k
        {
5136
470
        case IV_IDR_FRAME:
5137
            /*  IDR pic */
5138
470
            slice_type = ISLICE;
5139
470
            nal_type = NAL_IDR_W_LP;
5140
470
            cur_poc = 0;
5141
470
            ps_enc_ctxt->i4_cra_poc = cur_poc;
5142
470
            break;
5143
5144
109
        case IV_I_FRAME:
5145
109
            slice_type = ISLICE;
5146
5147
109
            if(ps_curr_inp->s_lap_out.i4_is_cra_pic)
5148
51
            {
5149
51
                nal_type = NAL_CRA;
5150
51
            }
5151
5152
109
            ps_enc_ctxt->i4_cra_poc = cur_poc;
5153
109
            break;
5154
5155
2.15k
        case IV_P_FRAME:
5156
2.15k
            slice_type = PSLICE;
5157
2.15k
            break;
5158
5159
36
        case IV_B_FRAME:
5160
            /* TODO : Mark the nal type as NAL_TRAIL_N for non ref pics */
5161
36
            slice_type = BSLICE;
5162
36
            break;
5163
5164
0
        default:
5165
            /* This should never occur */
5166
0
            ASSERT(0);
5167
2.76k
        }
5168
5169
        /* number of merge candidates and error metric chosen based on quality preset */
5170
2.76k
        switch(ps_curr_inp->s_lap_out.i4_quality_preset)
5171
2.76k
        {
5172
838
        case IHEVCE_QUALITY_P0:
5173
838
            max_merge_candidates = 5;
5174
838
            break;
5175
5176
233
        case IHEVCE_QUALITY_P2:
5177
233
            max_merge_candidates = 5;
5178
233
            break;
5179
5180
940
        case IHEVCE_QUALITY_P3:
5181
940
            max_merge_candidates = 3;
5182
940
            break;
5183
5184
301
        case IHEVCE_QUALITY_P4:
5185
403
        case IHEVCE_QUALITY_P5:
5186
636
        case IHEVCE_QUALITY_P6:
5187
757
        case IHEVCE_QUALITY_P7:
5188
757
            max_merge_candidates = 2;
5189
757
            break;
5190
5191
0
        default:
5192
0
            ASSERT(0);
5193
2.76k
        }
5194
5195
        /* acquire mutex lock for rate control calls */
5196
2.76k
        osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
5197
2.76k
        {
5198
2.76k
            ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered =
5199
2.76k
                ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
5200
2.76k
                ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd;
5201
5202
            /*initialize the frame info stat inside LAP out, Data inside this will be populated in ihevce_rc_get_bpp_based_frame_qp call*/
5203
2.76k
            ps_curr_inp->s_rc_lap_out.ps_frame_info = &ps_curr_inp->s_frame_info;
5204
5205
2.76k
            ps_curr_inp->s_rc_lap_out.i4_is_bottom_field = ps_curr_inp->s_input_buf.i4_bottom_field;
5206
2.76k
            if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode == 3)
5207
797
            {
5208
                /*for constant qp use same qp*/
5209
                /*HEVC_RC query rate control for qp*/
5210
797
                cur_qp = ihevce_rc_pre_enc_qp_query(
5211
797
                    (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
5212
797
                    &ps_curr_inp->s_rc_lap_out,
5213
797
                    0);
5214
797
            }
5215
1.97k
            else
5216
1.97k
            {
5217
1.97k
                cur_qp = ihevce_rc_get_bpp_based_frame_qp(
5218
1.97k
                    (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0], &ps_curr_inp->s_rc_lap_out);
5219
1.97k
            }
5220
2.76k
        }
5221
        /* release mutex lock after rate control calls */
5222
2.76k
        osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
5223
5224
        /* store the QP in output prms */
5225
        /* The same qp is also used in enc thread only for ME*/
5226
2.76k
        ps_curr_out->i4_curr_frm_qp = cur_qp;
5227
5228
        /* slice header entropy syn memory is not valid in pre encode stage */
5229
2.76k
        ps_curr_out->s_slice_hdr.pu4_entry_point_offset = NULL;
5230
5231
        /* derive the flag which indicates if stasino is enabled */
5232
2.76k
        stasino_enabled = (ps_enc_ctxt->s_runtime_coding_prms.i4_vqet &
5233
2.76k
                           (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION)) &&
5234
0
                          (ps_enc_ctxt->s_runtime_coding_prms.i4_vqet &
5235
0
                           (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER));
5236
5237
        /* initialize the slice header */
5238
2.76k
        ihevce_populate_slice_header(
5239
2.76k
            &ps_curr_out->s_slice_hdr,
5240
2.76k
            &ps_enc_ctxt->as_pps[0],
5241
2.76k
            &ps_enc_ctxt->as_sps[0],
5242
2.76k
            nal_type,
5243
2.76k
            slice_type,
5244
2.76k
            0,
5245
2.76k
            0,
5246
2.76k
            ps_curr_inp->s_lap_out.i4_poc,
5247
2.76k
            cur_qp,
5248
2.76k
            max_merge_candidates,
5249
2.76k
            ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass,
5250
2.76k
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
5251
2.76k
                .i4_quality_preset,
5252
2.76k
            stasino_enabled);
5253
5254
2.76k
        ps_curr_out->i4_slice_nal_type = nal_type;
5255
5256
2.76k
        ps_curr_out->s_slice_hdr.u4_nuh_temporal_id = 0;
5257
5258
2.76k
        if(1 == ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_enable_temporal_scalability)
5259
0
        {
5260
0
            ps_curr_out->s_slice_hdr.u4_nuh_temporal_id =
5261
0
                (ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers ==
5262
0
                 ps_curr_inp->s_lap_out.i4_temporal_lyr_id);  //TEMPORALA_SCALABILITY CHANGES
5263
0
        }
5264
5265
        /* populate sps, vps and pps pointers for the entropy input params */
5266
2.76k
        ps_curr_out->ps_pps = &ps_enc_ctxt->as_pps[0];
5267
2.76k
        ps_curr_out->ps_sps = &ps_enc_ctxt->as_sps[0];
5268
2.76k
        ps_curr_out->ps_vps = &ps_enc_ctxt->as_vps[0];
5269
2.76k
    }
5270
5271
0
#ifndef DISABLE_SEI
5272
    /* By default, Sei messages are set to 0, to avoid unintialised memory access */
5273
0
    memset(&ps_curr_out->s_sei, 0, sizeof(sei_params_t));
5274
5275
    /* VUI, SEI flags reset */
5276
2.76k
    ps_curr_out->s_sei.i1_sei_parameters_present_flag = 0;
5277
2.76k
    ps_curr_out->s_sei.i1_buf_period_params_present_flag = 0;
5278
2.76k
    ps_curr_out->s_sei.i1_pic_timing_params_present_flag = 0;
5279
2.76k
    ps_curr_out->s_sei.i1_recovery_point_params_present_flag = 0;
5280
2.76k
    ps_curr_out->s_sei.i1_decoded_pic_hash_sei_flag = 0;
5281
2.76k
    ps_curr_out->s_sei.i4_sei_mastering_disp_colour_vol_params_present_flags = 0;
5282
5283
2.76k
    if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_enable_flag == 1)
5284
591
    {
5285
        /* insert buffering period, display volume, recovery point only at irap points */
5286
591
        WORD32 insert_per_irap =
5287
591
            ((slice_type == ISLICE) &&
5288
176
             (((NAL_IDR_N_LP == nal_type) || (NAL_CRA == nal_type)) || (NAL_IDR_W_LP == nal_type)));
5289
5290
591
        ps_curr_out->s_sei.i1_sei_parameters_present_flag = 1;
5291
5292
        /* populate Sei buffering period based on encoder configuration and tools */
5293
591
        if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_buffer_period_flags == 1)
5294
0
        {
5295
0
            ihevce_populate_buffering_period_sei(
5296
0
                &ps_curr_out->s_sei,
5297
0
                &ps_enc_ctxt->as_sps[0].s_vui_parameters,
5298
0
                &ps_enc_ctxt->as_sps[0],
5299
0
                &ps_enc_ctxt->ps_stat_prms->s_vui_sei_prms);
5300
5301
0
            ps_curr_out->s_sei.i1_buf_period_params_present_flag = insert_per_irap;
5302
5303
0
            ihevce_populate_active_parameter_set_sei(
5304
0
                &ps_curr_out->s_sei, &ps_enc_ctxt->as_vps[0], &ps_enc_ctxt->as_sps[0]);
5305
0
        }
5306
5307
        /* populate Sei picture timing based on encoder configuration and tools */
5308
591
        if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_pic_timing_flags == 1)
5309
0
        {
5310
0
            ihevce_populate_picture_timing_sei(
5311
0
                &ps_curr_out->s_sei,
5312
0
                &ps_enc_ctxt->as_sps[0].s_vui_parameters,
5313
0
                &ps_enc_ctxt->s_runtime_src_prms,
5314
0
                ps_curr_inp->s_input_buf.i4_bottom_field);
5315
0
            ps_curr_out->s_sei.i1_pic_timing_params_present_flag = 1;
5316
0
        }
5317
5318
        /* populate Sei recovery point based on encoder configuration and tools */
5319
591
        if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_recovery_point_flags == 1)
5320
0
        {
5321
0
            ihevce_populate_recovery_point_sei(
5322
0
                &ps_curr_out->s_sei, &ps_enc_ctxt->ps_stat_prms->s_vui_sei_prms);
5323
0
            ps_curr_out->s_sei.i1_recovery_point_params_present_flag = insert_per_irap;
5324
0
        }
5325
5326
        /* populate mastering_display_colour_volume parameters */
5327
591
        if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_mastering_disp_colour_vol_flags == 1)
5328
0
        {
5329
0
            ihevce_populate_mastering_disp_col_vol_sei(
5330
0
                &ps_curr_out->s_sei, &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms);
5331
5332
0
            ps_curr_out->s_sei.i4_sei_mastering_disp_colour_vol_params_present_flags =
5333
0
                insert_per_irap;
5334
0
        }
5335
5336
        /* populate SEI Hash Flag based on encoder configuration */
5337
591
        if(0 != ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag)
5338
0
        {
5339
            /* Sanity checks */
5340
0
            ASSERT(0 != ps_enc_ctxt->as_sps[0].i1_chroma_format_idc);
5341
5342
0
            ASSERT(
5343
0
                (0 < ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag) &&
5344
0
                (4 > ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag));
5345
5346
            /* MD5 is not supported now! picture_md5[cIdx][i] pblm */
5347
0
            ASSERT(1 != ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag);
5348
5349
0
            ps_curr_out->s_sei.i1_decoded_pic_hash_sei_flag =
5350
0
                ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag;
5351
0
        }
5352
591
    }
5353
2.76k
#endif
5354
5355
    /* For interlace pictures, first_field depends on topfield_first and bottom field */
5356
2.76k
    if(i4_field_pic)
5357
0
    {
5358
0
        first_field =
5359
0
            (ps_curr_inp->s_input_buf.i4_topfield_first ^ ps_curr_inp->s_input_buf.i4_bottom_field);
5360
0
    }
5361
5362
    /* get frame level lambda params */
5363
2.76k
    ihevce_get_frame_lambda_prms(
5364
2.76k
        ps_enc_ctxt,
5365
2.76k
        ps_curr_out,
5366
2.76k
        cur_qp,
5367
2.76k
        first_field,
5368
2.76k
        ps_curr_inp->s_lap_out.i4_is_ref_pic,
5369
2.76k
        ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
5370
2.76k
        lamda_modifier_for_I_pic[4] /*mean TRF*/,
5371
2.76k
        0,
5372
2.76k
        PRE_ENC_LAMBDA_TYPE);
5373
    /* Coarse ME and Decomp buffers sharing */
5374
2.76k
    {
5375
2.76k
        UWORD8 *apu1_lyr_bufs[MAX_NUM_HME_LAYERS];
5376
2.76k
        WORD32 ai4_lyr_buf_strd[MAX_NUM_HME_LAYERS];
5377
5378
        /* get the Decomposition frame buffer from ME */
5379
2.76k
        i4_decomp_lyrs_idx = ihevce_coarse_me_get_lyr_buf_desc(
5380
2.76k
            ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt, &apu1_lyr_bufs[0], &ai4_lyr_buf_strd[0]);
5381
        /* register the buffers with decomp module along with frame init */
5382
2.76k
        ihevce_decomp_pre_intra_frame_init(
5383
2.76k
            ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
5384
2.76k
            &apu1_lyr_bufs[0],
5385
2.76k
            &ai4_lyr_buf_strd[0],
5386
2.76k
            ps_curr_out->ps_layer1_buf,
5387
2.76k
            ps_curr_out->ps_layer2_buf,
5388
2.76k
            ps_curr_out->ps_ed_ctb_l1,
5389
2.76k
            ps_curr_out->as_lambda_prms[0].i4_ol_sad_lambda_qf,
5390
2.76k
            ps_curr_out->ps_ctb_analyse);
5391
2.76k
    }
5392
5393
    /* -------------------------------------------------------- */
5394
    /*   Preparing Pre encode Passes Job Queue                  */
5395
    /* -------------------------------------------------------- */
5396
2.76k
    ihevce_prepare_pre_enc_job_queue(ps_enc_ctxt, ps_curr_inp, i4_ping_pong);
5397
5398
    /*assign return variables */
5399
2.76k
    *pi4_end_flag_ret = end_flag;
5400
2.76k
    *pi4_cur_qp_ret = cur_qp;
5401
2.76k
    *pi4_decomp_lyr_idx = i4_decomp_lyrs_idx;
5402
    //*pps_frm_recon_ret = ps_frm_recon;
5403
2.76k
}
5404
5405
/*!
5406
******************************************************************************
5407
* \if Function name : ihevce_pre_enc_coarse_me_init \endif
5408
*
5409
* \brief
5410
*   set out_buf params
5411
*   Calculate end_flag if flushmode on
5412
*   Slice initialization
5413
*   Populate SIE params
5414
*   reference list creation
5415
*
5416
* \param[in] Encoder context pointer
5417
*
5418
* \return
5419
*    None
5420
*
5421
* \author
5422
*  Ittiam
5423
*
5424
*****************************************************************************
5425
*/
5426
void ihevce_pre_enc_coarse_me_init(
5427
    enc_ctxt_t *ps_enc_ctxt,
5428
    ihevce_lap_enc_buf_t *ps_curr_inp,
5429
    pre_enc_me_ctxt_t *ps_curr_out,
5430
    recon_pic_buf_t **pps_frm_recon_ret,
5431
    WORD32 i4_decomp_lyrs_idx,
5432
    WORD32 i4_cur_qp,
5433
    WORD32 i4_ping_pong)
5434
5435
2.76k
{
5436
    /* local variables */
5437
2.76k
    recon_pic_buf_t *ps_frm_recon;
5438
2.76k
    coarse_me_master_ctxt_t *ps_ctxt = NULL;
5439
2.76k
    ps_ctxt = (coarse_me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt;
5440
    /* Reference buffer management and reference list creation for pre enc group */
5441
2.76k
    ihevce_pre_enc_manage_ref_pics(ps_enc_ctxt, ps_curr_inp, ps_curr_out, i4_ping_pong);
5442
5443
    /* get a free recon buffer for current picture  */
5444
2.76k
    {
5445
2.76k
        WORD32 ctr;
5446
5447
2.76k
        ps_frm_recon = NULL;
5448
7.23k
        for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
5449
7.23k
        {
5450
7.23k
            if(1 == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free)
5451
2.76k
            {
5452
2.76k
                ps_frm_recon = ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr];
5453
2.76k
                break;
5454
2.76k
            }
5455
7.23k
        }
5456
2.76k
    }
5457
    /* should not be NULL */
5458
2.76k
    ASSERT(ps_frm_recon != NULL);
5459
5460
    /* populate reference /recon params based on LAP output */
5461
2.76k
    ps_frm_recon->i4_is_free = 0;
5462
    /* top first field is set to 1 by application */
5463
2.76k
    ps_frm_recon->i4_topfield_first = ps_curr_inp->s_input_buf.i4_topfield_first;
5464
2.76k
    ps_frm_recon->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
5465
2.76k
    ps_frm_recon->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
5466
2.76k
    ps_frm_recon->i4_display_num = ps_curr_inp->s_lap_out.i4_display_num;
5467
    /* bottom field is toggled for every field by application */
5468
2.76k
    ps_frm_recon->i4_bottom_field = ps_curr_inp->s_input_buf.i4_bottom_field;
5469
5470
    /* Reference picture property is given by LAP */
5471
2.76k
    ps_frm_recon->i4_is_reference = ps_curr_inp->s_lap_out.i4_is_ref_pic;
5472
5473
    /* Deblock a picture for all reference frames unconditionally. */
5474
    /* Deblock non ref if psnr compute or save recon is enabled    */
5475
2.76k
    ps_frm_recon->i4_deblk_pad_hpel_cur_pic = ps_frm_recon->i4_is_reference ||
5476
23
                                              (ps_enc_ctxt->ps_stat_prms->i4_save_recon);
5477
5478
    /* set the width, height and stride to defalut values */
5479
2.76k
    ps_frm_recon->s_yuv_buf_desc.i4_y_ht = 0;
5480
2.76k
    ps_frm_recon->s_yuv_buf_desc.i4_uv_ht = 0;
5481
2.76k
    ps_frm_recon->s_yuv_buf_desc.i4_y_wd = 0;
5482
2.76k
    ps_frm_recon->s_yuv_buf_desc.i4_uv_wd = 0;
5483
2.76k
    ps_frm_recon->s_yuv_buf_desc.i4_y_strd = 0;
5484
2.76k
    ps_frm_recon->s_yuv_buf_desc.i4_uv_strd = 0;
5485
5486
    /* register the Layer1 MV bank pointer with ME module */
5487
2.76k
    ihevce_coarse_me_set_lyr1_mv_bank(
5488
2.76k
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
5489
2.76k
        ps_curr_inp,
5490
2.76k
        ps_curr_out->pv_me_mv_bank,
5491
2.76k
        ps_curr_out->pv_me_ref_idx,
5492
2.76k
        i4_decomp_lyrs_idx);
5493
5494
    /* Coarse picture level init of ME */
5495
2.76k
    ihevce_coarse_me_frame_init(
5496
2.76k
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
5497
2.76k
        ps_enc_ctxt->ps_stat_prms,
5498
2.76k
        &ps_enc_ctxt->s_frm_ctb_prms,
5499
2.76k
        &ps_curr_out->as_lambda_prms[0],
5500
2.76k
        ps_enc_ctxt->i4_pre_enc_num_ref_l0,
5501
2.76k
        ps_enc_ctxt->i4_pre_enc_num_ref_l1,
5502
2.76k
        ps_enc_ctxt->i4_pre_enc_num_ref_l0_active,
5503
2.76k
        ps_enc_ctxt->i4_pre_enc_num_ref_l1_active,
5504
2.76k
        &ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong][LIST_0][0],
5505
2.76k
        &ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong][LIST_1][0],
5506
2.76k
        ps_curr_inp,
5507
2.76k
        i4_cur_qp,
5508
2.76k
        ps_curr_out->ps_layer1_buf,
5509
2.76k
        ps_curr_out->ps_ed_ctb_l1,
5510
2.76k
        ps_curr_out->pu1_me_reverse_map_info,
5511
2.76k
        ps_curr_inp->s_lap_out.i4_temporal_lyr_id);
5512
5513
    /*assign return variables */
5514
2.76k
    *pps_frm_recon_ret = ps_frm_recon;
5515
2.76k
}
5516
5517
/*!
5518
******************************************************************************
5519
* \brief
5520
*  Function to calculate modulation based on spatial variance across lap period
5521
*
5522
*****************************************************************************
5523
*/
5524
void ihevce_variance_calc_acc_activity(enc_ctxt_t *ps_enc_ctxt, WORD32 i4_cur_ipe_idx)
5525
2.76k
{
5526
2.76k
    pre_enc_me_ctxt_t *ps_curr_out = ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[i4_cur_ipe_idx];
5527
2.76k
    WORD32 is_curr_bslice = (ps_curr_out->s_slice_hdr.i1_slice_type == BSLICE);
5528
2.76k
#if MODULATION_OVER_LAP
5529
2.76k
    WORD32 loop_lap2 = MAX(1, ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe - 1);
5530
#else
5531
    WORD32 loop_lap2 = 1;
5532
#endif
5533
2.76k
    WORD32 i4_delay_loop = ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe;
5534
2.76k
    WORD32 i, j;
5535
5536
2.76k
    ps_curr_out->i8_acc_frame_8x8_sum_act_sqr = 0;
5537
2.76k
    ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength = 0;
5538
8.30k
    for(i = 0; i < 2; i++)
5539
5.53k
    {
5540
5.53k
        ps_curr_out->i8_acc_frame_8x8_sum_act[i] = 0;
5541
5.53k
        ps_curr_out->i4_acc_frame_8x8_num_blks[i] = 0;
5542
5.53k
        ps_curr_out->i8_acc_frame_16x16_sum_act[i] = 0;
5543
5.53k
        ps_curr_out->i4_acc_frame_16x16_num_blks[i] = 0;
5544
5.53k
        ps_curr_out->i8_acc_frame_32x32_sum_act[i] = 0;
5545
5.53k
        ps_curr_out->i4_acc_frame_32x32_num_blks[i] = 0;
5546
5.53k
    }
5547
2.76k
    ps_curr_out->i8_acc_frame_16x16_sum_act[i] = 0;
5548
2.76k
    ps_curr_out->i4_acc_frame_16x16_num_blks[i] = 0;
5549
2.76k
    ps_curr_out->i8_acc_frame_32x32_sum_act[i] = 0;
5550
2.76k
    ps_curr_out->i4_acc_frame_32x32_num_blks[i] = 0;
5551
5552
2.76k
    if(!is_curr_bslice)
5553
2.73k
    {
5554
2.73k
        for(i = 0; i < loop_lap2; i++)
5555
2.73k
        {
5556
2.73k
            WORD32 ipe_idx_tmp = (i4_cur_ipe_idx + i) % i4_delay_loop;
5557
2.73k
            ihevce_lap_enc_buf_t *ps_in = ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[ipe_idx_tmp];
5558
2.73k
            pre_enc_me_ctxt_t *ps_out = ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[ipe_idx_tmp];
5559
2.73k
            UWORD8 is_bslice = (ps_out->s_slice_hdr.i1_slice_type == BSLICE);
5560
5561
2.73k
            if(!is_bslice)
5562
2.73k
            {
5563
2.73k
                ps_curr_out->i8_acc_frame_8x8_sum_act_sqr += ps_out->u8_curr_frame_8x8_sum_act_sqr;
5564
2.73k
                ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength += ps_out->i4_curr_frame_8x8_sum_act_for_strength[0];
5565
8.19k
                for(j = 0; j < 2; j++)
5566
5.46k
                {
5567
5.46k
                    ps_curr_out->i8_acc_frame_8x8_sum_act[j] += ps_out->i8_curr_frame_8x8_sum_act[j];
5568
5.46k
                    ps_curr_out->i4_acc_frame_8x8_num_blks[j] += ps_out->i4_curr_frame_8x8_num_blks[j];
5569
5.46k
                    ps_curr_out->i8_acc_frame_16x16_sum_act[j] += ps_out->i8_curr_frame_16x16_sum_act[j];
5570
5.46k
                    ps_curr_out->i4_acc_frame_16x16_num_blks[j] += ps_out->i4_curr_frame_16x16_num_blks[j];
5571
5.46k
                    ps_curr_out->i8_acc_frame_32x32_sum_act[j] += ps_out->i8_curr_frame_32x32_sum_act[j];
5572
5.46k
                    ps_curr_out->i4_acc_frame_32x32_num_blks[j] += ps_out->i4_curr_frame_32x32_num_blks[j];
5573
5.46k
                }
5574
2.73k
                ps_curr_out->i8_acc_frame_16x16_sum_act[j] += ps_out->i8_curr_frame_16x16_sum_act[j];
5575
2.73k
                ps_curr_out->i4_acc_frame_16x16_num_blks[j] += ps_out->i4_curr_frame_16x16_num_blks[j];
5576
2.73k
                ps_curr_out->i8_acc_frame_32x32_sum_act[j] += ps_out->i8_curr_frame_32x32_sum_act[j];
5577
2.73k
                ps_curr_out->i4_acc_frame_32x32_num_blks[j] += ps_out->i4_curr_frame_32x32_num_blks[j];
5578
2.73k
            }
5579
2.73k
            if(NULL == ps_in->s_rc_lap_out.ps_rc_lap_out_next_encode)
5580
2.73k
                break;
5581
2.73k
        }
5582
5583
10.9k
        for(j = 0; j < 3; j++)
5584
8.19k
        {
5585
8.19k
            if(j < 2)
5586
8.19k
                ASSERT(0 != ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5587
8.19k
            ASSERT(0 != ps_curr_out->i4_acc_frame_16x16_num_blks[j]);
5588
8.19k
            ASSERT(0 != ps_curr_out->i4_acc_frame_32x32_num_blks[j]);
5589
5590
30.0k
#define AVG_ACTIVITY(a, b, c) a = ((b + (c >> 1)) / c)
5591
5592
8.19k
            if(j < 2)
5593
5.46k
            {
5594
5.46k
                if(0 == ps_curr_out->i4_acc_frame_8x8_num_blks[j])
5595
0
                {
5596
0
                    ps_curr_out->i8_curr_frame_8x8_avg_act[j] = 0;
5597
0
                }
5598
5.46k
                else
5599
5.46k
                {
5600
5.46k
                    AVG_ACTIVITY(ps_curr_out->i8_curr_frame_8x8_sum_act_for_strength,
5601
5.46k
                                 ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength,
5602
5.46k
                                 ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5603
5.46k
                    AVG_ACTIVITY(ps_curr_out->i8_curr_frame_8x8_avg_act[j],
5604
5.46k
                                 ps_curr_out->i8_acc_frame_8x8_sum_act[j],
5605
5.46k
                                 ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5606
5.46k
                    ps_curr_out->ld_curr_frame_8x8_log_avg[j] =
5607
5.46k
                        fast_log2(1 + ps_curr_out->i8_curr_frame_8x8_avg_act[j]);
5608
5.46k
                }
5609
5.46k
            }
5610
5611
8.19k
            if(0 == ps_curr_out->i4_acc_frame_16x16_num_blks[j])
5612
0
            {
5613
0
                ps_curr_out->i8_curr_frame_16x16_avg_act[j] = 0;
5614
0
            }
5615
8.19k
            else
5616
8.19k
            {
5617
8.19k
                AVG_ACTIVITY(ps_curr_out->i8_curr_frame_16x16_avg_act[j],
5618
8.19k
                             ps_curr_out->i8_acc_frame_16x16_sum_act[j],
5619
8.19k
                             ps_curr_out->i4_acc_frame_16x16_num_blks[j]);
5620
8.19k
                ps_curr_out->ld_curr_frame_16x16_log_avg[j] =
5621
8.19k
                    fast_log2(1 + ps_curr_out->i8_curr_frame_16x16_avg_act[j]);
5622
8.19k
            }
5623
5624
8.19k
            if(0 == ps_curr_out->i4_acc_frame_32x32_num_blks[j])
5625
0
            {
5626
0
                ps_curr_out->i8_curr_frame_32x32_avg_act[j] = 0;
5627
0
            }
5628
8.19k
            else
5629
8.19k
            {
5630
8.19k
                AVG_ACTIVITY(ps_curr_out->i8_curr_frame_32x32_avg_act[j],
5631
8.19k
                             ps_curr_out->i8_acc_frame_32x32_sum_act[j],
5632
8.19k
                             ps_curr_out->i4_acc_frame_32x32_num_blks[j]);
5633
8.19k
                ps_curr_out->ld_curr_frame_32x32_log_avg[j] =
5634
8.19k
                    fast_log2(1 + ps_curr_out->i8_curr_frame_32x32_avg_act[j]);
5635
8.19k
            }
5636
8.19k
        }
5637
5638
        /* store the avg activity for B pictures */
5639
2.73k
#if POW_OPT
5640
2.73k
        ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_8x8_log_avg[0];
5641
2.73k
        ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_8x8_log_avg[1];
5642
2.73k
        ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_16x16_log_avg[0];
5643
2.73k
        ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_16x16_log_avg[1];
5644
2.73k
        ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[2] = ps_curr_out->ld_curr_frame_16x16_log_avg[2];
5645
2.73k
        ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_32x32_log_avg[0];
5646
2.73k
        ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_32x32_log_avg[1];
5647
2.73k
        ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[2] = ps_curr_out->ld_curr_frame_32x32_log_avg[2];
5648
#else
5649
        ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[0] = ps_curr_out->i8_curr_frame_8x8_avg_act[0];
5650
        ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[1] = ps_curr_out->i8_curr_frame_8x8_avg_act[1];
5651
        ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[0] = ps_curr_out->i8_curr_frame_16x16_avg_act[0];
5652
        ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[1] = ps_curr_out->i8_curr_frame_16x16_avg_act[1];
5653
        ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[2] = ps_curr_out->i8_curr_frame_16x16_avg_act[2];
5654
        ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[0] = ps_curr_out->i8_curr_frame_32x32_avg_act[0];
5655
        ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[1] = ps_curr_out->i8_curr_frame_32x32_avg_act[1];
5656
        ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[2] = ps_curr_out->i8_curr_frame_32x32_avg_act[2];
5657
#endif
5658
5659
        /* calculate modulation index */
5660
2.73k
        {
5661
2.73k
            LWORD64 i8_mean, i8_mean_sqr, i8_variance;
5662
2.73k
            LWORD64 i8_deviation;
5663
2.73k
            WORD32 i4_mod_factor;
5664
2.73k
            float f_strength;
5665
5666
2.73k
            if(ps_curr_out->i4_acc_frame_8x8_num_blks[0] > 0)
5667
2.73k
            {
5668
#if STRENGTH_BASED_ON_CURR_FRM
5669
                AVG_ACTIVITY(i8_mean_sqr, ps_curr_out->i8_curr_frame_8x8_sum_act_sqr,
5670
                             ps_curr_out->i4_curr_frame_8x8_num_blks[0]);
5671
#else
5672
2.73k
                AVG_ACTIVITY(i8_mean_sqr, ps_curr_out->i8_acc_frame_8x8_sum_act_sqr,
5673
2.73k
                             ps_curr_out->i4_acc_frame_8x8_num_blks[0]);
5674
2.73k
#endif
5675
2.73k
                i8_mean = ps_curr_out->i8_curr_frame_8x8_sum_act_for_strength;
5676
2.73k
                i8_variance = i8_mean_sqr - (i8_mean * i8_mean);
5677
2.73k
                i8_deviation = sqrt(i8_variance);
5678
5679
2.73k
#if STRENGTH_BASED_ON_DEVIATION
5680
2.73k
                if(i8_deviation <= REF_MOD_DEVIATION)
5681
1.48k
                {
5682
1.48k
                    f_strength = ((i8_deviation - BELOW_REF_DEVIATION) * REF_MOD_STRENGTH) / (REF_MOD_DEVIATION - BELOW_REF_DEVIATION);
5683
1.48k
                }
5684
1.24k
                else
5685
1.24k
                {
5686
1.24k
                    f_strength = ((i8_deviation - ABOVE_REF_DEVIATION) * REF_MOD_STRENGTH) / (REF_MOD_DEVIATION - ABOVE_REF_DEVIATION);
5687
1.24k
                }
5688
#else
5689
                f_strength = ((i8_mean_sqr / (float)(i8_mean * i8_mean)) - 1.0) * REF_MOD_STRENGTH / REF_MOD_VARIANCE;
5690
#endif
5691
2.73k
                i4_mod_factor = (WORD32)(i8_deviation / 60);
5692
2.73k
                f_strength = CLIP3(f_strength, 0.0, REF_MAX_STRENGTH);
5693
2.73k
            }
5694
0
            else
5695
0
            {
5696
                /* If not sufficient blocks are present, turn modulation index to 1  */
5697
0
                i4_mod_factor = 1;
5698
0
                f_strength = 0;
5699
0
            }
5700
2.73k
            ps_curr_out->ai4_mod_factor_derived_by_variance[0] = i4_mod_factor;
5701
2.73k
            ps_curr_out->ai4_mod_factor_derived_by_variance[1] = i4_mod_factor;
5702
2.73k
            ps_curr_out->f_strength = f_strength;
5703
5704
2.73k
            ps_enc_ctxt->ai4_mod_factor_derived_by_variance[0] = i4_mod_factor;
5705
2.73k
            ps_enc_ctxt->ai4_mod_factor_derived_by_variance[1] = i4_mod_factor;
5706
2.73k
            ps_enc_ctxt->f_strength = f_strength;
5707
2.73k
        }
5708
2.73k
    }
5709
36
    else
5710
36
    {
5711
36
        ps_curr_out->ai4_mod_factor_derived_by_variance[0] = ps_enc_ctxt->ai4_mod_factor_derived_by_variance[0];
5712
36
        ps_curr_out->ai4_mod_factor_derived_by_variance[1] = ps_enc_ctxt->ai4_mod_factor_derived_by_variance[1];
5713
36
        ps_curr_out->f_strength = ps_enc_ctxt->f_strength;
5714
5715
        /* copy the prev avg activity from Tid 0 for B pictures*/
5716
36
#if POW_OPT
5717
36
        ps_curr_out->ld_curr_frame_8x8_log_avg[0] = ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[0];
5718
36
        ps_curr_out->ld_curr_frame_8x8_log_avg[1] = ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[1];
5719
36
        ps_curr_out->ld_curr_frame_16x16_log_avg[0] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[0];
5720
36
        ps_curr_out->ld_curr_frame_16x16_log_avg[1] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[1];
5721
36
        ps_curr_out->ld_curr_frame_16x16_log_avg[2] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[2];
5722
36
        ps_curr_out->ld_curr_frame_32x32_log_avg[0] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[0];
5723
36
        ps_curr_out->ld_curr_frame_32x32_log_avg[1] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[1];
5724
36
        ps_curr_out->ld_curr_frame_32x32_log_avg[2] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[2];
5725
#else
5726
        ps_curr_out->i8_curr_frame_8x8_avg_act[0] = ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[0];
5727
        ps_curr_out->i8_curr_frame_8x8_avg_act[1] = ps_enc_ctxt->ai8_lap2_8x8_avg_act_from_T0[1];
5728
        ps_curr_out->i8_curr_frame_16x16_avg_act[0] = ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[0];
5729
        ps_curr_out->i8_curr_frame_16x16_avg_act[1] = ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[1];
5730
        ps_curr_out->i8_curr_frame_16x16_avg_act[2] = ps_enc_ctxt->ai8_lap2_16x16_avg_act_from_T0[2];
5731
        ps_curr_out->i8_curr_frame_32x32_avg_act[0] = ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[0];
5732
        ps_curr_out->i8_curr_frame_32x32_avg_act[1] = ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[1];
5733
        ps_curr_out->i8_curr_frame_32x32_avg_act[2] = ps_enc_ctxt->ai8_lap2_32x32_avg_act_from_T0[2];
5734
#endif
5735
36
    }
5736
2.76k
#undef AVG_ACTIVITY
5737
2.76k
}
5738
5739
/*!
5740
******************************************************************************
5741
* \if Function name : ihevce_pre_enc_process_frame_thrd \endif
5742
*
5743
* \brief
5744
*    Pre-Encode Frame processing thread interface function
5745
*
5746
* \param[in] High level encoder context pointer
5747
*
5748
* \return
5749
*    None
5750
*
5751
* \author
5752
*  Ittiam
5753
*
5754
*****************************************************************************
5755
*/
5756
WORD32 ihevce_pre_enc_process_frame_thrd(void *pv_frm_proc_thrd_ctxt)
5757
218
{
5758
218
    frm_proc_thrd_ctxt_t *ps_thrd_ctxt = (frm_proc_thrd_ctxt_t *)pv_frm_proc_thrd_ctxt;
5759
218
    ihevce_hle_ctxt_t *ps_hle_ctxt = ps_thrd_ctxt->ps_hle_ctxt;
5760
218
    enc_ctxt_t *ps_enc_ctxt = (enc_ctxt_t *)ps_thrd_ctxt->pv_enc_ctxt;
5761
218
    multi_thrd_ctxt_t *ps_multi_thrd = &ps_enc_ctxt->s_multi_thrd;
5762
218
    WORD32 i4_thrd_id = ps_thrd_ctxt->i4_thrd_id;
5763
218
    WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
5764
218
    WORD32 i4_end_flag = 0;
5765
218
    WORD32 i4_out_flush_flag = 0;
5766
218
    WORD32 i4_cur_decomp_idx = 0;
5767
218
    WORD32 i4_cur_coarse_me_idx = 0;
5768
218
    WORD32 i4_cur_ipe_idx = 0;
5769
218
    ihevce_lap_enc_buf_t *ps_lap_inp_buf = NULL;
5770
218
    void *pv_dep_mngr_prev_frame_pre_enc_l1 = ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_l1;
5771
218
    void *pv_dep_mngr_prev_frame_pre_enc_l0 = ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_l0;
5772
218
    void *pv_dep_mngr_prev_frame_pre_enc_coarse_me =
5773
218
        ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_coarse_me;
5774
218
    WORD32 i4_num_buf_prod_for_l0_ipe = 0;
5775
218
    WORD32 i4_decomp_end_flag = 0;
5776
5777
218
    (void)ps_hle_ctxt;
5778
218
    (void)i4_resolution_id;
5779
5780
    /* ---------- Processing Loop until Flush command is received --------- */
5781
3.20k
    while(0 == i4_end_flag)
5782
2.98k
    {
5783
        /* Wait till previous frame(instance)'s decomp_intra is processed */
5784
2.98k
        {
5785
2.98k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l1, i4_thrd_id);
5786
2.98k
        }
5787
5788
        /* ----------------------------------------------------------- */
5789
        /*     decomp pre_intra init                                   */
5790
        /* ----------------------------------------------------------- */
5791
5792
        /****** Lock the critical section for decomp pre_intra init ******/
5793
2.98k
        {
5794
2.98k
            WORD32 i4_status;
5795
5796
2.98k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_init);
5797
2.98k
            if(OSAL_SUCCESS != i4_status)
5798
0
                return 0;
5799
2.98k
        }
5800
5801
2.98k
        ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_decomp_idx] = 0;
5802
5803
        /* init */
5804
2.98k
        if((ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] == 0) &&
5805
2.98k
           (0 == i4_decomp_end_flag))
5806
2.98k
        {
5807
2.98k
            ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
5808
2.98k
            pre_enc_me_ctxt_t *ps_curr_out = NULL;
5809
2.98k
            WORD32 in_buf_id;
5810
2.98k
            WORD32 out_buf_id;
5811
5812
2.98k
            do
5813
3.14k
            {
5814
3.14k
                ps_lap_inp_buf = NULL;
5815
3.14k
                if(0 == ps_multi_thrd->i4_last_inp_buf)
5816
2.98k
                {
5817
                    /* ------- get input buffer input data que ---------- */
5818
2.98k
                    ps_lap_inp_buf = (ihevce_lap_enc_buf_t *)ihevce_q_get_filled_buff(
5819
2.98k
                        (void *)ps_enc_ctxt,
5820
2.98k
                        IHEVCE_INPUT_DATA_CTRL_Q,
5821
2.98k
                        &in_buf_id,
5822
2.98k
                        BUFF_QUE_BLOCKING_MODE);
5823
2.98k
                    ps_multi_thrd->i4_last_inp_buf = ihevce_check_last_inp_buf(
5824
2.98k
                        (WORD32 *)ps_lap_inp_buf->s_input_buf.pv_synch_ctrl_bufs);
5825
2.98k
                }
5826
5827
3.14k
                ps_curr_inp =
5828
3.14k
                    ihevce_lap_process(ps_enc_ctxt->pv_lap_interface_ctxt, ps_lap_inp_buf);
5829
5830
3.14k
            } while(NULL == ps_curr_inp);
5831
5832
            /* set the flag saying init is done so that other cores dont do it */
5833
2.98k
            ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] = 1;
5834
5835
2.98k
            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_decomp_idx] = ps_curr_inp;
5836
2.98k
            ps_multi_thrd->ai4_in_buf_id_pre_enc[i4_cur_decomp_idx] =
5837
2.98k
                ps_curr_inp->s_input_buf.i4_buf_id;
5838
5839
            /* ------- get free output buffer from pre-enc/enc buffer que ---------- */
5840
2.98k
            ps_curr_out = (pre_enc_me_ctxt_t *)ihevce_q_get_free_buff(
5841
2.98k
                (void *)ps_enc_ctxt, IHEVCE_PRE_ENC_ME_Q, &out_buf_id, BUFF_QUE_BLOCKING_MODE);
5842
2.98k
            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_decomp_idx] = ps_curr_out;
5843
2.98k
            ps_multi_thrd->ai4_out_buf_id_pre_enc[i4_cur_decomp_idx] = out_buf_id;
5844
5845
2.98k
            if((NULL != ps_curr_inp) && (NULL != ps_curr_out))
5846
2.98k
            {
5847
                /* by default last picture to be encoded flag is set to 0      */
5848
                /* this flag will be used by slave threads to exit at the end */
5849
2.98k
                ps_multi_thrd->i4_last_pic_flag = 0;
5850
5851
                /* store the buffer id */
5852
2.98k
                ps_curr_out->i4_buf_id = out_buf_id;
5853
5854
2.98k
                ps_curr_out->i8_acc_num_blks_high_sad = 0;
5855
2.98k
                ps_curr_out->i8_total_blks = 0;
5856
2.98k
                ps_curr_out->i4_is_high_complex_region = -1;
5857
5858
                /* set the parameters for sync b/w pre-encode and encode threads */
5859
2.98k
                ps_curr_out->i4_end_flag = ps_curr_inp->s_lap_out.i4_end_flag;
5860
2.98k
                ps_curr_out->i4_frm_proc_valid_flag = 1;
5861
2.98k
                if(ps_curr_out->i4_end_flag)
5862
218
                {
5863
218
                    ps_curr_out->i4_frm_proc_valid_flag =
5864
218
                        ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag;
5865
218
                    ps_multi_thrd->i4_last_pic_flag = 1;
5866
218
                    ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = 1;
5867
218
                }
5868
2.98k
                if(ps_curr_inp->s_lap_out.i4_out_flush_flag)
5869
0
                {
5870
0
                    ps_curr_out->i4_frm_proc_valid_flag =
5871
0
                        ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag;
5872
0
                }
5873
5874
                /* do the init processing if input frm data is valid */
5875
2.98k
                if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
5876
2.76k
                {
5877
2.76k
                    WORD32 end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx];
5878
2.76k
                    WORD32 cur_qp = 0, count;
5879
5880
2.76k
                    ihevce_pre_enc_init(
5881
2.76k
                        ps_enc_ctxt,
5882
2.76k
                        ps_curr_inp,
5883
2.76k
                        ps_curr_out,
5884
2.76k
                        &end_flag,
5885
2.76k
                        &cur_qp,
5886
2.76k
                        &ps_multi_thrd->ai4_decomp_lyr_buf_idx[i4_cur_decomp_idx],
5887
2.76k
                        i4_cur_decomp_idx);
5888
5889
2.76k
                    ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = end_flag;
5890
2.76k
                    ps_multi_thrd->ai4_cur_frame_qp_pre_enc[i4_cur_decomp_idx] = cur_qp;
5891
5892
190k
                    for(count = 0; count < ((HEVCE_MAX_HEIGHT >> 1) / 8); count++)
5893
188k
                    {
5894
188k
                        ps_multi_thrd->aai4_l1_pre_intra_done[i4_cur_decomp_idx][count] = 0;
5895
188k
                    }
5896
2.76k
                }
5897
2.98k
            }
5898
2.98k
        }
5899
0
        else if(1 == i4_decomp_end_flag)
5900
0
        {
5901
            /* Once end is reached all subsequent flags are set to 1 to indicate end */
5902
0
            ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = 1;
5903
0
        }
5904
5905
        /****** UnLock the critical section after decomp pre_intra init ******/
5906
2.98k
        {
5907
2.98k
            WORD32 i4_status;
5908
2.98k
            i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_init);
5909
5910
2.98k
            if(OSAL_SUCCESS != i4_status)
5911
0
                return 0;
5912
2.98k
        }
5913
2.98k
        if(i4_thrd_id == 0)
5914
2.98k
        {
5915
2.98k
            PROFILE_START(&ps_hle_ctxt->profile_pre_enc_l1l2[i4_resolution_id]);
5916
2.98k
        }
5917
        /* ------------------------------------------------------------ */
5918
        /*        Layer Decomp and Pre Intra Analysis                   */
5919
        /* ------------------------------------------------------------ */
5920
2.98k
        if(0 == i4_decomp_end_flag)
5921
2.98k
        {
5922
2.98k
            pre_enc_me_ctxt_t *ps_curr_out = ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_decomp_idx];
5923
5924
2.98k
            if(1 == ps_curr_out->i4_frm_proc_valid_flag)
5925
2.76k
            {
5926
2.76k
                ihevce_decomp_pre_intra_process(
5927
2.76k
                    ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
5928
2.76k
                    &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_decomp_idx]->s_lap_out,
5929
2.76k
                    &ps_enc_ctxt->s_frm_ctb_prms,
5930
2.76k
                    ps_multi_thrd,
5931
2.76k
                    i4_thrd_id,
5932
2.76k
                    i4_cur_decomp_idx);
5933
2.76k
            }
5934
2.98k
        }
5935
5936
        /* ------------------------------------------------------------ */
5937
        /*        Layer Decomp and Pre Intra Deinit                     */
5938
        /* ------------------------------------------------------------ */
5939
5940
        /****** Lock the critical section for decomp deinit ******/
5941
2.98k
        {
5942
2.98k
            WORD32 i4_status;
5943
2.98k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_decomp_deinit);
5944
5945
2.98k
            if(OSAL_SUCCESS != i4_status)
5946
0
                return 0;
5947
2.98k
        }
5948
5949
2.98k
        ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx]++;
5950
2.98k
        i4_decomp_end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx];
5951
5952
        /* check for last thread condition */
5953
2.98k
        if(ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx] ==
5954
2.98k
           ps_multi_thrd->i4_num_pre_enc_proc_thrds)
5955
2.98k
        {
5956
2.98k
            ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx] = 0;
5957
5958
            /* reset the init flag so that init happens by the first thread for the next frame
5959
               of same ping_pong instance */
5960
2.98k
            ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] = 0;
5961
5962
            /* update the pre enc l1 done in dep manager */
5963
2.98k
            ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l1);
5964
2.98k
        }
5965
5966
        /* index increment */
5967
2.98k
        i4_cur_decomp_idx = i4_cur_decomp_idx + 1;
5968
5969
        /* wrap around case */
5970
2.98k
        if(i4_cur_decomp_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
5971
1.44k
        {
5972
1.44k
            i4_cur_decomp_idx = 0;
5973
1.44k
        }
5974
5975
        /****** UnLock the critical section after decomp pre_intra deinit ******/
5976
2.98k
        {
5977
2.98k
            WORD32 i4_status;
5978
2.98k
            i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_decomp_deinit);
5979
5980
2.98k
            if(OSAL_SUCCESS != i4_status)
5981
0
                return 0;
5982
2.98k
        }
5983
5984
        /* ------------------------------------------------------------ */
5985
        /*                     HME Init                                 */
5986
        /* ------------------------------------------------------------ */
5987
5988
        /* Wait till previous frame(instance)'s coarse_me is processed */
5989
2.98k
        {
5990
2.98k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me, i4_thrd_id);
5991
2.98k
        }
5992
5993
        /****** Lock the critical section for hme init ******/
5994
2.98k
        {
5995
2.98k
            WORD32 i4_status;
5996
5997
2.98k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_init);
5998
2.98k
            if(OSAL_SUCCESS != i4_status)
5999
0
                return 0;
6000
2.98k
        }
6001
6002
2.98k
        if(0 == ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx])
6003
2.98k
        {
6004
            /* do the init processing if input frm data is valid */
6005
2.98k
            if(1 ==
6006
2.98k
               ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6007
2.76k
            {
6008
2.76k
                recon_pic_buf_t *ps_frm_recon = NULL;
6009
6010
                /* DPB management for coarse me + HME init */
6011
2.76k
                ihevce_pre_enc_coarse_me_init(
6012
2.76k
                    ps_enc_ctxt,
6013
2.76k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6014
2.76k
                    ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6015
2.76k
                    &ps_frm_recon,
6016
2.76k
                    ps_multi_thrd->ai4_decomp_lyr_buf_idx[i4_cur_coarse_me_idx],
6017
2.76k
                    ps_multi_thrd->ai4_cur_frame_qp_pre_enc[i4_cur_coarse_me_idx],
6018
2.76k
                    i4_cur_coarse_me_idx);
6019
2.76k
            }
6020
6021
2.98k
            ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx] = 1;
6022
2.98k
        }
6023
6024
        /****** Unlock the critical section for hme init ******/
6025
2.98k
        {
6026
2.98k
            WORD32 i4_status;
6027
6028
2.98k
            i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_init);
6029
2.98k
            if(OSAL_SUCCESS != i4_status)
6030
0
                return 0;
6031
2.98k
        }
6032
6033
        /* ------------------------------------------------------------ */
6034
        /*  Coarse Motion estimation and early intra-inter decision     */
6035
        /* ------------------------------------------------------------ */
6036
2.98k
        if(1 == ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6037
2.76k
        {
6038
2.76k
            ihevce_coarse_me_process(
6039
2.76k
                ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
6040
2.76k
                ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6041
2.76k
                &ps_enc_ctxt->s_multi_thrd,
6042
2.76k
                i4_thrd_id,
6043
2.76k
                i4_cur_coarse_me_idx);
6044
2.76k
        }
6045
6046
        /* update the end flag */
6047
2.98k
        i4_end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_coarse_me_idx];
6048
2.98k
        i4_out_flush_flag =
6049
2.98k
            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx]->s_lap_out.i4_out_flush_flag;
6050
6051
        /****** Lock the critical section for hme deinit ******/
6052
2.98k
        {
6053
2.98k
            WORD32 i4_status;
6054
2.98k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_deinit);
6055
6056
2.98k
            if(OSAL_SUCCESS != i4_status)
6057
0
                return 0;
6058
2.98k
        }
6059
6060
        /* last thread finishing pre_enc_process will update the flag indicating
6061
        decomp and coarse ME is done. So that the next frame (next ping_pong instance)
6062
        can start immediately after finishing current frame's IPE */
6063
2.98k
        if(1 == ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6064
2.76k
        {
6065
2.76k
            ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx]++;
6066
6067
            /* ------------------------------------------------------------ */
6068
            /*  Update qp used in based in L1 satd/act in case of scene cut */
6069
            /* ------------------------------------------------------------ */
6070
2.76k
            {
6071
2.76k
                ihevce_lap_enc_buf_t *ps_curr_inp =
6072
2.76k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx];
6073
6074
2.76k
                if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
6075
2.76k
                {
6076
2.76k
                    WORD32 i4_prev_coarse_me_idx;
6077
6078
                    /* wrap around case */
6079
2.76k
                    if(i4_cur_coarse_me_idx == 0)
6080
1.44k
                    {
6081
1.44k
                        i4_prev_coarse_me_idx = ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe - 1;
6082
1.44k
                    }
6083
1.32k
                    else
6084
1.32k
                    {
6085
1.32k
                        i4_prev_coarse_me_idx = i4_cur_coarse_me_idx - 1;
6086
1.32k
                    }
6087
6088
2.76k
                    ihevce_update_qp_L1_sad_based(
6089
2.76k
                        ps_enc_ctxt,
6090
2.76k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6091
2.76k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_prev_coarse_me_idx],
6092
2.76k
                        ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6093
2.76k
                        ((ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6094
2.76k
                          ps_multi_thrd->i4_num_pre_enc_proc_thrds)));
6095
2.76k
                }
6096
2.76k
            }
6097
            /* check for last thread condition */
6098
2.76k
            if(ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6099
2.76k
               ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6100
2.76k
            {
6101
2.76k
                ihevce_lap_enc_buf_t *ps_curr_inp =
6102
2.76k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx];
6103
6104
                /*        Frame END processing                  */
6105
2.76k
                ihevce_coarse_me_frame_end(ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt);
6106
6107
2.76k
                if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
6108
2.76k
                {
6109
2.76k
                    WORD32 i4_enable_noise_detection = 0;
6110
2.76k
                    WORD32 i4_vqet = ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet;
6111
6112
2.76k
                    if(i4_vqet & (1 << BITPOS_IN_VQ_TOGGLE_FOR_CONTROL_TOGGLER))
6113
0
                    {
6114
0
                        if(i4_vqet & (1 << BITPOS_IN_VQ_TOGGLE_FOR_ENABLING_NOISE_PRESERVATION))
6115
0
                        {
6116
0
                            i4_enable_noise_detection = 1;
6117
0
                        }
6118
0
                    }
6119
6120
2.76k
                    if(1 != ((ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME) &&
6121
36
                             (ps_enc_ctxt->s_lap_stat_prms.ai4_quality_preset[i4_resolution_id] ==
6122
36
                              IHEVCE_QUALITY_P6)))
6123
2.76k
                    {
6124
2.76k
                        ihevce_decomp_pre_intra_curr_frame_pre_intra_deinit(
6125
2.76k
                            ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
6126
2.76k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6127
2.76k
                            &ps_enc_ctxt->s_frm_ctb_prms);
6128
2.76k
                    }
6129
2.76k
                }
6130
6131
2.76k
                ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6132
6133
2.76k
                ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] = 0;
6134
6135
                /* get the layer 1 ctxt to be passed on to encode group */
6136
2.76k
                ihevce_coarse_me_get_lyr1_ctxt(
6137
2.76k
                    ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
6138
2.76k
                    ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->pv_me_lyr_ctxt,
6139
2.76k
                    ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->pv_me_lyr_bnk_ctxt);
6140
6141
                /* reset the init flag so that init happens by the first thread for the next frame
6142
                    of same ping_pong instance */
6143
2.76k
                ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx] = 0;
6144
6145
                /* update the pre enc l1 done in dep manager */
6146
2.76k
                ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me);
6147
2.76k
            }
6148
6149
2.76k
            i4_num_buf_prod_for_l0_ipe++;
6150
6151
            /* index increment */
6152
2.76k
            i4_cur_coarse_me_idx = i4_cur_coarse_me_idx + 1;
6153
6154
            /* wrap around case */
6155
2.76k
            if(i4_cur_coarse_me_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6156
1.32k
            {
6157
1.32k
                i4_cur_coarse_me_idx = 0;
6158
1.32k
            }
6159
2.76k
        }
6160
218
        else
6161
218
        {
6162
            /* for invalid frame set the processed flag to 1 for L0 IPE */
6163
218
            ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6164
6165
218
            if(1 == i4_out_flush_flag)
6166
0
            {
6167
                /* update the num thrds who have finished pre-enc processing */
6168
0
                ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx]++;
6169
6170
0
                if(ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6171
0
                   ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6172
0
                {
6173
0
                    ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6174
6175
                    /* reset num thread finished counter */
6176
0
                    ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] = 0;
6177
6178
0
                    ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx] = 0;
6179
6180
                    /* update flag indicating coarse_me and decomp is done */
6181
0
                    ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me);
6182
0
                }
6183
0
            }
6184
6185
218
            i4_num_buf_prod_for_l0_ipe++;
6186
6187
            /* index increment */
6188
218
            i4_cur_coarse_me_idx = i4_cur_coarse_me_idx + 1;
6189
6190
            /* wrap around case */
6191
218
            if(i4_cur_coarse_me_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6192
120
            {
6193
120
                i4_cur_coarse_me_idx = 0;
6194
120
            }
6195
218
        }
6196
6197
        /****** UnLock the critical section after hme deinit ******/
6198
2.98k
        {
6199
2.98k
            WORD32 i4_status;
6200
2.98k
            i4_status =
6201
2.98k
                osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit);
6202
6203
2.98k
            if(OSAL_SUCCESS != i4_status)
6204
0
                return 0;
6205
2.98k
        }
6206
6207
2.98k
        if(i4_thrd_id == 0)
6208
2.98k
        {
6209
2.98k
            PROFILE_STOP(&ps_hle_ctxt->profile_pre_enc_l1l2[i4_resolution_id], NULL);
6210
2.98k
        }
6211
6212
        /* ----------------------------------------------------------- */
6213
        /*     IPE init and process                                    */
6214
        /* ----------------------------------------------------------- */
6215
2.98k
        if(i4_thrd_id == 0)
6216
2.98k
        {
6217
2.98k
            PROFILE_START(&ps_hle_ctxt->profile_pre_enc_l0ipe[i4_resolution_id]);
6218
2.98k
        }
6219
2.98k
        if(i4_num_buf_prod_for_l0_ipe >= ps_multi_thrd->i4_delay_pre_me_btw_l0_ipe || i4_end_flag ||
6220
0
           i4_out_flush_flag)
6221
2.98k
        {
6222
2.98k
            do
6223
2.98k
            {
6224
                /* Wait till previous frame(instance)'s IPE is processed */
6225
2.98k
                {
6226
2.98k
                    ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l0, i4_thrd_id);
6227
2.98k
                }
6228
6229
                /* Wait till current frame(instance)'s L1 and below layers are processed */
6230
2.98k
                {
6231
2.98k
                    volatile WORD32 *pi4_cur_l1_complete =
6232
2.98k
                        &ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_ipe_idx];
6233
6234
2.98k
                    while(1)
6235
2.98k
                    {
6236
2.98k
                        if(*pi4_cur_l1_complete)
6237
2.98k
                            break;
6238
2.98k
                    }
6239
2.98k
                }
6240
6241
                /* ----------------------------------------------------------- */
6242
                /*     L0 IPE qp init                                          */
6243
                /* ----------------------------------------------------------- */
6244
6245
                /****** Lock the critical section for init ******/
6246
2.98k
                {
6247
2.98k
                    WORD32 i4_status;
6248
2.98k
                    i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_l0_ipe_init);
6249
6250
2.98k
                    if(OSAL_SUCCESS != i4_status)
6251
0
                        return 0;
6252
2.98k
                }
6253
6254
                /* first thread that enters will calculate qp and write that to shared variable
6255
                   that will be accessed by other threads */
6256
2.98k
                if(ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] == 0)
6257
2.98k
                {
6258
2.98k
                    volatile WORD32 i4_is_qp_valid = -1;
6259
2.98k
                    WORD32 i4_update_qp;
6260
2.98k
                    WORD32 i4_cur_q_scale;
6261
6262
2.98k
                    i4_cur_q_scale =
6263
2.98k
                        ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp;
6264
2.98k
                    i4_cur_q_scale = ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale[i4_cur_q_scale];
6265
2.98k
                    i4_cur_q_scale = (i4_cur_q_scale + (1 << (QSCALE_Q_FAC_3 - 1))) >>
6266
2.98k
                                     QSCALE_Q_FAC_3;
6267
                    /* Get free buffer to store L0 IPE output to enc loop */
6268
2.98k
                    ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc =
6269
2.98k
                        (pre_enc_L0_ipe_encloop_ctxt_t *)ihevce_q_get_free_buff(
6270
2.98k
                            (void *)ps_enc_ctxt,
6271
2.98k
                            IHEVCE_L0_IPE_ENC_Q,
6272
2.98k
                            &ps_multi_thrd->i4_L0_IPE_out_buf_id,
6273
2.98k
                            BUFF_QUE_BLOCKING_MODE);
6274
2.98k
                    if(ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass != 2 &&
6275
2.98k
                       ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
6276
2.14k
                    {
6277
2.14k
                        complexity_RC_reset_marking(
6278
2.14k
                            ps_enc_ctxt, i4_cur_ipe_idx, (i4_end_flag || i4_out_flush_flag));
6279
2.14k
                    }
6280
2.98k
                    if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6281
2.98k
                                ->s_input_buf.i4_inp_frm_data_valid_flag)
6282
2.76k
                    {
6283
5.53k
                        while(i4_is_qp_valid == -1)
6284
2.76k
                        {
6285
                            /*this rate control call is outside mutex lock to avoid deadlock. If this acquires mutex lock enc will not be able to
6286
                            populate qp*/
6287
2.76k
                            i4_is_qp_valid = ihevce_rc_check_is_pre_enc_qp_valid(
6288
2.76k
                                (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6289
2.76k
                                (volatile WORD32 *)&ps_enc_ctxt->s_multi_thrd.i4_force_end_flag);
6290
2.76k
                            if(1 == ps_enc_ctxt->s_multi_thrd.i4_force_end_flag)
6291
0
                            {
6292
                                /*** For force end condition break from this loop ***/
6293
0
                                i4_is_qp_valid = 1;
6294
0
                                break;
6295
0
                            }
6296
2.76k
                        }
6297
6298
                        /*lock rate control context*/
6299
2.76k
                        osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
6300
6301
                        /* Qp query has to happen irrespective of using it or not since producer consumer logic will be disturbed */
6302
2.76k
                        i4_update_qp = ihevce_rc_pre_enc_qp_query(
6303
2.76k
                            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6304
2.76k
                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out,
6305
2.76k
                            0);
6306
6307
2.76k
                        if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
6308
1.97k
                        {
6309
1.97k
                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6310
1.97k
                                ->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1 =
6311
1.97k
                                ihevce_get_L0_satd_based_on_L1(
6312
1.97k
                                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6313
1.97k
                                        ->s_rc_lap_out.i8_frame_satd_by_act_L1_accum,
6314
1.97k
                                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6315
1.97k
                                        ->s_rc_lap_out.i4_num_pels_in_frame_considered,
6316
1.97k
                                    i4_cur_q_scale);
6317
6318
1.97k
                            if(ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass != 2)
6319
1.97k
                            {
6320
1.97k
                                if(ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6321
1.97k
                                           ->s_rc_lap_out.i4_rc_scene_type ==
6322
1.97k
                                       SCENE_TYPE_SCENE_CUT ||
6323
1.97k
                                   ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6324
1.97k
                                       ->s_rc_lap_out.i4_is_I_only_scd ||
6325
1.89k
                                   ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6326
1.89k
                                           ->s_rc_lap_out.i4_is_non_I_scd == 1)
6327
171
                                {
6328
171
                                    float i_to_avg_rest_ratio;
6329
171
                                    WORD32 i4_count = 0;
6330
6331
342
                                    while(1)
6332
342
                                    {
6333
342
                                        i_to_avg_rest_ratio = ihevce_get_i_to_avg_ratio(
6334
342
                                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6335
342
                                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6336
342
                                                 ->s_rc_lap_out,
6337
342
                                            1,
6338
342
                                            0,
6339
342
                                            0,
6340
342
                                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6341
342
                                                ->s_rc_lap_out.ai4_offsets,
6342
342
                                            0);
6343
                                        /* HEVC_RC query rate control for qp */
6344
342
                                        i4_update_qp = ihevce_get_L0_est_satd_based_scd_qp(
6345
342
                                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6346
342
                                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6347
342
                                                 ->s_rc_lap_out,
6348
342
                                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6349
342
                                                ->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1,
6350
342
                                            i_to_avg_rest_ratio);
6351
6352
342
                                        ihevce_set_L0_scd_qp(
6353
342
                                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6354
342
                                            i4_update_qp);
6355
6356
342
                                        if(ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6357
342
                                                   ->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
6358
240
                                           ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6359
240
                                                   ->s_lap_out.i4_pic_type != IV_I_FRAME)
6360
196
                                        {
6361
196
                                            i4_update_qp +=
6362
196
                                                ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6363
196
                                                    ->s_lap_out.i4_temporal_lyr_id +
6364
196
                                                1;
6365
6366
196
                                            i4_update_qp =
6367
196
                                                CLIP3(i4_update_qp, MIN_HEVC_QP, MAX_HEVC_QP);
6368
196
                                        }
6369
6370
342
                                        i4_count++;
6371
342
                                        if((i4_update_qp ==
6372
342
                                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6373
342
                                                ->s_rc_lap_out.i4_L0_qp) ||
6374
171
                                           i4_count > 4)
6375
171
                                            break;
6376
6377
171
                                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6378
171
                                            ->s_rc_lap_out.i4_L0_qp = i4_update_qp;
6379
171
                                    }
6380
171
                                }
6381
1.97k
                            }
6382
0
                            else
6383
0
                            {
6384
                                //i4_update_qp = ihevce_get_first_pass_qp(ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_lap_out.pv_frame_info);
6385
0
                                i4_update_qp = ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6386
0
                                                   ->s_rc_lap_out.ps_frame_info->i4_rc_hevc_qp;
6387
0
                            }
6388
1.97k
                        }
6389
6390
2.76k
                        {
6391
2.76k
                            WORD32 i4_index = 0;
6392
2.76k
                            rc_lap_out_params_t *ps_rc_lap_temp =
6393
2.76k
                                &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out;
6394
2.76k
                            WORD32 i4_offset;
6395
6396
2.76k
                            if(ps_rc_lap_temp->i4_rc_pic_type != IV_IDR_FRAME &&
6397
2.29k
                               ps_rc_lap_temp->i4_rc_pic_type != IV_I_FRAME)
6398
2.18k
                            {
6399
2.18k
                                i4_index = ps_rc_lap_temp->i4_rc_temporal_lyr_id + 1;
6400
2.18k
                            }
6401
2.76k
                            i4_offset = ps_rc_lap_temp->ai4_offsets[i4_index];
6402
2.76k
                            ASSERT(i4_offset >= 0);
6403
                            /* Map the current frame Qp to L0 Qp */
6404
2.76k
                            ps_rc_lap_temp->i4_L0_qp = i4_update_qp - i4_offset;
6405
2.76k
                        }
6406
2.76k
                        osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
6407
2.76k
                        ASSERT(ps_multi_thrd->i4_qp_update_l0_ipe == -1);
6408
2.76k
                        ps_multi_thrd->i4_qp_update_l0_ipe = i4_update_qp;
6409
2.76k
                        ps_multi_thrd->i4_rc_l0_qp = i4_update_qp;
6410
2.76k
                    }
6411
2.98k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6412
2.98k
                        ->s_lap_out.f_i_pic_lamda_modifier = CONST_LAMDA_MOD_VAL;
6413
2.98k
                }
6414
                /* update qp only if it is not scene cut since it has already been
6415
                   populated in L1 for scene cut frames */
6416
2.98k
                if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6417
2.98k
                            ->s_input_buf.i4_inp_frm_data_valid_flag &&
6418
2.76k
                   ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
6419
1.97k
                {
6420
                    /*get relevant lambda params*/
6421
1.97k
                    ihevce_get_frame_lambda_prms(
6422
1.97k
                        ps_enc_ctxt,
6423
1.97k
                        ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx],
6424
1.97k
                        ps_multi_thrd->i4_qp_update_l0_ipe,
6425
1.97k
                        ps_enc_ctxt->s_runtime_src_prms.i4_field_pic,
6426
1.97k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_lap_out.i4_is_ref_pic,
6427
1.97k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6428
1.97k
                            ->s_lap_out.i4_temporal_lyr_id,
6429
1.97k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6430
1.97k
                            ->s_lap_out.f_i_pic_lamda_modifier,
6431
1.97k
                        0,
6432
1.97k
                        PRE_ENC_LAMBDA_TYPE);
6433
6434
1.97k
                    ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp =
6435
1.97k
                        ps_multi_thrd->i4_qp_update_l0_ipe;
6436
1.97k
                }
6437
                /* Compute accumulated activity and strength */
6438
2.98k
                if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6439
2.98k
                            ->s_input_buf.i4_inp_frm_data_valid_flag &&
6440
2.76k
                   ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] == 0)
6441
2.76k
                {
6442
2.76k
                    ihevce_variance_calc_acc_activity(ps_enc_ctxt, i4_cur_ipe_idx);
6443
2.76k
                }
6444
6445
                /* Mark qp as read by last thread */
6446
2.98k
                ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx]++;
6447
2.98k
                if(ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] ==
6448
2.98k
                   ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6449
2.98k
                {
6450
2.98k
                    ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] = 0;
6451
2.98k
                    ps_multi_thrd->i4_qp_update_l0_ipe = -1;
6452
2.98k
                }
6453
6454
                /****** UnLock the critical section after deinit ******/
6455
2.98k
                {
6456
2.98k
                    WORD32 i4_status;
6457
2.98k
                    i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_l0_ipe_init);
6458
6459
2.98k
                    if(OSAL_SUCCESS != i4_status)
6460
0
                        return 0;
6461
2.98k
                }
6462
6463
2.98k
                if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6464
2.98k
                            ->s_input_buf.i4_inp_frm_data_valid_flag)
6465
2.76k
                {
6466
2.76k
                    WORD32 i4_slice_type =
6467
2.76k
                        (WORD32)ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]
6468
2.76k
                            ->s_slice_hdr.i1_slice_type;
6469
2.76k
                    WORD32 i4_quality_preset =
6470
2.76k
                        (WORD32)ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6471
2.76k
                            ->s_lap_out.i4_quality_preset;
6472
2.76k
                    WORD32 i4_temporal_layer_id =
6473
2.76k
                        (WORD32)ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6474
2.76k
                            ->s_lap_out.i4_temporal_lyr_id;
6475
2.76k
#if DISABLE_L0_IPE_INTRA_IN_BPICS
6476
2.76k
                    if(1 != ((i4_quality_preset == IHEVCE_QUALITY_P6) &&
6477
233
                             (i4_temporal_layer_id > TEMPORAL_LAYER_DISABLE)))
6478
2.76k
#endif
6479
2.76k
                    {
6480
2.76k
                        UWORD8 i1_cu_qp_delta_enabled_flag =
6481
2.76k
                            ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_cu_level_rc;
6482
6483
2.76k
                        ihevce_populate_ipe_frame_init(
6484
2.76k
                            ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6485
2.76k
                            ps_enc_ctxt->ps_stat_prms,
6486
2.76k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp,
6487
2.76k
                            i4_slice_type,
6488
2.76k
                            i4_thrd_id,
6489
2.76k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx],
6490
2.76k
                            i1_cu_qp_delta_enabled_flag,
6491
2.76k
                            &ps_enc_ctxt->s_rc_quant,
6492
2.76k
                            i4_quality_preset,
6493
2.76k
                            i4_temporal_layer_id,
6494
2.76k
                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_lap_out);
6495
6496
2.76k
                        ihevce_ipe_process(
6497
2.76k
                            ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6498
2.76k
                            &ps_enc_ctxt->s_frm_ctb_prms,
6499
2.76k
                            &ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->as_lambda_prms[0],
6500
2.76k
                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx],
6501
2.76k
                            ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc,
6502
2.76k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_ctb_analyse,
6503
2.76k
                            ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc->ps_ipe_analyse_ctb,
6504
2.76k
                            &ps_enc_ctxt->s_multi_thrd,
6505
2.76k
                            i4_slice_type,
6506
2.76k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_layer1_buf,
6507
2.76k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_layer2_buf,
6508
2.76k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_ed_ctb_l1,
6509
2.76k
                            i4_thrd_id,
6510
2.76k
                            i4_cur_ipe_idx);
6511
2.76k
                    }
6512
2.76k
                }
6513
6514
                /* ----------------------------------------------------------- */
6515
                /*     pre-enc de-init                                         */
6516
                /* ----------------------------------------------------------- */
6517
6518
                /****** Lock the critical section for deinit ******/
6519
2.98k
                {
6520
2.98k
                    WORD32 i4_status;
6521
2.98k
                    i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_deinit);
6522
6523
2.98k
                    if(OSAL_SUCCESS != i4_status)
6524
0
                        return 0;
6525
2.98k
                }
6526
6527
2.98k
                ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx]++;
6528
2.98k
                if(ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx] ==
6529
2.98k
                   ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6530
2.98k
                {
6531
2.98k
                    ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx] = 0;
6532
2.98k
                    ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx] = 0;
6533
6534
                    /* reset the init flag so that init happens by the first thread for the
6535
                       next frame of same ping_pnog instnace */
6536
2.98k
                    ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_ipe_idx] = 0;
6537
2.98k
                }
6538
6539
                /* de-init */
6540
2.98k
                if(0 == ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx])
6541
2.98k
                {
6542
2.98k
                    ihevce_lap_enc_buf_t *ps_curr_inp =
6543
2.98k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx];
6544
2.98k
                    pre_enc_me_ctxt_t *ps_curr_out =
6545
2.98k
                        ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx];
6546
6547
                    /* set the flag saying de init is done so that other cores dont do it */
6548
2.98k
                    ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx] = 1;
6549
6550
2.98k
                    if(1 == ps_curr_out->i4_frm_proc_valid_flag)
6551
2.76k
                    {
6552
2.76k
                        LWORD64 frame_acc_satd_by_modqp;
6553
2.76k
                        float L1_full_processed_ratio;
6554
6555
2.76k
                        if(ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated)
6556
2.63k
                        {
6557
2.63k
                            L1_full_processed_ratio =
6558
2.63k
                                ((float)ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum /
6559
2.63k
                                 ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated);
6560
2.63k
                        }
6561
138
                        else
6562
138
                        {
6563
138
                            L1_full_processed_ratio = 1.0;
6564
138
                        }
6565
                        /* Get frame-level satd cost and mode bit cost from IPE */
6566
2.76k
                        ps_curr_out->i8_frame_acc_satd_cost = ihevce_ipe_get_frame_intra_satd_cost(
6567
2.76k
                            ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6568
2.76k
                            &frame_acc_satd_by_modqp,
6569
2.76k
                            &ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits,
6570
2.76k
                            &ps_curr_inp->s_lap_out.i8_frame_level_activity_fact,
6571
2.76k
                            &ps_curr_inp->s_lap_out.i8_frame_l0_acc_satd);
6572
6573
2.76k
                        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
6574
233
                           (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
6575
0
                        {
6576
0
                            ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits = -1;
6577
0
                        }
6578
6579
2.76k
                        {
6580
2.76k
                            WORD32 i4_cur_q_scale = (ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
6581
2.76k
                                                         [ps_enc_ctxt->s_multi_thrd.i4_rc_l0_qp +
6582
2.76k
                                                          ps_enc_ctxt->s_rc_quant.i1_qp_offset] +
6583
2.76k
                                                     (1 << (QSCALE_Q_FAC_3 - 1))) >>
6584
2.76k
                                                    QSCALE_Q_FAC_3;
6585
6586
                            /* calculate satd/act_fac = satd/qm * (qp_used_at_L0_analysis) */
6587
2.76k
                            ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum =
6588
2.76k
                                frame_acc_satd_by_modqp * i4_cur_q_scale;
6589
2.76k
                        }
6590
6591
                        /* Because of early intra inter decision, L0 intra analysis might not happen for entire frame, correct the error
6592
                           based on L1 data */
6593
2.76k
                        ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits = (LWORD64)(
6594
2.76k
                            ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits *
6595
2.76k
                            L1_full_processed_ratio);
6596
6597
2.76k
                        if(L1_full_processed_ratio < 1.5)
6598
2.21k
                        {
6599
2.21k
                            ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum = (LWORD64)(
6600
2.21k
                                ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum *
6601
2.21k
                                L1_full_processed_ratio);
6602
2.21k
                        }
6603
557
                        else
6604
557
                        {
6605
                            /* This is the case when too many candidates would not have gone through intra analysis, scaling based on L1 is found to be inappropriate,
6606
                            Hence directly estimating L0 satd from L1 satd */
6607
557
                            ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum =
6608
557
                                ps_curr_inp->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1;
6609
557
                        }
6610
2.76k
                    }
6611
6612
                    /* register the current input buffer to be cnosumed by encode group threads */
6613
2.98k
                    ps_curr_out->curr_inp_buf_id =
6614
2.98k
                        ps_multi_thrd->ai4_in_buf_id_pre_enc[i4_cur_ipe_idx];
6615
2.98k
                    ps_curr_out->ps_curr_inp = ps_curr_inp;
6616
6617
                    /* set the output buffer as produced */
6618
2.98k
                    ihevce_q_set_buff_prod(
6619
2.98k
                        (void *)ps_enc_ctxt,
6620
2.98k
                        IHEVCE_PRE_ENC_ME_Q,
6621
2.98k
                        ps_multi_thrd->ai4_out_buf_id_pre_enc[i4_cur_ipe_idx]);
6622
6623
                    /* set the output buffer of L0 IPE as produced */
6624
2.98k
                    ihevce_q_set_buff_prod(
6625
2.98k
                        (void *)ps_enc_ctxt,
6626
2.98k
                        IHEVCE_L0_IPE_ENC_Q,
6627
2.98k
                        ps_multi_thrd->i4_L0_IPE_out_buf_id);
6628
6629
                    /* update flag indicating ipe is done */
6630
2.98k
                    ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l0);
6631
2.98k
                }
6632
6633
2.98k
                {
6634
                    /* index increment */
6635
2.98k
                    i4_cur_ipe_idx = i4_cur_ipe_idx + 1;
6636
6637
                    /* wrap around case */
6638
2.98k
                    if(i4_cur_ipe_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6639
1.44k
                    {
6640
1.44k
                        i4_cur_ipe_idx = 0;
6641
1.44k
                    }
6642
6643
2.98k
                    i4_num_buf_prod_for_l0_ipe--;
6644
2.98k
                }
6645
                /*NOTE: update of above indices should mark end if ipe.do not access below this*/
6646
6647
                /****** UnLock the critical section after deinit ******/
6648
2.98k
                {
6649
2.98k
                    WORD32 i4_status;
6650
2.98k
                    i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_deinit);
6651
6652
2.98k
                    if(OSAL_SUCCESS != i4_status)
6653
0
                        return 0;
6654
2.98k
                }
6655
6656
2.98k
                if(1 == ps_multi_thrd->i4_force_end_flag)
6657
0
                {
6658
0
                    i4_end_flag = 1;
6659
0
                    break;
6660
0
                }
6661
2.98k
            } while((i4_end_flag || i4_out_flush_flag) && i4_num_buf_prod_for_l0_ipe);
6662
2.98k
        }
6663
2.98k
        if(i4_thrd_id == 0)
6664
2.98k
        {
6665
2.98k
            PROFILE_STOP(&ps_hle_ctxt->profile_pre_enc_l0ipe[i4_resolution_id], NULL);
6666
2.98k
        }
6667
2.98k
    }
6668
6669
218
    return 0;
6670
218
}
6671
6672
void calc_l1_level_hme_intra_sad_different_qp(
6673
    enc_ctxt_t *ps_enc_ctxt,
6674
    pre_enc_me_ctxt_t *ps_curr_out,
6675
    ihevce_lap_enc_buf_t *ps_curr_inp,
6676
    WORD32 i4_tot_ctb_l1_x,
6677
    WORD32 i4_tot_ctb_l1_y)
6678
2.76k
{
6679
2.76k
    ihevce_ed_ctb_l1_t *ps_ed_ctb_l1;
6680
2.76k
    WORD32 i4_qp_counter, i4_qp_start = 0, i4_qp_end = 0, i, i4_j, i4_new_frame_qp;
6681
2.76k
    LWORD64 i8_l1_intra_sad_nc_accounted = 0, cur_intra_sad, raw_hme_sad = 0;
6682
2.76k
    LWORD64 cur_hme_sad = 0, cur_hme_sad_for_offset = 0, acc_hme_l1_sad = 0,
6683
2.76k
            acc_hme_l1_sad_for_offset = 0;
6684
2.76k
    i4_qp_start = 1;
6685
2.76k
    i4_qp_end = 51;
6686
6687
49.8k
    for(i4_qp_counter = i4_qp_start; i4_qp_counter <= i4_qp_end; i4_qp_counter = i4_qp_counter + 3)
6688
47.0k
    {
6689
47.0k
        i8_l1_intra_sad_nc_accounted = 0;
6690
47.0k
        cur_intra_sad = 0;
6691
47.0k
        raw_hme_sad = 0;
6692
47.0k
        cur_hme_sad = 0;
6693
47.0k
        cur_hme_sad_for_offset = 0;
6694
47.0k
        acc_hme_l1_sad = 0;
6695
47.0k
        ps_ed_ctb_l1 = ps_curr_out->ps_ed_ctb_l1;
6696
47.0k
        i4_new_frame_qp = i4_qp_counter;
6697
47.0k
        acc_hme_l1_sad = 0;
6698
6699
301k
        for(i = 0; i < (i4_tot_ctb_l1_x * i4_tot_ctb_l1_y); i += 1)
6700
254k
        {
6701
4.32M
            for(i4_j = 0; i4_j < 16; i4_j++)
6702
4.07M
            {
6703
4.07M
                if(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] != -1)
6704
3.48M
                {
6705
3.48M
                    ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
6706
3.48M
                    if(ps_curr_inp->s_rc_lap_out.i4_rc_pic_type != IV_I_FRAME &&
6707
3.35M
                       ps_curr_inp->s_rc_lap_out.i4_rc_pic_type != IV_IDR_FRAME)
6708
1.91M
                    {
6709
                        /*When l1 is disabled for B pics i4_best_sad_8x8_l1_ipe is set to max value always,
6710
                        so will enter this path even for incomplete ctb, hence the assert holdsto good only for P pic  */
6711
1.91M
                        if(ps_curr_inp->s_rc_lap_out.i4_rc_quality_preset == IHEVCE_QUALITY_P6)
6712
91.1k
                        {
6713
91.1k
                            if(ps_curr_inp->s_rc_lap_out.i4_rc_pic_type == IV_P_FRAME)
6714
91.1k
                            {
6715
91.1k
                                ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] >= 0);
6716
91.1k
                                ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me_for_decide[i4_j] >= 0);
6717
91.1k
                            }
6718
91.1k
                        }
6719
1.82M
                        else
6720
1.82M
                        {
6721
1.82M
                            ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] >= 0);
6722
1.82M
                            ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me_for_decide[i4_j] >= 0);
6723
1.82M
                        }
6724
6725
1.91M
#if 1  //DISABLE_L1_L2_IPE_INTRA_IN_BPICS && RC_DEPENDENCY_FOR_BPIC
6726
1.91M
                        if((ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] != -1))
6727
1.91M
#endif
6728
1.91M
                        {
6729
1.91M
                            cur_hme_sad = ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] -
6730
1.91M
                                          (QP2QUANT_MD[i4_new_frame_qp] << 3);
6731
1.91M
                        }
6732
1.91M
                        raw_hme_sad += ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j];
6733
6734
1.91M
                        if(cur_hme_sad > 0)
6735
610k
                            acc_hme_l1_sad += cur_hme_sad;
6736
1.91M
                    }
6737
3.48M
                    if(cur_hme_sad_for_offset > 0)
6738
0
                    {
6739
0
                        acc_hme_l1_sad_for_offset += cur_hme_sad_for_offset;
6740
0
                    }
6741
3.48M
                    ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
6742
                    /*intra sad is scaled by 1.17 to be account for 1/3 vs 1/6th rounding*/
6743
3.48M
                    cur_intra_sad = (LWORD64)(
6744
3.48M
                        (ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] * 1.17) -
6745
3.48M
                        (QP2QUANT_MD[i4_new_frame_qp] << 3));
6746
6747
3.48M
                    if(cur_intra_sad > 0)
6748
1.41M
                        i8_l1_intra_sad_nc_accounted += cur_intra_sad;
6749
3.48M
                }
6750
4.07M
            }
6751
254k
            ps_ed_ctb_l1 += 1;
6752
254k
        }
6753
47.0k
        if((ps_curr_inp->s_rc_lap_out.i4_rc_quality_preset == IHEVCE_QUALITY_P6) &&
6754
3.96k
           (ps_curr_inp->s_rc_lap_out.i4_rc_pic_type == IV_B_FRAME))
6755
0
        {
6756
0
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter] = -1;
6757
0
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 1] = -1;
6758
0
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 2] = -1;
6759
0
        }
6760
47.0k
        else
6761
47.0k
        {
6762
47.0k
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter] =
6763
47.0k
                i8_l1_intra_sad_nc_accounted;
6764
47.0k
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 1] =
6765
47.0k
                i8_l1_intra_sad_nc_accounted;
6766
47.0k
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 2] =
6767
47.0k
                i8_l1_intra_sad_nc_accounted;
6768
47.0k
        }
6769
47.0k
        ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter] = acc_hme_l1_sad;
6770
47.0k
        ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter + 1] = acc_hme_l1_sad;
6771
47.0k
        ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter + 2] = acc_hme_l1_sad;
6772
47.0k
        ps_curr_inp->s_rc_lap_out.i8_raw_l1_coarse_me_sad = raw_hme_sad;
6773
47.0k
    }
6774
2.76k
}