Coverage Report

Created: 2026-09-01 06:17

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
201k
#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.93k
{
249
2.93k
    WORD32 i4_ctr;
250
2.93k
    WORD32 i4_is_full = 1;
251
2.93k
    WORD32 i4_least_POC = 0x7FFFFFFF;
252
2.93k
    WORD32 i4_least_POC_idx = -1;
253
2.93k
    WORD32 i4_least_GOP_num = 0x7FFFFFFF;
254
255
15.2k
    for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
256
13.0k
    {
257
13.0k
        if(pps_recon_buf_q[i4_ctr]->i4_is_free == 1)
258
726
        {
259
726
            i4_is_full = 0;
260
726
            break;
261
726
        }
262
13.0k
    }
263
2.93k
    if(i4_is_full)
264
2.21k
    {
265
        /* remove if any non-reference pictures are present */
266
13.2k
        for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
267
11.0k
        {
268
11.0k
            if(!pps_recon_buf_q[i4_ctr]->i4_is_reference &&
269
21
               pps_recon_buf_q[i4_ctr]->i4_non_ref_free_flag)
270
21
            {
271
21
                i4_least_POC_idx = i4_ctr;
272
21
                break;
273
21
            }
274
11.0k
        }
275
        /* if all non reference pictures are removed, then find the least poc
276
        in the least gop number*/
277
2.21k
        if(i4_least_POC_idx == -1)
278
2.19k
        {
279
13.1k
            for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
280
10.9k
            {
281
10.9k
                if(i4_least_GOP_num > pps_recon_buf_q[i4_ctr]->i4_idr_gop_num)
282
2.50k
                {
283
2.50k
                    i4_least_GOP_num = pps_recon_buf_q[i4_ctr]->i4_idr_gop_num;
284
2.50k
                }
285
10.9k
            }
286
13.1k
            for(i4_ctr = 0; i4_ctr < i4_num_buf; i4_ctr++)
287
10.9k
            {
288
10.9k
                if(i4_least_POC > pps_recon_buf_q[i4_ctr]->i4_poc &&
289
4.83k
                   i4_least_GOP_num == pps_recon_buf_q[i4_ctr]->i4_idr_gop_num)
290
3.59k
                {
291
3.59k
                    i4_least_POC = pps_recon_buf_q[i4_ctr]->i4_poc;
292
3.59k
                    i4_least_POC_idx = i4_ctr;
293
3.59k
                }
294
10.9k
            }
295
2.19k
        }
296
2.21k
    }
297
2.93k
    return i4_least_POC_idx;
298
2.93k
}
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.12k
{
320
2.12k
    rc_lap_out_params_t *ps_cur_ipe_lap_out;
321
2.12k
    rc_lap_out_params_t *ps_lap_out_temp;
322
2.12k
    WORD32 i4_max_temporal_layers;
323
324
2.12k
    ps_cur_ipe_lap_out =
325
2.12k
        &ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out;
326
2.12k
    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_model = 0;
327
2.12k
    ps_cur_ipe_lap_out->i4_is_cmplx_change_reset_bits = 0;
328
329
2.12k
    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.12k
    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
183
    {
335
183
        ps_enc_ctxt->i4_past_RC_reset_count = 0;
336
183
    }
337
338
2.12k
    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.12k
    ps_enc_ctxt->i4_past_RC_reset_count++;
343
2.12k
    ps_enc_ctxt->i4_past_RC_scd_reset_count++;
344
345
    /*complexity based rate control reset */
346
347
2.12k
    if((ps_cur_ipe_lap_out->i4_rc_pic_type == IV_P_FRAME ||
348
495
        ps_cur_ipe_lap_out->i4_rc_pic_type == IV_I_FRAME) &&
349
1.72k
       (i4_max_temporal_layers > 1) && (!i4_end_flag) &&
350
19
       (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.12k
    return;
503
2.12k
}
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.93k
{
531
    /* local variables */
532
2.93k
    WORD32 ctr;
533
2.93k
    WORD32 ref_pics;
534
2.93k
    WORD32 ai4_buf_status[HEVCE_MAX_DPB_PICS] = { 0 };
535
2.93k
    WORD32 curr_poc;
536
2.93k
    WORD32 wp_flag = 0;
537
2.93k
    WORD32 num_ref_pics_list0 = 0;
538
2.93k
    WORD32 num_ref_pics_list1 = 0;
539
2.93k
    WORD32 cra_poc = ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc;
540
2.93k
    WORD32 slice_type = ps_curr_out->s_slice_hdr.i1_slice_type;
541
2.93k
    recon_pic_buf_t *(*aps_pre_enc_ref_pic_list)[HEVCE_MAX_REF_PICS * 2];
542
2.93k
    WORD32 i4_inc_L1_active_ref_pic = 0;
543
2.93k
    WORD32 i4_inc_L0_active_ref_pic = 0;
544
545
2.93k
    (void)ps_curr_out;
546
2.93k
    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.93k
    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.93k
    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.93k
    if(BSLICE == slice_type)
556
43
    {
557
43
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_bipred_flag;
558
43
    }
559
2.89k
    else if(PSLICE == slice_type)
560
2.31k
    {
561
2.31k
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_pred_flag;
562
2.31k
    }
563
583
    else
564
583
    {
565
583
        wp_flag = 0;
566
583
    }
567
568
    /*to support diplicate pics*/
569
2.93k
    {
570
2.93k
        WORD32 i, j;
571
8.81k
        for(i = 0; i < 2; i++)
572
5.87k
        {
573
99.8k
            for(j = 0; j < HEVCE_MAX_REF_PICS * 2; j++)
574
93.9k
            {
575
93.9k
                aps_pre_enc_ref_pic_list[i][j] =
576
93.9k
                    &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][i][j];
577
93.9k
            }
578
5.87k
        }
579
2.93k
    }
580
581
    /* run a loop over the number of reference pics given by LAP */
582
11.0k
    for(ref_pics = 0; ref_pics < ps_curr_inp->s_lap_out.i4_num_ref_pics; ref_pics++)
583
8.11k
    {
584
8.11k
        WORD32 ref_poc;
585
8.11k
        WORD32 i4_loop = 1;
586
8.11k
        WORD32 i4_temp_list;
587
588
8.11k
        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
22.1k
        for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
592
22.1k
        {
593
            /* if the POC is matching with current ref picture*/
594
22.1k
            if((ref_poc == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_poc) &&
595
8.11k
               (0 == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free))
596
8.11k
            {
597
                /* mark the buf status as used */
598
8.11k
                ai4_buf_status[ctr] = 1;
599
600
                /* populate the reference lists based on delta poc array */
601
8.11k
                if((ref_poc < curr_poc) || (0 == curr_poc))
602
8.05k
                {
603
                    /* list 0 */
604
8.05k
                    memcpy(
605
8.05k
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0],
606
8.05k
                        ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
607
8.05k
                        sizeof(recon_pic_buf_t));
608
8.05k
                    i4_temp_list = num_ref_pics_list0;
609
610
                    /*duplicate pics added to the list*/
611
8.05k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
612
8.05k
                                         .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
8.05k
                    memcpy(
625
8.05k
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
626
8.05k
                             .s_weight_offset,
627
8.05k
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
628
8.05k
                        sizeof(ihevce_wght_offst_t));
629
630
                    /* Store the used as ref for current pic flag  */
631
8.05k
                    ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_0][num_ref_pics_list0]
632
8.05k
                        .i4_used_by_cur_pic_flag =
633
8.05k
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
634
635
8.05k
                    num_ref_pics_list0++;
636
8.05k
                    i4_loop = 1;
637
                    /*duplicate pics added to the list*/
638
8.05k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
639
8.05k
                                         .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
8.05k
                }
658
58
                else
659
58
                {
660
                    /* list 1 */
661
58
                    memcpy(
662
58
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1],
663
58
                        ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr],
664
58
                        sizeof(recon_pic_buf_t));
665
666
58
                    i4_temp_list = num_ref_pics_list1;
667
                    /*duplicate pics added to the list*/
668
58
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
669
58
                                         .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
58
                    memcpy(
682
58
                        &ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
683
58
                             .s_weight_offset,
684
58
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
685
58
                        sizeof(ihevce_wght_offst_t));
686
687
                    /* Store the used as ref for current pic flag  */
688
58
                    ps_enc_ctxt->as_pre_enc_ref_lists[i4_ping_pong][LIST_1][num_ref_pics_list1]
689
58
                        .i4_used_by_cur_pic_flag =
690
58
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
691
692
58
                    num_ref_pics_list1++;
693
58
                    i4_loop = 1;
694
                    /*duplicate pics added to the list*/
695
58
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
696
58
                                         .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
58
                }
715
8.11k
                break;
716
8.11k
            }
717
22.1k
        }
718
719
        /* if the reference picture is not found then error */
720
8.11k
        ASSERT(ctr != ps_enc_ctxt->i4_pre_enc_num_buf_recon_q);
721
8.11k
    }
722
    /* sort the reference pics in List0 in descending order POC */
723
2.93k
    if(num_ref_pics_list0 > 1)
724
2.13k
    {
725
        /* run a loop for num ref pics -1 */
726
7.70k
        for(ctr = 0; ctr < num_ref_pics_list0 - 1; ctr++)
727
5.57k
        {
728
5.57k
            WORD32 max_idx = ctr;
729
5.57k
            recon_pic_buf_t *ps_temp;
730
5.57k
            WORD32 i;
731
732
16.1k
            for(i = (ctr + 1); i < num_ref_pics_list0; i++)
733
10.6k
            {
734
                /* check for poc greater than current ref poc */
735
10.6k
                if(aps_pre_enc_ref_pic_list[LIST_0][i]->i4_poc >
736
10.6k
                   aps_pre_enc_ref_pic_list[LIST_0][max_idx]->i4_poc)
737
0
                {
738
0
                    max_idx = i;
739
0
                }
740
10.6k
            }
741
742
            /* if max of remaining is not current, swap the pointers */
743
5.57k
            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
5.57k
        }
750
2.13k
    }
751
752
    /* sort the reference pics in List1 in ascending order POC */
753
2.93k
    if(num_ref_pics_list1 > 1)
754
15
    {
755
        /* run a loop for num ref pics -1 */
756
30
        for(ctr = 0; ctr < num_ref_pics_list1 - 1; ctr++)
757
15
        {
758
15
            WORD32 min_idx = ctr;
759
15
            recon_pic_buf_t *ps_temp;
760
15
            WORD32 i;
761
762
30
            for(i = (ctr + 1); i < num_ref_pics_list1; i++)
763
15
            {
764
                /* check for p[oc less than current ref poc */
765
15
                if(aps_pre_enc_ref_pic_list[LIST_1][i]->i4_poc <
766
15
                   aps_pre_enc_ref_pic_list[LIST_1][min_idx]->i4_poc)
767
0
                {
768
0
                    min_idx = i;
769
0
                }
770
15
            }
771
772
            /* if min of remaining is not current, swap the pointers */
773
15
            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
15
        }
780
15
    }
781
782
    /* call the ME API to update the DPB of HME pyramids coarse layers */
783
2.93k
    ihevce_coarse_me_frame_dpb_update(
784
2.93k
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
785
2.93k
        num_ref_pics_list0,
786
2.93k
        num_ref_pics_list1,
787
2.93k
        &aps_pre_enc_ref_pic_list[LIST_0][0],
788
2.93k
        &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.93k
    {
792
2.93k
        WORD32 num_ref_pics_list_final = 0;
793
2.93k
        WORD32 list_idx = 0;
794
795
        /* LIST 0 */
796
        /* run a loop for num ref pics in list 0 */
797
10.9k
        for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
798
8.05k
        {
799
            /* check for used as reference flag */
800
8.05k
            if(1 == aps_pre_enc_ref_pic_list[LIST_0][ctr]->i4_used_by_cur_pic_flag)
801
8.05k
            {
802
                /* copy the pointer to the actual valid list idx */
803
8.05k
                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
8.05k
                list_idx++;
807
8.05k
                num_ref_pics_list_final++;
808
8.05k
            }
809
8.05k
        }
810
811
        /* finally store the number of pictures in List0 */
812
2.93k
        num_ref_pics_list0 = num_ref_pics_list_final;
813
        /* LIST 1 */
814
2.93k
        num_ref_pics_list_final = 0;
815
2.93k
        list_idx = 0;
816
817
        /* run a loop for num ref pics in list 1 */
818
2.99k
        for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
819
58
        {
820
            /* check for used as reference flag */
821
58
            if(1 == aps_pre_enc_ref_pic_list[LIST_1][ctr]->i4_used_by_cur_pic_flag)
822
58
            {
823
                /* copy the pointer to the actual valid list idx */
824
58
                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
58
                list_idx++;
828
58
                num_ref_pics_list_final++;
829
58
            }
830
58
        }
831
832
        /* finally store the number of pictures in List1 */
833
2.93k
        num_ref_pics_list1 = num_ref_pics_list_final;
834
2.93k
    }
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.93k
    if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
838
2.31k
    {
839
2.31k
        if(num_ref_pics_list0 > 2)
840
1.73k
        {
841
1.73k
            if(aps_pre_enc_ref_pic_list[LIST_0][0]->i4_poc ==
842
1.73k
               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.73k
        }
847
2.31k
    }
848
626
    else
849
626
    {
850
626
        if(num_ref_pics_list0 >= 2 && num_ref_pics_list1 >= 2)
851
5
        {
852
5
            if(aps_pre_enc_ref_pic_list[LIST_0][0]->i4_poc ==
853
5
               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
5
            if(aps_pre_enc_ref_pic_list[LIST_1][0]->i4_poc ==
858
5
               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
5
        }
863
626
    }
864
865
    /* append the reference pics in List1 and end of list0 */
866
2.99k
    for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
867
58
    {
868
58
        aps_pre_enc_ref_pic_list[LIST_0][num_ref_pics_list0 + ctr] =
869
58
            aps_pre_enc_ref_pic_list[LIST_1][ctr];
870
58
    }
871
872
    /* append the reference pics in List0 and end of list1 */
873
10.9k
    for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
874
8.05k
    {
875
8.05k
        aps_pre_enc_ref_pic_list[LIST_1][num_ref_pics_list1 + ctr] =
876
8.05k
            aps_pre_enc_ref_pic_list[LIST_0][ctr];
877
8.05k
    }
878
879
    /* reference list modification for adding duplicate reference */
880
2.93k
    {
881
882
2.93k
    }
883
884
    /* popluate the default weights and offsets for disabled cases */
885
2.93k
    {
886
2.93k
        WORD32 i;
887
888
        /* populate the weights and offsets for all pics in L0 + L1 */
889
11.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
890
8.11k
        {
891
            /* populate the weights and offsets if weighted prediction is disabled */
892
8.11k
            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
8.11k
        }
906
907
11.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
908
8.11k
        {
909
            /* populate the weights and offsets if weighted prediction is enabled */
910
8.11k
            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
8.11k
        }
924
2.93k
    }
925
926
    /* run a loop to free the non used reference pics */
927
17.6k
    for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
928
14.6k
    {
929
        /* if not used as reference */
930
14.6k
        if(0 == ai4_buf_status[ctr])
931
6.56k
        {
932
6.56k
            ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free = 1;
933
6.56k
            ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_poc = -1;
934
6.56k
        }
935
14.6k
    }
936
937
    /* store the number of reference pics in the list for ME/MC etc */
938
2.93k
    ps_enc_ctxt->i4_pre_enc_num_ref_l0 = num_ref_pics_list0;
939
2.93k
    ps_enc_ctxt->i4_pre_enc_num_ref_l1 = num_ref_pics_list1;
940
941
2.93k
#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.93k
#if MULTI_REF_ENABLE == 1
947
2.93k
    if(ps_curr_inp->s_lap_out.i4_quality_preset >= IHEVCE_QUALITY_P3)
948
2.03k
    {
949
2.03k
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
950
1.69k
        {
951
1.69k
            if(IHEVCE_QUALITY_P6 == ps_curr_inp->s_lap_out.i4_quality_preset)
952
330
            {
953
330
                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
330
                else
959
330
                {
960
330
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active =
961
330
                        MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25, num_ref_pics_list0);
962
330
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
963
330
                }
964
965
330
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
966
330
            }
967
1.36k
            else
968
1.36k
            {
969
1.36k
                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.36k
                else
974
1.36k
                {
975
1.36k
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(2, num_ref_pics_list0);
976
1.36k
                    ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
977
1.36k
                }
978
979
1.36k
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
980
1.36k
            }
981
1.69k
        }
982
335
        else
983
335
        {
984
335
            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
335
            else
991
335
            {
992
335
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(1, num_ref_pics_list0);
993
335
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(1, num_ref_pics_list1);
994
335
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active += i4_inc_L1_active_ref_pic;
995
335
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active += i4_inc_L0_active_ref_pic;
996
335
            }
997
335
        }
998
2.03k
    }
999
904
    else
1000
904
    {
1001
904
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1002
613
        {
1003
613
            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
613
            else
1006
613
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1007
1008
613
            ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = 0;
1009
613
        }
1010
291
        else
1011
291
        {
1012
291
            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
291
            else
1018
291
            {
1019
291
                ps_enc_ctxt->i4_pre_enc_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1020
291
                ps_enc_ctxt->i4_pre_enc_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1021
291
            }
1022
291
        }
1023
904
    }
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.93k
#endif
1051
1052
2.93k
    return;
1053
2.93k
}
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.93k
{
1084
2.93k
    WORD32 ctr;
1085
2.93k
    WORD32 ref_pics;
1086
2.93k
    WORD32 curr_poc, curr_idr_gop_num;
1087
2.93k
    WORD32 wp_flag;
1088
2.93k
    WORD32 num_ref_pics_list0 = 0;
1089
2.93k
    WORD32 num_ref_pics_list1 = 0;
1090
2.93k
    WORD32 cra_poc = ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc;
1091
2.93k
    WORD32 slice_type = ps_slice_header->i1_slice_type;
1092
2.93k
    recon_pic_buf_t *(*aps_ref_list)[HEVCE_MAX_REF_PICS * 2];
1093
2.93k
    recon_pic_buf_t(*aps_ref_list_temp)[HEVCE_MAX_REF_PICS * 2];
1094
2.93k
    WORD32 i4_num_rpics_l0_excl_dup;
1095
2.93k
    WORD32 i4_num_rpics_l1_excl_dup;
1096
2.93k
    WORD32 i4_inc_L1_active_ref_pic = 0;
1097
2.93k
    WORD32 i4_inc_L0_active_ref_pic = 0;
1098
2.93k
    WORD32 i4_bridx = i4_bitrate_instance_id;  //bitrate instance index
1099
2.93k
    WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
1100
2.93k
    me_enc_rdopt_ctxt_t *ps_cur_out_me_prms;
1101
2.93k
    recon_pic_buf_t ***ppps_recon_bufs = ps_enc_ctxt->pps_recon_buf_q;
1102
2.93k
    WORD32 i4_num_recon_bufs = ps_enc_ctxt->ai4_num_buf_recon_q[i4_bridx];
1103
1104
2.93k
    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.93k
    {
1108
2.93k
        WORD32 i, j;
1109
8.81k
        for(i = 0; i < NUM_REF_LISTS; i++)
1110
5.87k
        {
1111
99.8k
            for(j = 0; j < HEVCE_MAX_REF_PICS * 2; j++)
1112
93.9k
            {
1113
93.9k
                ps_cur_out_me_prms->aps_ref_list[i4_bridx][i][j] =
1114
93.9k
                    &ps_cur_out_me_prms->as_ref_list[i4_bridx][i][j];
1115
93.9k
            }
1116
5.87k
        }
1117
2.93k
    }
1118
1119
2.93k
    aps_ref_list = ps_cur_out_me_prms->aps_ref_list[i4_bridx];
1120
2.93k
    aps_ref_list_temp = ps_cur_out_me_prms->as_ref_list[i4_bridx];
1121
1122
2.93k
    curr_poc = ps_curr_inp->s_lap_out.i4_poc;
1123
2.93k
    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.93k
    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.93k
    if(BSLICE == slice_type)
1130
43
    {
1131
43
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_bipred_flag;
1132
43
    }
1133
2.89k
    else if(PSLICE == slice_type)
1134
2.31k
    {
1135
2.31k
        wp_flag = ps_curr_inp->s_lap_out.i1_weighted_pred_flag;
1136
2.31k
    }
1137
583
    else
1138
583
    {
1139
583
        wp_flag = 0;
1140
583
    }
1141
1142
2.93k
    ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l0 = 0;
1143
2.93k
    ps_slice_header->s_rplm.i1_ref_pic_list_modification_flag_l1 = 0;
1144
2.93k
    ASSERT(curr_poc != INVALID_POC);
1145
1146
    /* run a loop over the number of reference pics given by LAP */
1147
11.0k
    for(ref_pics = 0; ref_pics < ps_curr_inp->s_lap_out.i4_num_ref_pics; ref_pics++)
1148
8.11k
    {
1149
8.11k
        WORD32 ref_poc;
1150
8.11k
        WORD32 i4_loop = 1;
1151
8.11k
        WORD32 i4_temp_list;
1152
1153
8.11k
        ref_poc = curr_poc + ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_ref_pic_delta_poc;
1154
8.11k
        if((0 == curr_poc) && curr_idr_gop_num)
1155
0
        {
1156
0
            curr_idr_gop_num -= 1;
1157
0
        }
1158
8.11k
        ASSERT(ref_poc != INVALID_POC);
1159
        /* run a loop to check the poc based on delta poc array */
1160
23.2k
        for(ctr = 0; ctr < i4_num_recon_bufs; ctr++)
1161
23.2k
        {
1162
            /* if the POC is matching with current ref picture*/
1163
23.2k
            if((ref_poc == ppps_recon_bufs[i4_bridx][ctr]->i4_poc) &&
1164
8.15k
               (0 == ppps_recon_bufs[i4_bridx][ctr]->i4_is_free) &&
1165
8.15k
               (curr_idr_gop_num == ppps_recon_bufs[i4_bridx][ctr]->i4_idr_gop_num))
1166
8.11k
            {
1167
                /* populate the reference lists based on delta poc array */
1168
8.11k
                if((ref_poc < curr_poc) || (0 == curr_poc))
1169
8.05k
                {
1170
                    /* list 0 */
1171
8.05k
                    memcpy(
1172
8.05k
                        &aps_ref_list_temp[LIST_0][num_ref_pics_list0],
1173
8.05k
                        ppps_recon_bufs[i4_bridx][ctr],
1174
8.05k
                        sizeof(recon_pic_buf_t));
1175
1176
8.05k
                    i4_temp_list = num_ref_pics_list0;
1177
1178
                    /*duplicate pics added to the list*/
1179
8.05k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1180
8.05k
                                         .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
8.05k
                    memcpy(
1193
8.05k
                        &aps_ref_list_temp[LIST_0][num_ref_pics_list0].s_weight_offset,
1194
8.05k
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
1195
8.05k
                        sizeof(ihevce_wght_offst_t));
1196
1197
                    /* Store the used as ref for current pic flag  */
1198
8.05k
                    aps_ref_list_temp[LIST_0][num_ref_pics_list0].i4_used_by_cur_pic_flag =
1199
8.05k
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1200
1201
8.05k
                    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
8.05k
                    else
1213
8.05k
                    {
1214
8.05k
                        WORD16 i2_luma_weight =
1215
8.05k
                            (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1216
1217
8.05k
                        aps_ref_list[LIST_0][num_ref_pics_list0]->s_weight_offset.i2_luma_weight =
1218
8.05k
                            i2_luma_weight;
1219
1220
8.05k
                        aps_ref_list[LIST_0][num_ref_pics_list0]->i4_inv_luma_wt =
1221
8.05k
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1222
1223
8.05k
                        aps_ref_list[LIST_0][num_ref_pics_list0]->i4_log2_wt_denom =
1224
8.05k
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1225
8.05k
                    }
1226
1227
8.05k
                    num_ref_pics_list0++;
1228
8.05k
                    i4_loop = 1;
1229
1230
                    /*duplicate pics added to the list*/
1231
8.05k
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1232
8.05k
                                         .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
8.05k
                }
1276
58
                else
1277
58
                {
1278
                    /* list 1 */
1279
58
                    memcpy(
1280
58
                        &aps_ref_list_temp[LIST_1][num_ref_pics_list1],
1281
58
                        ppps_recon_bufs[i4_bridx][ctr],
1282
58
                        sizeof(recon_pic_buf_t));
1283
58
                    i4_temp_list = num_ref_pics_list1;
1284
                    /*duplicate pics added to the list*/
1285
58
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1286
58
                                         .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
58
                    memcpy(
1299
58
                        &aps_ref_list_temp[LIST_1][num_ref_pics_list1].s_weight_offset,
1300
58
                        &ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].as_wght_off[0],
1301
58
                        sizeof(ihevce_wght_offst_t));
1302
1303
                    /* Store the used as ref for current pic flag  */
1304
58
                    aps_ref_list_temp[LIST_1][num_ref_pics_list1].i4_used_by_cur_pic_flag =
1305
58
                        ps_curr_inp->s_lap_out.as_ref_pics[ref_pics].i4_used_by_cur_pic_flag;
1306
1307
58
                    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
58
                    else
1319
58
                    {
1320
58
                        WORD16 i2_luma_weight =
1321
58
                            (1 << ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom);
1322
1323
58
                        aps_ref_list[LIST_1][num_ref_pics_list1]->s_weight_offset.i2_luma_weight =
1324
58
                            i2_luma_weight;
1325
1326
58
                        aps_ref_list[LIST_1][num_ref_pics_list1]->i4_inv_luma_wt =
1327
58
                            ((1 << 15) + (i2_luma_weight >> 1)) / i2_luma_weight;
1328
1329
58
                        aps_ref_list[LIST_1][num_ref_pics_list1]->i4_log2_wt_denom =
1330
58
                            ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom;
1331
58
                    }
1332
1333
58
                    num_ref_pics_list1++;
1334
58
                    i4_loop = 1;
1335
                    /*duplicate pics added to the list*/
1336
58
                    while(i4_loop != ps_curr_inp->s_lap_out.as_ref_pics[ref_pics]
1337
58
                                         .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
58
                }
1381
8.11k
                break;
1382
8.11k
            }
1383
23.2k
        }
1384
1385
        /* if the reference picture is not found then error */
1386
8.11k
        ASSERT(ctr != i4_num_recon_bufs);
1387
8.11k
    }
1388
1389
2.93k
    i4_num_rpics_l0_excl_dup = num_ref_pics_list0;
1390
2.93k
    i4_num_rpics_l1_excl_dup = num_ref_pics_list1;
1391
1392
    /* sort the reference pics in List0 in descending order POC */
1393
2.93k
    if(num_ref_pics_list0 > 1)
1394
2.13k
    {
1395
        /* run a loop for num ref pics -1 */
1396
7.70k
        for(ctr = 0; ctr < num_ref_pics_list0 - 1; ctr++)
1397
5.57k
        {
1398
5.57k
            WORD32 max_idx = ctr;
1399
5.57k
            recon_pic_buf_t *ps_temp;
1400
5.57k
            WORD32 i;
1401
1402
16.1k
            for(i = (ctr + 1); i < num_ref_pics_list0; i++)
1403
10.6k
            {
1404
                /* check for poc greater than current ref poc */
1405
10.6k
                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
10.6k
            }
1410
1411
            /* if max of remaining is not current, swap the pointers */
1412
5.57k
            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
5.57k
        }
1419
2.13k
    }
1420
1421
    /* sort the reference pics in List1 in ascending order POC */
1422
2.93k
    if(num_ref_pics_list1 > 1)
1423
15
    {
1424
        /* run a loop for num ref pics -1 */
1425
30
        for(ctr = 0; ctr < num_ref_pics_list1 - 1; ctr++)
1426
15
        {
1427
15
            WORD32 min_idx = ctr;
1428
15
            recon_pic_buf_t *ps_temp;
1429
15
            WORD32 i;
1430
1431
30
            for(i = (ctr + 1); i < num_ref_pics_list1; i++)
1432
15
            {
1433
                /* check for p[oc less than current ref poc */
1434
15
                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
15
            }
1439
1440
            /* if min of remaining is not current, swap the pointers */
1441
15
            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
15
        }
1448
15
    }
1449
1450
    /* popluate the slice header parameters to signal delta POCs and use flags */
1451
2.93k
    {
1452
2.93k
        WORD32 i;
1453
2.93k
        WORD32 prev_poc = curr_poc;
1454
1455
2.93k
        ps_slice_header->s_stref_picset.i1_inter_ref_pic_set_prediction_flag = 0;
1456
1457
2.93k
        ps_slice_header->s_stref_picset.i1_num_neg_pics = num_ref_pics_list0;
1458
1459
2.93k
        ps_slice_header->s_stref_picset.i1_num_pos_pics = num_ref_pics_list1;
1460
1461
2.93k
        ps_slice_header->s_stref_picset.i1_num_ref_idc = -1;
1462
1463
        /* populate the delta POCs of reference pics */
1464
2.93k
        i = 0;
1465
1466
10.9k
        for(ctr = 0; ctr < i4_num_rpics_l0_excl_dup; ctr++)
1467
8.05k
        {
1468
8.05k
            WORD32 ref_poc_l0 = aps_ref_list[LIST_0][i]->i4_poc;
1469
1470
8.05k
            ps_slice_header->s_stref_picset.ai2_delta_poc[ctr] = prev_poc - ref_poc_l0;
1471
8.05k
            ps_slice_header->s_stref_picset.ai1_used[ctr] =
1472
8.05k
                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
8.05k
            if(1 == ps_slice_header->s_stref_picset.ai1_used[ctr])
1476
8.05k
            {
1477
                /* check for CRA poc related use flag signalling */
1478
8.05k
                ps_slice_header->s_stref_picset.ai1_used[ctr] =
1479
8.05k
                    (curr_poc > cra_poc) ? (ref_poc_l0 >= cra_poc) : (slice_type != ISLICE);
1480
8.05k
            }
1481
8.05k
            if(!(prev_poc - ref_poc_l0))
1482
0
            {
1483
0
                ctr -= 1;
1484
0
                i4_num_rpics_l0_excl_dup -= 1;
1485
0
            }
1486
8.05k
            prev_poc = ref_poc_l0;
1487
1488
8.05k
            i++;
1489
8.05k
        }
1490
1491
2.93k
        i = 0;
1492
2.93k
        prev_poc = curr_poc;
1493
2.99k
        for(; ctr < (i4_num_rpics_l0_excl_dup + i4_num_rpics_l1_excl_dup); ctr++)
1494
58
        {
1495
58
            WORD32 ref_poc_l1 = aps_ref_list[LIST_1][i]->i4_poc;
1496
1497
58
            ps_slice_header->s_stref_picset.ai2_delta_poc[ctr] = ref_poc_l1 - prev_poc;
1498
1499
58
            ps_slice_header->s_stref_picset.ai1_used[ctr] =
1500
58
                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
58
            if(1 == ps_slice_header->s_stref_picset.ai1_used[ctr])
1504
58
            {
1505
                /* check for CRA poc related use flag signalling */
1506
58
                ps_slice_header->s_stref_picset.ai1_used[ctr] =
1507
58
                    (curr_poc > cra_poc) ? (ref_poc_l1 >= cra_poc) : (slice_type != ISLICE);
1508
                /* (slice_type != ISLICE); */
1509
58
            }
1510
58
            if(!(ref_poc_l1 - prev_poc))
1511
0
            {
1512
0
                ctr -= 1;
1513
0
                i4_num_rpics_l1_excl_dup -= 1;
1514
0
            }
1515
58
            prev_poc = ref_poc_l1;
1516
58
            i++;
1517
58
        }
1518
2.93k
        ps_slice_header->s_stref_picset.i1_num_neg_pics = i4_num_rpics_l0_excl_dup;
1519
1520
2.93k
        ps_slice_header->s_stref_picset.i1_num_pos_pics = i4_num_rpics_l1_excl_dup;
1521
1522
2.93k
        if(IV_IDR_FRAME == ps_curr_inp->s_lap_out.i4_pic_type)
1523
450
        {
1524
450
            ps_slice_header->s_stref_picset.i1_num_neg_pics = 0;
1525
450
            ps_slice_header->s_stref_picset.i1_num_pos_pics = 0;
1526
450
        }
1527
1528
        /* not used so set to -1 */
1529
2.93k
        memset(&ps_slice_header->s_stref_picset.ai1_ref_idc[0], -1, MAX_DPB_SIZE);
1530
2.93k
    }
1531
    /* call the ME API to update the DPB of HME pyramids
1532
    Upadate list for reference bit-rate only */
1533
2.93k
    if(0 == i4_bridx)
1534
2.93k
    {
1535
2.93k
        ihevce_me_frame_dpb_update(
1536
2.93k
            ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
1537
2.93k
            num_ref_pics_list0,
1538
2.93k
            num_ref_pics_list1,
1539
2.93k
            &aps_ref_list[LIST_0][0],
1540
2.93k
            &aps_ref_list[LIST_1][0],
1541
2.93k
            i4_thrd_id);
1542
2.93k
    }
1543
1544
    /* Default list creation based on uses as ref pic for current pic flag */
1545
2.93k
    {
1546
2.93k
        WORD32 num_ref_pics_list_final = 0;
1547
2.93k
        WORD32 list_idx = 0;
1548
1549
        /* LIST 0 */
1550
        /* run a loop for num ref pics in list 0 */
1551
10.9k
        for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
1552
8.05k
        {
1553
            /* check for used as reference flag */
1554
8.05k
            if(1 == aps_ref_list[LIST_0][ctr]->i4_used_by_cur_pic_flag)
1555
8.05k
            {
1556
                /* copy the pointer to the actual valid list idx */
1557
8.05k
                aps_ref_list[LIST_0][list_idx] = aps_ref_list[LIST_0][ctr];
1558
1559
                /* increment the valid pic counters and idx */
1560
8.05k
                list_idx++;
1561
8.05k
                num_ref_pics_list_final++;
1562
8.05k
            }
1563
8.05k
        }
1564
1565
        /* finally store the number of pictures in List0 */
1566
2.93k
        num_ref_pics_list0 = num_ref_pics_list_final;
1567
1568
        /* LIST 1 */
1569
2.93k
        num_ref_pics_list_final = 0;
1570
2.93k
        list_idx = 0;
1571
1572
        /* run a loop for num ref pics in list 1 */
1573
2.99k
        for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
1574
58
        {
1575
            /* check for used as reference flag */
1576
58
            if(1 == aps_ref_list[LIST_1][ctr]->i4_used_by_cur_pic_flag)
1577
58
            {
1578
                /* copy the pointer to the actual valid list idx */
1579
58
                aps_ref_list[LIST_1][list_idx] = aps_ref_list[LIST_1][ctr];
1580
1581
                /* increment the valid pic counters and idx */
1582
58
                list_idx++;
1583
58
                num_ref_pics_list_final++;
1584
58
            }
1585
58
        }
1586
1587
        /* finally store the number of pictures in List1 */
1588
2.93k
        num_ref_pics_list1 = num_ref_pics_list_final;
1589
2.93k
    }
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.93k
    if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1593
2.31k
    {
1594
2.31k
        if(num_ref_pics_list0 > 2)
1595
1.73k
        {
1596
1.73k
            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.73k
        }
1601
2.31k
    }
1602
626
    else
1603
626
    {
1604
626
        if(num_ref_pics_list0 >= 2 && num_ref_pics_list1 >= 2)
1605
5
        {
1606
5
            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
5
            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
5
        }
1616
626
    }
1617
    /* append the reference pics in List1 and end of list0 */
1618
2.99k
    for(ctr = 0; ctr < num_ref_pics_list1; ctr++)
1619
58
    {
1620
58
        aps_ref_list[LIST_0][num_ref_pics_list0 + ctr] = aps_ref_list[LIST_1][ctr];
1621
58
    }
1622
1623
    /* append the reference pics in List0 and end of list1 */
1624
10.9k
    for(ctr = 0; ctr < num_ref_pics_list0; ctr++)
1625
8.05k
    {
1626
8.05k
        aps_ref_list[LIST_1][num_ref_pics_list1 + ctr] = aps_ref_list[LIST_0][ctr];
1627
8.05k
    }
1628
1629
    /* reference list modification for adding duplicate reference */
1630
2.93k
    {
1631
2.93k
        WORD32 i4_latest_idx = 0;
1632
2.93k
        recon_pic_buf_t *ps_ref_list_cur;
1633
2.93k
        recon_pic_buf_t *ps_ref_list_prev;
1634
        /*List 0*/
1635
2.93k
        ps_ref_list_cur = aps_ref_list[LIST_0][0];
1636
2.93k
        ps_ref_list_prev = ps_ref_list_cur;
1637
11.0k
        for(ctr = 0; ctr < (num_ref_pics_list0 + num_ref_pics_list1); ctr++)
1638
8.11k
        {
1639
8.11k
            if(ps_ref_list_cur->i4_poc != ps_ref_list_prev->i4_poc)
1640
5.63k
            {
1641
5.63k
                i4_latest_idx++;
1642
5.63k
            }
1643
8.11k
            ps_ref_list_prev = ps_ref_list_cur;
1644
8.11k
            ps_slice_header->s_rplm.i4_ref_poc_l0[ctr] = ps_ref_list_cur->i4_poc;
1645
8.11k
            ps_slice_header->s_rplm.i1_list_entry_l0[ctr] = i4_latest_idx;
1646
8.11k
            if((ctr + 1) < (num_ref_pics_list0 + num_ref_pics_list1))
1647
5.63k
            {
1648
5.63k
                ps_ref_list_cur = aps_ref_list[LIST_0][ctr + 1];
1649
5.63k
            }
1650
8.11k
        } /*end for*/
1651
1652
        /*LIST 1*/
1653
2.93k
        i4_latest_idx = 0;
1654
2.93k
        ps_ref_list_cur = aps_ref_list[LIST_1][0];
1655
2.93k
        ps_ref_list_prev = ps_ref_list_cur;
1656
11.0k
        for(ctr = 0; ctr < (num_ref_pics_list0 + num_ref_pics_list1); ctr++)
1657
8.11k
        {
1658
8.11k
            if(ps_ref_list_cur->i4_poc != ps_ref_list_prev->i4_poc)
1659
5.63k
            {
1660
5.63k
                i4_latest_idx++;
1661
5.63k
            }
1662
8.11k
            ps_ref_list_prev = ps_ref_list_cur;
1663
8.11k
            ps_slice_header->s_rplm.i4_ref_poc_l1[ctr] = ps_ref_list_cur->i4_poc;
1664
8.11k
            ps_slice_header->s_rplm.i1_list_entry_l1[ctr] = i4_latest_idx;
1665
8.11k
            if((ctr + 1) < (num_ref_pics_list0 + num_ref_pics_list1))
1666
5.63k
            {
1667
5.63k
                ps_ref_list_cur = aps_ref_list[LIST_1][ctr + 1];
1668
5.63k
            }
1669
8.11k
        } /*end for*/
1670
2.93k
    }
1671
1672
    /* set number of active references used for l0 and l1 in slice hdr */
1673
2.93k
    ps_slice_header->i1_num_ref_idx_active_override_flag = 1;
1674
2.93k
    ps_slice_header->i1_num_ref_idx_l0_active = num_ref_pics_list0 + num_ref_pics_list1;
1675
2.93k
    if(BSLICE == slice_type)
1676
43
    {
1677
        /* i1_num_ref_idx_l1_active applicable only for B pics */
1678
43
        ps_slice_header->i1_num_ref_idx_l1_active = num_ref_pics_list0 + num_ref_pics_list1;
1679
43
    }
1680
    /* popluate the slice header parameters with weights and offsets */
1681
2.93k
    {
1682
2.93k
        WORD32 i;
1683
1684
        /* populate the log 2 weight denom if weighted prediction is enabled */
1685
2.93k
        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
11.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
1695
8.11k
        {
1696
            /* populate the weights and offsets if weighted prediction is enabled */
1697
8.11k
            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
8.11k
        }
1765
1766
11.0k
        for(i = 0; i < (num_ref_pics_list0 + num_ref_pics_list1); i++)
1767
8.11k
        {
1768
            /* populate the weights and offsets if weighted prediction is enabled */
1769
8.11k
            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
8.11k
        }
1837
2.93k
    }
1838
1839
    /* store the number of reference pics in the list for ME/MC etc */
1840
2.93k
    ps_enc_ctxt->i4_num_ref_l0 = num_ref_pics_list0;
1841
2.93k
    ps_enc_ctxt->i4_num_ref_l1 = num_ref_pics_list1;
1842
1843
2.93k
#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.93k
#if MULTI_REF_ENABLE == 1
1849
2.93k
    if(ps_curr_inp->s_lap_out.i4_quality_preset >= IHEVCE_QUALITY_P3)
1850
2.03k
    {
1851
2.03k
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1852
1.69k
        {
1853
1.69k
            if(ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6)
1854
330
            {
1855
330
                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
330
                else
1861
330
                {
1862
330
                    ps_enc_ctxt->i4_num_ref_l0_active =
1863
330
                        MIN(MAX_NUM_REFS_IN_PPICS_IN_XS25, num_ref_pics_list0);
1864
1865
330
                    ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1866
330
                }
1867
330
            }
1868
1.36k
            else
1869
1.36k
            {
1870
1.36k
                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.36k
                else
1875
1.36k
                {
1876
1.36k
                    ps_enc_ctxt->i4_num_ref_l0_active = MIN(2, num_ref_pics_list0);
1877
1.36k
                    ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1878
1.36k
                }
1879
1.36k
            }
1880
1881
1.69k
            ps_enc_ctxt->i4_num_ref_l1_active = 0;
1882
1.69k
        }
1883
335
        else
1884
335
        {
1885
335
            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
335
            else
1892
335
            {
1893
335
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(1, num_ref_pics_list0);
1894
335
                ps_enc_ctxt->i4_num_ref_l1_active = MIN(1, num_ref_pics_list1);
1895
1896
335
                ps_enc_ctxt->i4_num_ref_l1_active += i4_inc_L1_active_ref_pic;
1897
335
                ps_enc_ctxt->i4_num_ref_l0_active += i4_inc_L0_active_ref_pic;
1898
335
            }
1899
335
        }
1900
2.03k
    }
1901
904
    else
1902
904
    {
1903
904
        if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
1904
613
        {
1905
613
            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
613
            else
1908
613
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1909
1910
613
            ps_enc_ctxt->i4_num_ref_l1_active = 0;
1911
613
        }
1912
291
        else
1913
291
        {
1914
291
            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
291
            else
1920
291
            {
1921
291
                ps_enc_ctxt->i4_num_ref_l0_active = MIN(4, num_ref_pics_list0);
1922
291
                ps_enc_ctxt->i4_num_ref_l1_active = MIN(4, num_ref_pics_list1);
1923
291
            }
1924
291
        }
1925
904
    }
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.93k
#endif
1952
1953
2.93k
    ps_slice_header->i1_num_ref_idx_l0_active = MAX(1, ps_enc_ctxt->i4_num_ref_l0_active);
1954
2.93k
    if(BSLICE == slice_type)
1955
43
    {
1956
        /* i1_num_ref_idx_l1_active applicable only for B pics */
1957
43
        ps_slice_header->i1_num_ref_idx_l1_active = MAX(1, ps_enc_ctxt->i4_num_ref_l1_active);
1958
43
    }
1959
2.93k
    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.93k
    return;
1977
2.93k
}
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.9k
{
2011
10.9k
    double lambda_modifier = CONST_LAMDA_MOD_VAL;
2012
10.9k
    double lambda_uv_modifier = CONST_LAMDA_MOD_VAL;
2013
10.9k
    double lambda = 0;
2014
10.9k
    double lambda_uv;
2015
10.9k
    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.9k
    WORD32 num_b_frms =
2021
10.9k
        (1 << ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_max_temporal_layers) - 1;
2022
10.9k
    WORD32 chroma_qp = (ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format == IV_YUV_422SP_UV)
2023
10.9k
                           ? MIN(i4_cur_frame_qp, 51)
2024
10.9k
                           : gai1_ihevc_chroma_qp_scale[i4_cur_frame_qp + MAX_QP_BD_OFFSET];
2025
2026
10.9k
    WORD32 i4_qp_bdoffset =
2027
10.9k
        6 * (ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8);
2028
10.9k
    WORD32 slice_type = ps_cur_pic_ctxt->s_slice_hdr.i1_slice_type;
2029
2030
10.9k
    (void)first_field;
2031
10.9k
    (void)i4_is_ref_pic;
2032
10.9k
    (void)i4_temporal_lyr_id;
2033
10.9k
    i4_use_const_lamda_modifier = USE_CONSTANT_LAMBDA_MODIFIER;
2034
10.9k
    i4_use_const_lamda_modifier = i4_use_const_lamda_modifier ||
2035
10.9k
                                  ((ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet &
2036
10.9k
                                    (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.9k
    if(ISLICE == slice_type)
2048
2.22k
    {
2049
2.22k
        double temporal_correction_islice = 1.0 - 0.05 * num_b_frms;
2050
2.22k
        temporal_correction_islice = MAX(0.5, temporal_correction_islice);
2051
2052
2.22k
        lambda_modifier = 0.57 * temporal_correction_islice;
2053
2.22k
        lambda_uv_modifier = lambda_modifier;
2054
2.22k
        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.22k
        else
2060
2.22k
        {
2061
2.22k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2062
2.22k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2063
2.22k
        }
2064
2.22k
    }
2065
8.75k
    else if(PSLICE == slice_type)
2066
8.57k
    {
2067
8.57k
        if(first_field)
2068
7.06k
            lambda_modifier = 0.442;  //0.442*0.8;
2069
1.51k
        else
2070
1.51k
            lambda_modifier = 0.442;
2071
8.57k
        lambda_uv_modifier = lambda_modifier;
2072
8.57k
        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.57k
        else
2078
8.57k
        {
2079
8.57k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2080
8.57k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2081
8.57k
        }
2082
8.57k
    }
2083
185
    else
2084
185
    {
2085
        /* BSLICE */
2086
185
        if(1 == i4_is_ref_pic)
2087
61
        {
2088
61
            lambda_modifier = 0.3536;
2089
61
        }
2090
124
        else if(2 == i4_is_ref_pic)
2091
0
        {
2092
0
            lambda_modifier = 0.45;
2093
0
        }
2094
124
        else
2095
124
        {
2096
124
            lambda_modifier = 0.68;
2097
124
        }
2098
185
        lambda_uv_modifier = lambda_modifier;
2099
185
        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
185
        else
2105
185
        {
2106
185
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_modifier = lambda_modifier;
2107
185
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].lambda_uv_modifier = lambda_uv_modifier;
2108
185
        }
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
185
        {
2112
            /* modify b lambda further based on temporal id */
2113
185
            if(i4_temporal_lyr_id)
2114
184
            {
2115
184
                lambda_modifier *= CLIP3((((double)(i4_cur_frame_qp - 12)) / 6.0), 2.00, 4.00);
2116
184
                lambda_uv_modifier *= CLIP3((((double)(chroma_qp - 12)) / 6.0), 2.00, 4.00);
2117
184
            }
2118
185
        }
2119
185
    }
2120
10.9k
    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.9k
    switch(i4_lambda_type)
2135
10.9k
    {
2136
8.04k
    case 0:
2137
8.04k
    {
2138
8.04k
        i4_qp_bdoffset = 0;
2139
2140
8.04k
        lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2141
8.04k
        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
8.04k
        lambda *= lambda_modifier;
2145
8.04k
        lambda_uv *= lambda_uv_modifier;
2146
2147
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2148
8.04k
            (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2149
2150
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2151
8.04k
            (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2152
2153
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2154
8.04k
            (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2155
2156
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2157
8.04k
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2158
8.04k
        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
8.04k
        else
2170
8.04k
        {
2171
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2172
8.04k
                (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2173
2174
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2175
8.04k
                (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2176
2177
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2178
8.04k
                (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2179
8.04k
        }
2180
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2181
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf;
2182
2183
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2184
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf;
2185
2186
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2187
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf;
2188
2189
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2190
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf;
2191
2192
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2193
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf;
2194
2195
8.04k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2196
8.04k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf;
2197
2198
8.04k
        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.93k
    case 2:
2263
2.93k
    {
2264
2.93k
        lambda = pow(2.0, (((double)(i4_cur_frame_qp + i4_qp_bdoffset - 12)) / 3.0));
2265
2.93k
        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.93k
        lambda *= lambda_modifier;
2269
2.93k
        lambda_uv *= lambda_uv_modifier;
2270
2271
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2272
2.93k
            (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2273
2274
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_qf =
2275
2.93k
            (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2276
2277
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_lambda_chroma_qf =
2278
2.93k
            (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2279
2280
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_lambda_qf =
2281
2.93k
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2282
2283
2.93k
        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.93k
        else
2295
2.93k
        {
2296
2.93k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_lambda_qf =
2297
2.93k
                (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2298
2299
2.93k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2300
2.93k
                (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2301
2302
2.93k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2303
2.93k
                (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2304
2.93k
        }
2305
        /* lambda corresponding to 8- bit, for metrics based on 8- bit ( Example 8bit SAD in encloop)*/
2306
2307
2.93k
        lambda = pow(2.0, (((double)(i4_cur_frame_qp - 12)) / 3.0));
2308
2.93k
        lambda_uv = pow(2.0, (((double)(chroma_qp - 12)) / 3.0));
2309
2310
        /* modify the base lambda according to lambda modifier */
2311
2.93k
        lambda *= lambda_modifier;
2312
2.93k
        lambda_uv *= lambda_uv_modifier;
2313
2314
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].u4_chroma_cost_weighing_factor =
2315
2.93k
            (UWORD32)((lambda / lambda_uv) * (1 << CHROMA_COST_WEIGHING_FACTOR_Q_SHIFT));
2316
2317
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_qf =
2318
2.93k
            (LWORD64)(lambda * (1 << LAMBDA_Q_SHIFT));
2319
2320
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i8_cl_ssd_type2_lambda_chroma_qf =
2321
2.93k
            (LWORD64)(lambda_uv * (1 << LAMBDA_Q_SHIFT));
2322
2323
2.93k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_sad_type2_lambda_qf =
2324
2.93k
            (WORD32)(sqrt(lambda) * (1 << LAMBDA_Q_SHIFT));
2325
2.93k
        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.93k
        else
2337
2.93k
        {
2338
2.93k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_sad_type2_lambda_qf =
2339
2.93k
                (WORD32)((sqrt(lambda) / 1.5) * (1 << LAMBDA_Q_SHIFT));
2340
2341
2.93k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_type2_lambda_qf =
2342
2.93k
                (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2343
2344
2.93k
            ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_type2_lambda_qf =
2345
2.93k
                (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2346
2.93k
        }
2347
2348
2.93k
        break;
2349
0
    }
2350
0
    default:
2351
0
    {
2352
        /* Intended to be a barren wasteland! */
2353
0
        ASSERT(0);
2354
0
    }
2355
10.9k
    }
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.9k
    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.9k
    else
2371
10.9k
    {
2372
10.9k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_cl_satd_lambda_qf =
2373
10.9k
            (WORD32)(sqrt(lambda * 1.5) * (1 << LAMBDA_Q_SHIFT));
2374
2375
10.9k
        ps_cur_pic_ctxt->as_lambda_prms[i4_inst_id].i4_ol_satd_lambda_qf =
2376
10.9k
            (WORD32)((sqrt(lambda * 1.5)) * (1 << (LAMBDA_Q_SHIFT)));
2377
10.9k
    }
2378
10.9k
}
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.93k
{
2408
2.93k
    WORD32 i4_l1_ht, i4_l1_wd;
2409
2.93k
    ihevce_ed_blk_t *ps_ed_4x4 = ps_curr_out->ps_layer1_buf;
2410
2.93k
    WORD32 best_satd_16x16;
2411
    //LWORD64 acc_satd = 0;
2412
2.93k
    LWORD64 acc_sad = 0; /*SAD accumulated to compare with coarse me sad*/
2413
2.93k
    WORD32 i4_tot_4x4block_l1_x, i4_tot_4x4block_l1_y;
2414
2.93k
    WORD32 i4_tot_ctb_l1_x, i4_tot_ctb_l1_y;
2415
2.93k
    WORD32 i;
2416
2.93k
    WORD32 i4_act_factor;
2417
2.93k
    UWORD8 u1_cu_possible_qp;
2418
2.93k
    WORD32 i4_q_scale_mod;
2419
2.93k
    LWORD64 i8_best_satd_16x16;
2420
2.93k
    LWORD64 i8_frame_satd_by_act_L1_accum;
2421
2.93k
    LWORD64 i8_frame_acc_sadt_L1, i8_frame_acc_sadt_L1_squared;
2422
2.93k
    WORD32 i4_new_frame_qp = 0, i4_qp_for_I_pic = 0;
2423
2.93k
    LWORD64 pre_intra_satd_act_evaluated = 0;
2424
2.93k
    ihevce_ed_ctb_l1_t *ps_ed_ctb_l1 = ps_curr_out->ps_ed_ctb_l1;
2425
2.93k
    WORD32 i4_j;
2426
2.93k
    double scale_factor_cmplx_change_detection;
2427
2.93k
    WORD32 i4_cmplx_change_detection_thrsh;
2428
2.93k
    long double ld_frame_avg_satd_L1;
2429
2430
2.93k
    if(i4_is_last_thread)
2431
2.93k
    {
2432
2.93k
        ihevce_decomp_pre_intra_master_ctxt_t *ps_master_ctxt =
2433
2.93k
            (ihevce_decomp_pre_intra_master_ctxt_t *)
2434
2.93k
                ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt;
2435
2.93k
        ihevce_decomp_pre_intra_ctxt_t *ps_ctxt = ps_master_ctxt->aps_decomp_pre_intra_thrd_ctxt[0];
2436
2437
2.93k
        i4_l1_wd = ps_ctxt->as_layers[1].i4_actual_wd;
2438
2.93k
        i4_l1_ht = ps_ctxt->as_layers[1].i4_actual_ht;
2439
2440
2.93k
        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2441
390
           (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.93k
        else
2446
2.93k
        {
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.93k
            i8_frame_acc_sadt_L1 = ihevce_decomp_pre_intra_get_frame_satd(
2450
2.93k
                ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt, &i4_l1_wd, &i4_l1_ht);
2451
2.93k
        }
2452
2453
2.93k
#if USE_SQRT_AVG_OF_SATD_SQR
2454
2.93k
        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2455
390
           (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.93k
        else
2460
2.93k
        {
2461
2.93k
            i8_frame_acc_sadt_L1_squared = ihevce_decomp_pre_intra_get_frame_satd_squared(
2462
2.93k
                ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt, &i4_l1_wd, &i4_l1_ht);
2463
2.93k
        }
2464
#else
2465
        i8_frame_acc_sadt_L1_squared = i8_frame_acc_sadt_L1;
2466
#endif
2467
2.93k
        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.93k
        else
2475
2.93k
        {
2476
2.93k
            scale_factor_cmplx_change_detection =
2477
2.93k
                (double)0.12 * ((640.0 * 384.0) / (i4_l1_wd * i4_l1_ht));
2478
2.93k
            i4_cmplx_change_detection_thrsh =
2479
2.93k
                (WORD32)(HME_HIGH_SAD_BLK_THRESH * (1 + scale_factor_cmplx_change_detection));
2480
2.93k
        }
2481
2.93k
        i4_tot_4x4block_l1_x =
2482
2.93k
            ((i4_l1_wd + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) /
2483
2.93k
            4;  //((i4_l1_wd + 31) & 0xFFFFFFE0)/4;//(i4_l1_wd + (i4_l1_wd % 32 )) / 4;
2484
2.93k
        i4_tot_4x4block_l1_y =
2485
2.93k
            ((i4_l1_ht + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) /
2486
2.93k
            4;  //((i4_l1_ht + 31) & 0xFFFFFFE0)/4;//(i4_l1_ht + (i4_l1_ht % 32 )) / 4;
2487
2.93k
        ld_frame_avg_satd_L1 =
2488
2.93k
            (WORD32)log(
2489
2.93k
                1 + (long double)i8_frame_acc_sadt_L1_squared /
2490
2.93k
                        ((long double)((i4_tot_4x4block_l1_x * i4_tot_4x4block_l1_y) >> 2))) /
2491
2.93k
            log(2.0);
2492
        /* L1 satd accumalated for computing qp */
2493
2.93k
        i8_frame_satd_by_act_L1_accum = 0;
2494
2.93k
        i4_tot_ctb_l1_x =
2495
2.93k
            ((i4_l1_wd + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) / (MAX_CTB_SIZE >> 1);
2496
2.93k
        i4_tot_ctb_l1_y =
2497
2.93k
            ((i4_l1_ht + ((MAX_CTB_SIZE >> 1) - 1)) & 0xFFFFFFE0) / (MAX_CTB_SIZE >> 1);
2498
2499
17.2k
        for(i = 0; i < (i4_tot_ctb_l1_x * i4_tot_ctb_l1_y); i += 1)
2500
14.3k
        {
2501
244k
            for(i4_j = 0; i4_j < 16; i4_j++)
2502
229k
            {
2503
229k
                if(ps_ed_ctb_l1->i4_best_satd_8x8[i4_j] != -1)
2504
198k
                {
2505
198k
                    ASSERT(ps_ed_ctb_l1->i4_best_satd_8x8[i4_j] >= 0);
2506
198k
                    ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
2507
2508
198k
                    if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2509
10.2k
                       (ps_curr_inp->s_lap_out.i4_temporal_lyr_id > TEMPORAL_LAYER_DISABLE))
2510
0
                    {
2511
0
                        best_satd_16x16 = 0;
2512
0
                    }
2513
198k
                    else
2514
198k
                    {
2515
198k
                        best_satd_16x16 = ps_ed_ctb_l1->i4_best_satd_8x8[i4_j];
2516
198k
                    }
2517
2518
198k
                    acc_sad += (WORD32)ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j];
2519
                    //acc_satd += (WORD32)best_satd_16x16;
2520
198k
                    u1_cu_possible_qp = ihevce_cu_level_qp_mod(
2521
198k
                        32,
2522
198k
                        best_satd_16x16,
2523
198k
                        ld_frame_avg_satd_L1,
2524
198k
                        REF_MOD_STRENGTH,  // To be changed later
2525
198k
                        &i4_act_factor,
2526
198k
                        &i4_q_scale_mod,
2527
198k
                        &ps_enc_ctxt->s_rc_quant);
2528
198k
                    i8_best_satd_16x16 = best_satd_16x16 << QP_LEVEL_MOD_ACT_FACTOR;
2529
2530
198k
                    if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2531
10.2k
                       (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
198k
                    if(0 != i4_act_factor)
2537
198k
                    {
2538
198k
                        i8_frame_satd_by_act_L1_accum +=
2539
198k
                            ((WORD32)(i8_best_satd_16x16 / i4_act_factor));
2540
                        /*Accumulate SAD for those regions which will undergo evaluation in L0 stage*/
2541
198k
                        if(ps_ed_4x4->intra_or_inter != 2)
2542
188k
                            pre_intra_satd_act_evaluated +=
2543
188k
                                ((WORD32)(i8_best_satd_16x16 / i4_act_factor));
2544
198k
                    }
2545
198k
                }
2546
229k
                ps_ed_4x4 += 4;
2547
229k
            }
2548
14.3k
            ps_ed_ctb_l1 += 1;
2549
14.3k
        }
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.93k
        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
2553
390
           (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.93k
        else
2560
2.93k
        {
2561
2.93k
            ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum = i8_frame_satd_by_act_L1_accum;
2562
2.93k
            ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated =
2563
2.93k
                pre_intra_satd_act_evaluated;
2564
2.93k
        }
2565
2566
2.93k
        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.93k
        ps_curr_inp->s_rc_lap_out.i8_raw_pre_intra_sad = acc_sad;
2569
2.93k
    }
2570
    /*update pre-enc qp using data from L1 to use better qp in L0 in case of cbr mode*/
2571
2.93k
    if(i4_is_last_thread)
2572
2.93k
    {
2573
        /* acquire mutex lock for rate control calls */
2574
2.93k
        osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2575
2.93k
        {
2576
2.93k
            LWORD64 i8_est_L0_satd_by_act;
2577
2.93k
            WORD32 i4_cur_q_scale;
2578
2.93k
            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
965
            else
2590
965
                i4_cur_q_scale =
2591
965
                    ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
2592
965
                        [ps_curr_out->i4_curr_frm_qp + ps_enc_ctxt->s_rc_quant.i1_qp_offset];
2593
2594
2.93k
            i4_cur_q_scale = (i4_cur_q_scale + (1 << (QSCALE_Q_FAC_3 - 1))) >> QSCALE_Q_FAC_3;
2595
2596
2.93k
            i8_est_L0_satd_by_act = ihevce_get_L0_satd_based_on_L1(
2597
2.93k
                i8_frame_satd_by_act_L1_accum,
2598
2.93k
                ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered,
2599
2.93k
                i4_cur_q_scale);
2600
            /*HEVC_RC query rate control for qp*/
2601
2.93k
            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
965
            else
2610
965
                i4_new_frame_qp = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms
2611
965
                                      .as_tgt_params[ps_enc_ctxt->i4_resolution_id]
2612
965
                                      .ai4_frame_qp[0];
2613
2.93k
            i4_new_frame_qp = CLIP3(i4_new_frame_qp, 1, 51);
2614
2.93k
            i4_qp_for_I_pic = CLIP3(i4_qp_for_I_pic, 1, 51);
2615
2.93k
            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.93k
            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.93k
            if(ps_curr_inp->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
2621
2.48k
               ps_curr_inp->s_lap_out.i4_pic_type != IV_I_FRAME)
2622
2.35k
            {
2623
2.35k
                i4_new_frame_qp += ps_curr_inp->s_lap_out.i4_temporal_lyr_id + 1;
2624
2.35k
            }
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.93k
            if(ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME ||
2640
2.80k
               ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME)
2641
583
            {
2642
583
                i4_new_frame_qp = i4_new_frame_qp - 3;
2643
583
            }
2644
2.35k
            else if(ps_curr_inp->s_lap_out.i4_pic_type == IV_P_FRAME)
2645
2.31k
            {
2646
2.31k
                i4_new_frame_qp = i4_new_frame_qp - 2;
2647
2.31k
            }
2648
2.93k
            if(ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2649
43
               ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 1)
2650
15
            {
2651
15
                i4_new_frame_qp = i4_new_frame_qp + 2;
2652
15
            }
2653
2.92k
            else if(
2654
2.92k
                ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME &&
2655
28
                ps_curr_inp->s_lap_out.i4_temporal_lyr_id == 2)
2656
28
            {
2657
28
                i4_new_frame_qp = i4_new_frame_qp + 6;
2658
28
            }
2659
2.89k
            else if(
2660
2.89k
                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.93k
            i4_new_frame_qp = CLIP3(i4_new_frame_qp, 1, 51);
2667
2.93k
            i4_qp_for_I_pic = CLIP3(i4_qp_for_I_pic, 1, 51);
2668
2669
2.93k
            {
2670
2.93k
                calc_l1_level_hme_intra_sad_different_qp(
2671
2.93k
                    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.93k
                ihevce_rc_register_L1_analysis_data(
2676
2.93k
                    ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
2677
2.93k
                    &ps_curr_inp->s_rc_lap_out,
2678
2.93k
                    i8_est_L0_satd_by_act,
2679
2.93k
                    ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad
2680
2.93k
                        [i4_new_frame_qp],  //since the sad passed will be used to calc complexity it should be non coded sad subtracted sad
2681
2.93k
                    ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_new_frame_qp]);
2682
2683
2.93k
                ihevce_coarse_me_get_rc_param(
2684
2.93k
                    ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
2685
2.93k
                    &ps_curr_out->i8_acc_frame_coarse_me_cost,
2686
2.93k
                    &ps_curr_out->i8_acc_frame_coarse_me_sad,
2687
2.93k
                    &ps_curr_out->i8_acc_num_blks_high_sad,
2688
2.93k
                    &ps_curr_out->i8_total_blks,
2689
2.93k
                    ps_curr_inp->s_lap_out.i4_is_prev_pic_in_Tid0_same_scene);
2690
2691
2.93k
                if(ps_curr_out->i8_total_blks)
2692
2.31k
                {
2693
2.31k
                    ps_curr_out->i4_complexity_percentage = (WORD32)(
2694
2.31k
                        (ps_curr_out->i8_acc_num_blks_high_sad * 100) /
2695
2.31k
                        (ps_curr_out->i8_total_blks));
2696
2.31k
                }
2697
                /*not for Const QP mode*/
2698
2.93k
                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.51k
                       (((float)(ps_curr_out->i8_acc_num_blks_high_sad * 100) /
2703
1.51k
                         (ps_curr_out->i8_total_blks)) > (i4_cmplx_change_detection_thrsh)))
2704
14
                    {
2705
14
                        ps_curr_out->i4_is_high_complex_region = 1;
2706
14
                    }
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.93k
                ps_curr_inp->s_rc_lap_out.i8_frame_acc_coarse_me_cost =
2713
2.93k
                    ps_curr_out->i8_acc_frame_coarse_me_cost;
2714
                /*check for I only reset case and Non I SCD*/
2715
2.93k
                ihevce_rc_check_non_lap_scd(
2716
2.93k
                    ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0], &ps_curr_inp->s_rc_lap_out);
2717
2.93k
            }
2718
2.93k
        }
2719
        /* release mutex lock after rate control calls */
2720
2.93k
        osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2721
2.93k
    }
2722
2.93k
}
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
3.13k
{
2749
3.13k
    ihevce_lap_enc_buf_t *ps_curr_inp;
2750
3.13k
    WORD32 first_field = 1;
2751
3.13k
    me_master_ctxt_t *ps_master_ctxt;
2752
2753
3.13k
    (void)i4_thrd_id;
2754
3.13k
    (void)ps_cur_out_me_prms;
2755
3.13k
    ps_curr_inp = ps_curr_inp_prms->ps_curr_inp;
2756
2757
3.13k
    ps_master_ctxt = (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
2758
2759
    /* get frame level lambda params */
2760
3.13k
    ihevce_get_frame_lambda_prms(
2761
3.13k
        ps_enc_ctxt,
2762
3.13k
        ps_curr_inp_prms,
2763
3.13k
        i4_cur_frame_qp,
2764
3.13k
        first_field,
2765
3.13k
        ps_curr_inp->s_lap_out.i4_is_ref_pic,
2766
3.13k
        ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
2767
3.13k
        ps_curr_inp->s_lap_out.f_i_pic_lamda_modifier,
2768
3.13k
        0,
2769
3.13k
        ENC_LAMBDA_TYPE);
2770
2771
3.13k
    if(1 == ps_curr_inp_prms->i4_frm_proc_valid_flag)
2772
2.93k
    {
2773
2.93k
        UWORD8 i1_cu_qp_delta_enabled_flag =
2774
2.93k
            ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_cu_level_rc;
2775
2776
        /* picture level init of ME */
2777
2.93k
        ihevce_me_frame_init(
2778
2.93k
            ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
2779
2.93k
            ps_cur_out_me_prms,
2780
2.93k
            ps_enc_ctxt->ps_stat_prms,
2781
2.93k
            &ps_enc_ctxt->s_frm_ctb_prms,
2782
2.93k
            &ps_curr_inp_prms->as_lambda_prms[0],
2783
2.93k
            ps_enc_ctxt->i4_num_ref_l0,
2784
2.93k
            ps_enc_ctxt->i4_num_ref_l1,
2785
2.93k
            ps_enc_ctxt->i4_num_ref_l0_active,
2786
2.93k
            ps_enc_ctxt->i4_num_ref_l1_active,
2787
2.93k
            &ps_cur_out_me_prms->aps_ref_list[0][LIST_0][0],
2788
2.93k
            &ps_cur_out_me_prms->aps_ref_list[0][LIST_1][0],
2789
2.93k
            ps_cur_out_me_prms->aps_ref_list[0],
2790
2.93k
            &ps_enc_ctxt->s_func_selector,
2791
2.93k
            ps_curr_inp,
2792
2.93k
            ps_curr_inp_prms->pv_me_lyr_ctxt,
2793
2.93k
            i4_me_frm_id,
2794
2.93k
            i4_thrd_id,
2795
2.93k
            i4_cur_frame_qp,
2796
2.93k
            ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
2797
2.93k
            i1_cu_qp_delta_enabled_flag,
2798
2.93k
            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.93k
        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.93k
        ihevce_dmgr_rst_row_row_sync(
2807
2.93k
            ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]->pv_dep_mngr_encloop_dep_me);
2808
2.93k
    }
2809
3.13k
}
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
195
{
2831
195
    rc_bits_sad_t s_rc_frame_stat;
2832
195
    WORD32 out_buf_id;
2833
195
    WORD32 i4_pic_type, k;
2834
195
    WORD32 cur_qp;
2835
195
    ihevce_lap_output_params_t s_lap_out;
2836
195
    rc_lap_out_params_t s_rc_lap_out;
2837
2838
390
    for(k = 0; k < i4_update_cnt; k++)  //ELP_RC
2839
195
    {
2840
195
        ihevce_rc_store_retrive_update_info(
2841
195
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i4_bit_rate_idx],
2842
195
            &s_rc_frame_stat,
2843
195
            i4_enc_frm_id_rc,
2844
195
            i4_bit_rate_idx,
2845
195
            2,
2846
195
            &out_buf_id,
2847
195
            &i4_pic_type,
2848
195
            &cur_qp,
2849
195
            (void *)&s_lap_out,
2850
195
            (void *)&s_rc_lap_out);
2851
2852
195
        ihevce_rc_update_pic_info(
2853
195
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i4_bit_rate_idx],
2854
195
            (s_rc_frame_stat.u4_total_texture_bits +
2855
195
             s_rc_frame_stat.u4_total_header_bits),  //pass total bits
2856
195
            s_rc_frame_stat.u4_total_header_bits,
2857
195
            s_rc_frame_stat.u4_total_sad,
2858
195
            s_rc_frame_stat.u4_total_intra_sad,
2859
195
            (IV_PICTURE_CODING_TYPE_T)i4_pic_type,
2860
195
            cur_qp,
2861
195
            0,
2862
195
            s_rc_frame_stat.i4_qp_normalized_8x8_cu_sum,
2863
195
            s_rc_frame_stat.i4_8x8_cu_sum,
2864
195
            s_rc_frame_stat.i8_sad_by_qscale,
2865
195
            &s_lap_out,
2866
195
            &s_rc_lap_out,
2867
195
            out_buf_id,
2868
195
            s_rc_frame_stat.u4_open_loop_intra_sad,
2869
195
            s_rc_frame_stat.i8_total_ssd_frame,
2870
195
            i4_enc_frm_id_rc);  //ps_curr_out->i4_inp_timestamp_low)
2871
195
        i4_enc_frm_id_rc++;
2872
195
        i4_enc_frm_id_rc = (i4_enc_frm_id_rc % ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
2873
195
    }
2874
195
}
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
195
{
2895
195
    frm_proc_thrd_ctxt_t *ps_thrd_ctxt;
2896
195
    enc_ctxt_t *ps_enc_ctxt;
2897
195
    WORD32 i4_me_end_flag, i4_enc_end_flag;
2898
195
    WORD32 i4_thrd_id;
2899
195
    ihevce_hle_ctxt_t *ps_hle_ctxt;
2900
195
    WORD32 i4_num_bitrates;  //number of bit-rates instances running
2901
195
    WORD32 i;  //ctr
2902
195
    void *pv_dep_mngr_prev_frame_me_done;
2903
195
    void *pv_dep_mngr_prev_frame_done;
2904
195
    WORD32 i4_resolution_id;
2905
195
    WORD32 i4_enc_frm_id_rc = 0;
2906
195
    WORD32 i4_enc_frm_id = 0;
2907
195
    WORD32 i4_me_frm_id = 0;
2908
2909
195
    ps_thrd_ctxt = (frm_proc_thrd_ctxt_t *)pv_frm_proc_thrd_ctxt;
2910
195
    ps_hle_ctxt = ps_thrd_ctxt->ps_hle_ctxt;
2911
195
    ps_enc_ctxt = (enc_ctxt_t *)ps_thrd_ctxt->pv_enc_ctxt; /*Changed for mres*/
2912
195
    i4_thrd_id = ps_thrd_ctxt->i4_thrd_id;
2913
195
    i4_me_end_flag = 0;
2914
195
    i4_enc_end_flag = 0;
2915
195
    i4_num_bitrates = ps_enc_ctxt->i4_num_bitrates;
2916
195
    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.32k
    while((0 == i4_me_end_flag) && (0 == i4_enc_end_flag))
2922
3.13k
    {
2923
3.13k
        WORD32 result;
2924
3.13k
        WORD32 ai4_in_buf_id[MAX_NUM_ME_PARALLEL];
2925
3.13k
        me_enc_rdopt_ctxt_t *ps_curr_out_me;
2926
2927
3.13k
        if(1 == ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel)
2928
3.13k
        {
2929
3.13k
            pv_dep_mngr_prev_frame_me_done =
2930
3.13k
                ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[0];
2931
3.13k
        }
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
3.13k
        {
2940
3.13k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_me_done, ps_thrd_ctxt->i4_thrd_id);
2941
3.13k
        }
2942
2943
        /****** Lock the critical section ******/
2944
3.13k
        if(NULL != ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id])
2945
3.13k
        {
2946
3.13k
            result = osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id]);
2947
2948
3.13k
            if(OSAL_SUCCESS != result)
2949
0
                return 0;
2950
3.13k
        }
2951
2952
3.13k
        {
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
3.13k
            if(ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] == 0)
2961
3.13k
            {
2962
3.13k
                WORD32 i4_ref_cur_qp;  //current frame Qp for reference bit-rate instance
2963
3.13k
                ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
2964
2965
3.13k
                if(0 == i4_me_end_flag)
2966
3.13k
                {
2967
                    /* ------- get the input prms buffer from pre encode que ------------ */
2968
3.13k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] =
2969
3.13k
                        (pre_enc_me_ctxt_t *)ihevce_q_get_filled_buff(
2970
3.13k
                            (void *)ps_enc_ctxt,
2971
3.13k
                            IHEVCE_PRE_ENC_ME_Q,
2972
3.13k
                            &ai4_in_buf_id[i4_me_frm_id],
2973
3.13k
                            BUFF_QUE_BLOCKING_MODE);
2974
                    /*always buffer must be available*/
2975
3.13k
                    ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] != NULL);
2976
2977
3.13k
                    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
3.13k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] =
2981
3.13k
                        (pre_enc_L0_ipe_encloop_ctxt_t *)ihevce_q_get_filled_buff(
2982
3.13k
                            (void *)ps_enc_ctxt,
2983
3.13k
                            IHEVCE_L0_IPE_ENC_Q,
2984
3.13k
                            &ps_enc_ctxt->s_multi_thrd.ai4_in_frm_l0_ipe_id[i4_me_frm_id],
2985
3.13k
                            BUFF_QUE_BLOCKING_MODE);
2986
2987
                    /*always buffer must be available*/
2988
3.13k
                    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
3.13k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] =
2992
3.13k
                        (me_enc_rdopt_ctxt_t *)ihevce_q_get_free_buff(
2993
3.13k
                            ps_enc_ctxt,
2994
3.13k
                            IHEVCE_ME_ENC_RDOPT_Q,
2995
3.13k
                            &ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id],
2996
3.13k
                            BUFF_QUE_BLOCKING_MODE);
2997
2998
                    /*always buffer must be available*/
2999
3.13k
                    ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] != NULL);
3000
3.13k
                }
3001
3.13k
                if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3002
3.13k
                   NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] &&
3003
3.13k
                   NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id])
3004
3.13k
                {
3005
3.13k
                    ps_curr_inp =
3006
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3007
3008
3.13k
                    ps_curr_out_me = ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id];
3009
3010
3.13k
                    ps_curr_out_me->ps_curr_inp_from_l0_ipe_prms =
3011
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id];
3012
3013
                    /*initialization of curr out me*/
3014
3.13k
                    ps_curr_out_me->ps_curr_inp_from_me_prms =
3015
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id];
3016
3017
3.13k
                    ps_curr_out_me->curr_inp_from_me_buf_id = ai4_in_buf_id[i4_me_frm_id];
3018
3019
3.13k
                    ps_curr_out_me->i4_buf_id =
3020
3.13k
                        ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id];
3021
3022
3.13k
                    ps_curr_out_me->ps_curr_inp =
3023
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3024
3025
3.13k
                    ps_curr_out_me->curr_inp_buf_id =
3026
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->curr_inp_buf_id;
3027
3028
3.13k
                    ps_curr_out_me->curr_inp_from_l0_ipe_buf_id =
3029
3.13k
                        ps_enc_ctxt->s_multi_thrd.ai4_in_frm_l0_ipe_id[i4_me_frm_id];
3030
3031
3.13k
                    ps_curr_out_me->i4_frm_proc_valid_flag =
3032
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3033
3.13k
                            ->i4_frm_proc_valid_flag;
3034
3035
3.13k
                    ps_curr_out_me->i4_end_flag =
3036
3.13k
                        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
3.13k
                    if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
3040
2.93k
                    {
3041
                        /* slice header will be populated in pre-enocde stage */
3042
2.93k
                        memcpy(
3043
2.93k
                            &ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]
3044
2.93k
                                 ->s_slice_hdr,
3045
2.93k
                            &ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3046
2.93k
                                 ->s_slice_hdr,
3047
2.93k
                            sizeof(slice_header_t));
3048
3049
2.93k
                        if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3050
2.93k
                               ->i4_frm_proc_valid_flag)
3051
2.93k
                        {
3052
2.93k
                            WORD32 ctr;
3053
2.93k
                            recon_pic_buf_t *ps_frm_recon;
3054
5.87k
                            for(i = 0; i < i4_num_bitrates; i++)
3055
2.93k
                            {
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.93k
                                {
3061
2.93k
                                    WORD32 i4_free_id;
3062
2.93k
                                    i4_free_id = ihevce_find_free_indx(
3063
2.93k
                                        ps_enc_ctxt->pps_recon_buf_q[i],
3064
2.93k
                                        ps_enc_ctxt->ai4_num_buf_recon_q[i]);
3065
3066
2.93k
                                    if(i4_free_id != -1)
3067
2.21k
                                    {
3068
2.21k
                                        ps_enc_ctxt->pps_recon_buf_q[i][i4_free_id]->i4_is_free = 1;
3069
2.21k
                                        ps_enc_ctxt->pps_recon_buf_q[i][i4_free_id]->i4_poc = -1;
3070
2.21k
                                    }
3071
2.93k
                                }
3072
3073
2.93k
                                ps_frm_recon = NULL;
3074
8.42k
                                for(ctr = 0; ctr < ps_enc_ctxt->ai4_num_buf_recon_q[i]; ctr++)
3075
8.42k
                                {
3076
8.42k
                                    if(ps_enc_ctxt->pps_recon_buf_q[i][ctr]->i4_is_free)
3077
2.93k
                                    {
3078
2.93k
                                        ps_frm_recon = ps_enc_ctxt->pps_recon_buf_q[i][ctr];
3079
2.93k
                                        break;
3080
2.93k
                                    }
3081
8.42k
                                }
3082
2.93k
                                ASSERT(ps_frm_recon != NULL);
3083
3084
2.93k
                                ps_frm_recon->i4_is_free = 0;
3085
2.93k
                                ps_frm_recon->i4_non_ref_free_flag = 0;
3086
2.93k
                                ps_frm_recon->i4_topfield_first =
3087
2.93k
                                    ps_curr_inp->s_input_buf.i4_topfield_first;
3088
2.93k
                                ps_frm_recon->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
3089
2.93k
                                ps_frm_recon->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
3090
2.93k
                                ps_frm_recon->i4_display_num =
3091
2.93k
                                    ps_curr_inp->s_lap_out.i4_display_num;
3092
2.93k
                                ps_frm_recon->i4_idr_gop_num =
3093
2.93k
                                    ps_curr_inp->s_lap_out.i4_idr_gop_num;
3094
2.93k
                                ps_frm_recon->i4_bottom_field =
3095
2.93k
                                    ps_curr_inp->s_input_buf.i4_bottom_field;
3096
2.93k
                                ps_frm_recon->i4_is_reference =
3097
2.93k
                                    ps_curr_inp->s_lap_out.i4_is_ref_pic;
3098
3099
2.93k
                                {
3100
2.93k
                                    WORD32 sei_hash_enabled;
3101
2.93k
#ifndef DISABLE_SEI
3102
2.93k
                                    sei_hash_enabled = (ps_enc_ctxt->ps_stat_prms->s_out_strm_prms
3103
2.93k
                                             .i4_sei_enable_flag == 1) &&
3104
808
                                        (ps_enc_ctxt->ps_stat_prms->s_out_strm_prms
3105
808
                                             .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.93k
                                    ps_frm_recon->i4_deblk_pad_hpel_cur_pic =
3112
2.93k
                                        ps_frm_recon->i4_is_reference ||
3113
28
                                        (ps_enc_ctxt->ps_stat_prms->i4_save_recon) ||
3114
28
                                        (1 == sei_hash_enabled);
3115
2.93k
                                }
3116
3117
2.93k
                                ps_frm_recon->s_yuv_buf_desc.i4_y_ht =
3118
2.93k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht;
3119
2.93k
                                ps_frm_recon->s_yuv_buf_desc.i4_uv_ht =
3120
2.93k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht >>
3121
2.93k
                                    ((ps_enc_ctxt->s_runtime_src_prms.i4_chr_format ==
3122
2.93k
                                      IV_YUV_422SP_UV)
3123
2.93k
                                         ? 0
3124
2.93k
                                         : 1);
3125
2.93k
                                ps_frm_recon->s_yuv_buf_desc.i4_y_wd =
3126
2.93k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd;
3127
2.93k
                                ps_frm_recon->s_yuv_buf_desc.i4_uv_wd =
3128
2.93k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd;
3129
2.93k
                                ps_frm_recon->s_yuv_buf_desc.i4_y_strd =
3130
2.93k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd +
3131
2.93k
                                    (PAD_HORZ << 1);
3132
2.93k
                                ps_frm_recon->s_yuv_buf_desc.i4_uv_strd =
3133
2.93k
                                    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd +
3134
2.93k
                                    (PAD_HORZ << 1);
3135
3136
                                /* reset the row_frm dep mngr for ME reverse sync for reference bitrate */
3137
2.93k
                                if(i == 0)
3138
2.93k
                                {
3139
2.93k
                                    ihevce_dmgr_map_rst_sync(ps_frm_recon->pv_dep_mngr_recon);
3140
2.93k
                                }
3141
3142
2.93k
                                ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i] =
3143
2.93k
                                    ps_frm_recon;
3144
2.93k
                            }
3145
2.93k
                        }
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.87k
                        for(i = i4_num_bitrates - 1; i >= 0; i--)
3150
2.93k
                        {
3151
2.93k
                            ihevce_manage_ref_pics(
3152
2.93k
                                ps_enc_ctxt,
3153
2.93k
                                ps_curr_inp,
3154
2.93k
                                &ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id]
3155
2.93k
                                     ->s_slice_hdr,
3156
2.93k
                                i4_me_frm_id,
3157
2.93k
                                i4_thrd_id,
3158
2.93k
                                i); /* bitrate instance ID */
3159
2.93k
                        }
3160
                        /*query of qp to be moved just before encoding starts*/
3161
2.93k
                        i4_ref_cur_qp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3162
2.93k
                                            ->i4_curr_frm_qp;
3163
                        /* The Qp populated in Pre enc stage needs to overwritten with Qp
3164
                        queried from rate control*/
3165
2.93k
                    }
3166
195
                    else
3167
195
                    {
3168
195
                        i4_ref_cur_qp = 0;
3169
195
                    }
3170
3171
                    /* call the core encoding loop */
3172
3.13k
                    ihevce_frame_init(
3173
3.13k
                        ps_enc_ctxt,
3174
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id],
3175
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id],
3176
3.13k
                        i4_ref_cur_qp,
3177
3.13k
                        i4_me_frm_id,
3178
3.13k
                        i4_thrd_id);
3179
3.13k
                }
3180
3181
3.13k
                ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_me_frm_id] = 1;
3182
3.13k
            }
3183
3.13k
        }
3184
3185
        /************************************/
3186
        /******  EXIT CRITICAL SECTION ******/
3187
        /************************************/
3188
3189
        /****** Unlock the critical section ******/
3190
3.13k
        if(NULL != ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id])
3191
3.13k
        {
3192
3.13k
            result = osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i4_me_frm_id]);
3193
3.13k
            if(OSAL_SUCCESS != result)
3194
0
                return 0;
3195
3.13k
        }
3196
3197
3.13k
        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
3.13k
        i4_me_end_flag = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_end_flag;
3207
3.13k
        if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3208
3.13k
           NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] &&
3209
3.13k
           NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id])
3210
3.13k
        {
3211
3.13k
            pre_enc_me_ctxt_t *ps_curr_inp_prms;
3212
3.13k
            pre_enc_L0_ipe_encloop_ctxt_t *ps_curr_L0_IPE_inp_prms;
3213
3.13k
            ihevce_lap_enc_buf_t *ps_curr_inp;
3214
3215
            /* get the current  buffer pointer  */
3216
3.13k
            ps_curr_inp_prms = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id];
3217
3.13k
            ps_curr_L0_IPE_inp_prms =
3218
3.13k
                ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id];
3219
3.13k
            ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->ps_curr_inp;
3220
3.13k
            if(i4_thrd_id == 0)
3221
3.13k
            {
3222
3.13k
                PROFILE_START(&ps_hle_ctxt->profile_enc_me[ps_enc_ctxt->i4_resolution_id]);
3223
3.13k
            }
3224
3225
            /* -------------------------------------------------- */
3226
            /*    Motion estimation (enc layer) of entire frame   */
3227
            /* -------------------------------------------------- */
3228
3.13k
            if((i4_me_end_flag == 0) &&
3229
2.93k
               (1 ==
3230
2.93k
                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]->i4_frm_proc_valid_flag))
3231
2.93k
            {
3232
                /* Init i4_is_prev_frame_reference for the next P-frame */
3233
2.93k
                me_master_ctxt_t *ps_master_ctxt =
3234
2.93k
                    (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3235
3236
                /* get the current thread ctxt pointer */
3237
2.93k
                me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3238
3239
2.93k
                me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3240
3241
2.93k
                if(ISLICE != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3242
2.93k
                                 ->s_slice_hdr.i1_slice_type)
3243
2.35k
                {
3244
2.35k
                    ihevce_me_process(
3245
2.35k
                        ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
3246
2.35k
                        ps_curr_inp,
3247
2.35k
                        ps_curr_inp_prms->ps_ctb_analyse,
3248
2.35k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id],
3249
2.35k
                        ps_curr_inp_prms->plf_intra_8x8_cost,
3250
2.35k
                        ps_curr_L0_IPE_inp_prms->ps_ipe_analyse_ctb,
3251
2.35k
                        ps_curr_L0_IPE_inp_prms,
3252
2.35k
                        ps_curr_inp_prms->pv_me_lyr_ctxt,
3253
2.35k
                        &ps_enc_ctxt->s_multi_thrd,
3254
2.35k
                        ((ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel == 1) ? 0 : 1),
3255
2.35k
                        i4_thrd_id,
3256
2.35k
                        i4_me_frm_id);
3257
2.35k
                }
3258
583
                else
3259
583
                {
3260
                    /* Init i4_is_prev_frame_reference for the next P-frame */
3261
583
                    me_master_ctxt_t *ps_master_ctxt =
3262
583
                        (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3263
3264
                    /* get the current thread ctxt pointer */
3265
583
                    me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3266
3267
583
                    me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3268
3269
583
                    multi_thrd_ctxt_t *ps_multi_thrd_ctxt = &ps_enc_ctxt->s_multi_thrd;
3270
3271
583
                    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
583
                    else
3276
583
                    {
3277
583
                        ps_frm_ctxt->i4_is_prev_frame_reference =
3278
583
                            ps_multi_thrd_ctxt->aps_cur_inp_me_prms[i4_me_frm_id]
3279
583
                                ->ps_curr_inp->s_lap_out.i4_is_ref_pic;
3280
583
                    }
3281
583
                }
3282
2.93k
            }
3283
3.13k
            if(i4_thrd_id == 0)
3284
3.13k
            {
3285
3.13k
                PROFILE_STOP(&ps_hle_ctxt->profile_enc_me[ps_enc_ctxt->i4_resolution_id], NULL);
3286
3.13k
            }
3287
3.13k
        }
3288
        /************************************/
3289
        /******  ENTER CRITICAL SECTION *****/
3290
        /************************************/
3291
3.13k
        {
3292
3.13k
            WORD32 result_frame_init;
3293
3.13k
            void *pv_mutex_handle_frame_init;
3294
3295
            /* Create mutex for locking non-reentrant sections      */
3296
3.13k
            pv_mutex_handle_frame_init =
3297
3.13k
                ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i4_me_frm_id];
3298
3299
            /****** Lock the critical section ******/
3300
3.13k
            if(NULL != pv_mutex_handle_frame_init)
3301
3.13k
            {
3302
3.13k
                result_frame_init = osal_mutex_lock(pv_mutex_handle_frame_init);
3303
3304
3.13k
                if(OSAL_SUCCESS != result_frame_init)
3305
0
                    return 0;
3306
3.13k
            }
3307
3.13k
        }
3308
3309
3.13k
        if(0 == ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id])
3310
3.13k
        {
3311
            /* ------- set buffer produced from me_enc que ------------ */
3312
3.13k
            ihevce_q_set_buff_prod(
3313
3.13k
                ps_enc_ctxt,
3314
3.13k
                IHEVCE_ME_ENC_RDOPT_Q,
3315
3.13k
                ps_enc_ctxt->s_multi_thrd.ai4_me_out_buf_id[i4_me_frm_id]);
3316
3317
3.13k
            ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id] = 1;
3318
3.13k
        }
3319
3.13k
        if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] &&
3320
3.13k
           NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id])
3321
3.13k
        {
3322
3.13k
            ihevce_lap_enc_buf_t *ps_curr_inp;
3323
3324
3.13k
            WORD32 first_field = 1;
3325
3326
            /* Increment the counter to keep track of no of threads exiting the current mutex*/
3327
3.13k
            ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id]++;
3328
3329
3.13k
            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
3.13k
            if(ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id] ==
3334
3.13k
               ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
3335
3.13k
            {
3336
3.13k
                ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_me_frm_id] = 0;
3337
3338
3.13k
                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
3.13k
                if(IV_P_FRAME == ps_curr_inp->s_lap_out.i4_pic_type)
3342
2.46k
                {
3343
2.46k
                    WORD32 i4_idx_dvsr_p = ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p;
3344
                    /* Sanity Check */
3345
2.46k
                    ASSERT(ps_curr_inp->s_lap_out.i4_pic_type < IV_IP_FRAME);
3346
3347
                    /*  Frame END processing for Dynamic Vertival Search    */
3348
2.46k
                    ihevce_l0_me_frame_end(
3349
2.46k
                        ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
3350
2.46k
                        i4_idx_dvsr_p,
3351
2.46k
                        ps_curr_inp->s_lap_out.i4_display_num,
3352
2.46k
                        i4_me_frm_id);
3353
3354
2.46k
                    ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p++;
3355
2.46k
                    if(ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p == NUM_SG_INTERLEAVED)
3356
2.46k
                    {
3357
2.46k
                        ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p = 0;
3358
2.46k
                    }
3359
2.46k
                }
3360
3.13k
                if(1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id]
3361
3.13k
                            ->i4_frm_proc_valid_flag)
3362
2.93k
                {
3363
                    /* Init i4_is_prev_frame_reference for the next P-frame */
3364
2.93k
                    me_master_ctxt_t *ps_master_ctxt =
3365
2.93k
                        (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3366
3367
                    /* get the current thread ctxt pointer */
3368
2.93k
                    me_ctxt_t *ps_ctxt = ps_master_ctxt->aps_me_ctxt[i4_thrd_id];
3369
3370
2.93k
                    me_frm_ctxt_t *ps_frm_ctxt = ps_ctxt->aps_me_frm_prms[i4_me_frm_id];
3371
3372
2.93k
                    ps_frm_ctxt->ps_curr_descr->aps_layers[0]->i4_non_ref_free = 1;
3373
2.93k
                }
3374
3.13k
                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_me_prms[i4_me_frm_id] = NULL;
3375
3.13k
                ps_enc_ctxt->s_multi_thrd.aps_cur_out_me_prms[i4_me_frm_id] = NULL;
3376
3.13k
                ps_enc_ctxt->s_multi_thrd.aps_cur_L0_ipe_inp_prms[i4_me_frm_id] = NULL;
3377
3.13k
                ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_me_frm_id] = 0;
3378
3.13k
                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
3.13k
                ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_me_done);
3382
3.13k
            }
3383
3.13k
        }
3384
        /************************************/
3385
        /******  EXIT CRITICAL SECTION ******/
3386
        /************************************/
3387
3388
3.13k
        {
3389
3.13k
            void *pv_mutex_handle_frame_init;
3390
3391
            /* Create mutex for locking non-reentrant sections      */
3392
3.13k
            pv_mutex_handle_frame_init =
3393
3.13k
                ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i4_me_frm_id];
3394
            /****** Unlock the critical section ******/
3395
3.13k
            if(NULL != pv_mutex_handle_frame_init)
3396
3.13k
            {
3397
3.13k
                result = osal_mutex_unlock(pv_mutex_handle_frame_init);
3398
3.13k
                if(OSAL_SUCCESS != result)
3399
0
                    return 0;
3400
3.13k
            }
3401
3.13k
        }
3402
        /* -------------------------------------------- */
3403
        /*        Encode Loop of entire frame           */
3404
        /* -------------------------------------------- */
3405
3.13k
        ASSERT(ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel <= MAX_NUM_ENC_LOOP_PARALLEL);
3406
3407
3.13k
        if(1 == ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel)
3408
3.13k
        {
3409
3.13k
            pv_dep_mngr_prev_frame_done = ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[0];
3410
3.13k
        }
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
3.13k
        {
3418
3.13k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_done, ps_thrd_ctxt->i4_thrd_id);
3419
3.13k
        }
3420
3421
        /************************************/
3422
        /****** ENTER CRITICAL SECTION ******/
3423
        /************************************/
3424
3.13k
        {
3425
3.13k
            WORD32 result_frame_init;
3426
3.13k
            void *pv_mutex_handle_frame_init;
3427
3428
            /* Create mutex for locking non-reentrant sections      */
3429
3.13k
            pv_mutex_handle_frame_init =
3430
3.13k
                ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i4_enc_frm_id];
3431
3432
            /****** Lock the critical section ******/
3433
3.13k
            if(NULL != pv_mutex_handle_frame_init)
3434
3.13k
            {
3435
3.13k
                result_frame_init = osal_mutex_lock(pv_mutex_handle_frame_init);
3436
3437
3.13k
                if(OSAL_SUCCESS != result_frame_init)
3438
0
                    return 0;
3439
3.13k
            }
3440
3.13k
        }
3441
3442
3.13k
        {
3443
3.13k
            ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
3444
3.13k
            pre_enc_me_ctxt_t *ps_curr_inp_from_me = NULL;
3445
3.13k
            me_enc_rdopt_ctxt_t *ps_curr_inp_enc = NULL;
3446
3.13k
            pre_enc_L0_ipe_encloop_ctxt_t *ps_curr_L0_IPE_inp_prms = NULL;
3447
3.13k
            recon_pic_buf_t *(*aps_ref_list)[HEVCE_MAX_REF_PICS * 2];
3448
3.13k
            WORD32 ai4_cur_qp[IHEVCE_MAX_NUM_BITRATES] = { 0 };
3449
3.13k
            WORD32 i4_field_pic = ps_enc_ctxt->s_runtime_src_prms.i4_field_pic;
3450
3.13k
            WORD32 first_field = 1;
3451
3.13k
            WORD32 result_frame_init;
3452
3.13k
            void *pv_mutex_handle_frame_init;
3453
3454
            /* Create mutex for locking non-reentrant sections      */
3455
3.13k
            pv_mutex_handle_frame_init =
3456
3.13k
                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
3.13k
            if(ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] == 0)
3460
3.13k
            {
3461
3.13k
                WORD32
3462
3.13k
                    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
3.13k
                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] =
3465
3.13k
                    (me_enc_rdopt_ctxt_t *)ihevce_q_get_filled_buff(
3466
3.13k
                        ps_enc_ctxt,
3467
3.13k
                        IHEVCE_ME_ENC_RDOPT_Q,
3468
3.13k
                        &ps_enc_ctxt->s_multi_thrd.i4_enc_in_buf_id[i4_enc_frm_id],
3469
3.13k
                        BUFF_QUE_BLOCKING_MODE);
3470
3.13k
                i4_enc_end_flag =
3471
3.13k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->i4_end_flag;
3472
3473
3.13k
                ASSERT(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL);
3474
3475
3.13k
                if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
3476
3.13k
                {
3477
3.13k
                    ps_curr_inp =
3478
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->ps_curr_inp;
3479
3.13k
                    ps_curr_inp_from_me =
3480
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3481
3.13k
                            ->ps_curr_inp_from_me_prms;
3482
3.13k
                    ps_curr_inp_enc = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id];
3483
3.13k
                    ps_curr_L0_IPE_inp_prms =
3484
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3485
3.13k
                            ->ps_curr_inp_from_l0_ipe_prms;
3486
3487
6.26k
                    for(i4_bitrate_ctr = 0; i4_bitrate_ctr < i4_num_bitrates; i4_bitrate_ctr++)
3488
3.13k
                    {
3489
3.13k
                        iv_enc_recon_data_buffs_t
3490
3.13k
                            *ps_recon_out[MAX_NUM_ENC_LOOP_PARALLEL][IHEVCE_MAX_NUM_BITRATES] = {
3491
3.13k
                                { NULL }
3492
3.13k
                            };
3493
3.13k
                        frm_proc_ent_cod_ctxt_t *ps_curr_out[MAX_NUM_ENC_LOOP_PARALLEL]
3494
3.13k
                                                            [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
3.13k
                        ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr] =
3501
3.13k
                            (frm_proc_ent_cod_ctxt_t *)ihevce_q_get_free_buff(
3502
3.13k
                                (void *)ps_enc_ctxt,
3503
3.13k
                                IHEVCE_FRM_PRS_ENT_COD_Q +
3504
3.13k
                                    i4_bitrate_ctr, /*decides the buffer queue */
3505
3.13k
                                &ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i4_bitrate_ctr],
3506
3.13k
                                BUFF_QUE_BLOCKING_MODE);
3507
3.13k
                        ps_enc_ctxt->s_multi_thrd.is_out_buf_freed[i4_enc_frm_id][i4_bitrate_ctr] =
3508
3.13k
                            0;
3509
3.13k
                        ps_enc_ctxt->s_multi_thrd
3510
3.13k
                            .ps_curr_out_enc_grp[i4_enc_frm_id][i4_bitrate_ctr] =
3511
3.13k
                            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
3.13k
#ifndef DISABLE_SEI
3515
3.13k
                        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
3.13k
#endif
3524
                        /*derive end flag and input valid flag in output buffer */
3525
3.13k
                        if(NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id])
3526
3.13k
                        {
3527
3.13k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_end_flag =
3528
3.13k
                                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3529
3.13k
                                    ->i4_end_flag;
3530
3.13k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_frm_proc_valid_flag =
3531
3.13k
                                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3532
3.13k
                                    ->i4_frm_proc_valid_flag;
3533
3534
3.13k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_out_flush_flag =
3535
3.13k
                                ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3536
3.13k
                                    ->ps_curr_inp->s_lap_out.i4_out_flush_flag;
3537
3.13k
                        }
3538
3539
                        /*derive other parameters in output buffer */
3540
3.13k
                        if(NULL != ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr] &&
3541
3.13k
                           (NULL != ps_curr_inp_from_me) &&
3542
3.13k
                           (1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag) &&
3543
2.93k
                           (i4_enc_end_flag == 0))
3544
2.93k
                        {
3545
                            /* copy the time stamps from inp to entropy inp */
3546
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_inp_timestamp_low =
3547
2.93k
                                ps_curr_inp_from_me->i4_inp_timestamp_low;
3548
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_inp_timestamp_high =
3549
2.93k
                                ps_curr_inp_from_me->i4_inp_timestamp_high;
3550
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->pv_app_frm_ctxt =
3551
2.93k
                                ps_curr_inp_from_me->pv_app_frm_ctxt;
3552
3553
                            /*copy slice header params from temp structure to output buffer */
3554
2.93k
                            memcpy(
3555
2.93k
                                &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->s_slice_hdr,
3556
2.93k
                                &ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3557
2.93k
                                     ->s_slice_hdr,
3558
2.93k
                                sizeof(slice_header_t));
3559
3560
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3561
2.93k
                                ->s_slice_hdr.pu4_entry_point_offset =
3562
2.93k
                                &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3563
2.93k
                                     ->ai4_entry_point_offset[0];
3564
3565
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_slice_nal_type =
3566
2.93k
                                ps_curr_inp_from_me->i4_slice_nal_type;
3567
3568
                            /* populate sps, vps and pps pointers for the entropy input params */
3569
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_pps =
3570
2.93k
                                &ps_enc_ctxt->as_pps[i4_bitrate_ctr];
3571
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_sps =
3572
2.93k
                                &ps_enc_ctxt->as_sps[i4_bitrate_ctr];
3573
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->ps_vps =
3574
2.93k
                                &ps_enc_ctxt->as_vps[i4_bitrate_ctr];
3575
3576
2.93k
#ifndef DISABLE_SEI
3577
                            /* SEI header will be populated in pre-enocde stage */
3578
2.93k
                            memcpy(
3579
2.93k
                                &ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->s_sei,
3580
2.93k
                                &ps_curr_inp_from_me->s_sei,
3581
2.93k
                                sizeof(sei_params_t));
3582
3583
2.93k
#endif
3584
                            /*AUD and EOS presnt flags are populated*/
3585
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i1_aud_present_flag =
3586
2.93k
                                ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_aud_enable_flags;
3587
3588
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i1_eos_present_flag =
3589
2.93k
                                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.93k
                            {
3593
2.93k
                                ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]->i4_display_num =
3594
2.93k
                                    ps_curr_inp->s_lap_out.i4_display_num;
3595
2.93k
                            }
3596
3597
                            /* The Qp populated in Pre enc stage needs to overwritten with Qp
3598
                        queried from rate control*/
3599
2.93k
                            ps_curr_out[i4_enc_frm_id][i4_bitrate_ctr]
3600
2.93k
                                ->s_slice_hdr.i1_slice_qp_delta =
3601
2.93k
                                (WORD8)ps_curr_inp_from_me->i4_curr_frm_qp -
3602
2.93k
                                ps_enc_ctxt->as_pps[i4_bitrate_ctr].i1_pic_init_qp;
3603
2.93k
                        }
3604
3605
                        /* ------- get a filled descriptor from output Que ------------ */
3606
3.13k
                        if(/*(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag) &&*/
3607
3.13k
                           (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
3.13k
                    }  //bitrate ctr
3647
3.13k
                }
3648
3.13k
            }
3649
3.13k
            if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
3650
3.13k
            {
3651
3.13k
                ps_curr_inp =
3652
3.13k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]->ps_curr_inp;
3653
3.13k
                ps_curr_inp_from_me = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3654
3.13k
                                          ->ps_curr_inp_from_me_prms;
3655
3.13k
                ps_curr_inp_enc = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id];
3656
3.13k
                ps_curr_L0_IPE_inp_prms =
3657
3.13k
                    ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3658
3.13k
                        ->ps_curr_inp_from_l0_ipe_prms;
3659
3.13k
            }
3660
3.13k
            if((NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]) &&
3661
3.13k
               ((1 == ps_curr_inp_enc->i4_frm_proc_valid_flag) &&
3662
2.93k
                (ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] == 0)))
3663
2.93k
            {
3664
5.87k
                for(i = 0; i < i4_num_bitrates; i++)
3665
2.93k
                {
3666
2.93k
                    aps_ref_list = ps_curr_inp_enc->aps_ref_list[i];
3667
                    /* acquire mutex lock for rate control calls */
3668
2.93k
                    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.93k
                    if(ps_curr_inp->s_lap_out.i4_pic_type == IV_I_FRAME ||
3672
2.80k
                       ps_curr_inp->s_lap_out.i4_pic_type == IV_IDR_FRAME)
3673
583
                    {
3674
583
                        ihevce_rc_update_cur_frm_intra_satd(
3675
583
                            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3676
583
                            ps_curr_inp_from_me->i8_frame_acc_satd_cost,
3677
583
                            ps_enc_ctxt->i4_active_enc_frame_id);
3678
583
                    }
3679
3680
                    /*pels assuming satd/act is obtained for entire frame*/
3681
2.93k
                    ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered =
3682
2.93k
                        ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
3683
2.93k
                        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.93k
                    {
3687
2.93k
                        LWORD64 i8_new_bitrate =
3688
2.93k
                            ihevce_rc_get_new_bitrate(ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3689
2.93k
                        LWORD64 i8_new_peak_bitrate = ihevce_rc_get_new_peak_bitrate(
3690
2.93k
                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3691
2.93k
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3692
2.93k
                            ->i8_buf_level_bitrate_change = -1;
3693
2.93k
                        if((i8_new_bitrate != -1) &&
3694
169
                           (i8_new_peak_bitrate != -1)) /*-1 indicates no pending request*/
3695
169
                        {
3696
169
                            LWORD64 buffer_level = ihevce_rc_change_avg_bitrate(
3697
169
                                ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3698
169
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3699
169
                                ->i8_buf_level_bitrate_change = buffer_level;
3700
169
                        }
3701
2.93k
                    }
3702
3703
2.93k
                    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.93k
#if 1  //KISH ELP
3711
2.93k
                    {
3712
2.93k
                        rc_bits_sad_t as_rc_frame_stat[IHEVCE_MAX_NUM_BITRATES];
3713
3714
2.93k
                        if(ps_enc_ctxt->ai4_rc_query[i] ==
3715
2.93k
                           ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)  //KISH
3716
2.74k
                        {
3717
2.74k
                            WORD32 out_buf_id[IHEVCE_MAX_NUM_BITRATES];
3718
2.74k
                            WORD32 i4_pic_type;
3719
2.74k
                            WORD32 cur_qp[IHEVCE_MAX_NUM_BITRATES];
3720
2.74k
                            ihevce_lap_output_params_t s_lap_out;
3721
3722
2.74k
                            rc_lap_out_params_t s_rc_lap_out;
3723
2.74k
                            WORD32 i4_suppress_bpic_update;
3724
3725
2.74k
                            ihevce_rc_store_retrive_update_info(
3726
2.74k
                                (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3727
2.74k
                                &as_rc_frame_stat[i],
3728
2.74k
                                ps_enc_ctxt->i4_active_enc_frame_id,
3729
2.74k
                                i,
3730
2.74k
                                2,
3731
2.74k
                                &out_buf_id[i],
3732
2.74k
                                &i4_pic_type,
3733
2.74k
                                &cur_qp[i],
3734
2.74k
                                (void *)&s_lap_out,
3735
2.74k
                                (void *)&s_rc_lap_out);
3736
3737
2.74k
                            i4_suppress_bpic_update =
3738
2.74k
                                (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.74k
                            if(1 == ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
3741
2.74k
                            {
3742
                                /* SGI & Enc Loop Parallelism related changes*/
3743
2.74k
                                ihevce_rc_interface_update(
3744
2.74k
                                    (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3745
2.74k
                                    (IV_PICTURE_CODING_TYPE_T)s_rc_lap_out.i4_rc_pic_type,
3746
2.74k
                                    &s_rc_lap_out,
3747
2.74k
                                    cur_qp[i],
3748
2.74k
                                    i4_enc_frm_id_rc);
3749
2.74k
                            }
3750
3751
2.74k
                            ihevce_rc_update_pic_info(
3752
2.74k
                                (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3753
2.74k
                                (as_rc_frame_stat[i].u4_total_texture_bits +
3754
2.74k
                                 as_rc_frame_stat[i].u4_total_header_bits),  //pass total bits
3755
2.74k
                                as_rc_frame_stat[i].u4_total_header_bits,
3756
2.74k
                                as_rc_frame_stat[i].u4_total_sad,
3757
2.74k
                                as_rc_frame_stat[i].u4_total_intra_sad,
3758
2.74k
                                (IV_PICTURE_CODING_TYPE_T)i4_pic_type,
3759
2.74k
                                cur_qp[i],
3760
2.74k
                                i4_suppress_bpic_update,
3761
2.74k
                                as_rc_frame_stat[i].i4_qp_normalized_8x8_cu_sum,
3762
2.74k
                                as_rc_frame_stat[i].i4_8x8_cu_sum,
3763
2.74k
                                as_rc_frame_stat[i].i8_sad_by_qscale,
3764
2.74k
                                &s_lap_out,
3765
2.74k
                                &s_rc_lap_out,
3766
2.74k
                                out_buf_id[i],
3767
2.74k
                                as_rc_frame_stat[i].u4_open_loop_intra_sad,
3768
2.74k
                                as_rc_frame_stat[i].i8_total_ssd_frame,
3769
2.74k
                                ps_enc_ctxt
3770
2.74k
                                    ->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.74k
                            ps_enc_ctxt->ai4_rc_query[i]--;
3777
3778
2.74k
                            if(i == (i4_num_bitrates - 1))
3779
2.74k
                            {
3780
2.74k
                                ihevce_rc_cal_pre_enc_qp(
3781
2.74k
                                    (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0]);
3782
3783
2.74k
                                ps_enc_ctxt->i4_active_enc_frame_id++;
3784
2.74k
                                ps_enc_ctxt->i4_active_enc_frame_id =
3785
2.74k
                                    (ps_enc_ctxt->i4_active_enc_frame_id %
3786
2.74k
                                     ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
3787
2.74k
                            }
3788
2.74k
                        }
3789
2.93k
                    }
3790
2.93k
#endif
3791
2.93k
                    if(ps_enc_ctxt->ai4_rc_query[i] < ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
3792
2.93k
                    {
3793
                        /*HEVC_RC query rate control for qp*/
3794
2.93k
                        ai4_cur_qp[i] = ihevce_rc_get_pic_quant(
3795
2.93k
                            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3796
2.93k
                            &ps_curr_inp->s_rc_lap_out,
3797
2.93k
                            ENC_GET_QP,
3798
2.93k
                            i4_enc_frm_id_rc,
3799
2.93k
                            0,
3800
2.93k
                            &ps_curr_inp->s_lap_out.ai4_frame_bits_estimated[i]);
3801
3802
2.93k
                        ps_curr_inp->s_rc_lap_out.i4_orig_rc_qp = ai4_cur_qp[i];
3803
3804
2.93k
                        ps_enc_ctxt->s_multi_thrd.i4_in_frame_rc_enabled = 0;
3805
2.93k
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3806
2.93k
                            ->i4_sub_pic_level_rc = 0;
3807
2.93k
                        ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3808
2.93k
                            ->ai4_frame_bits_estimated =
3809
2.93k
                            ps_curr_inp->s_lap_out.ai4_frame_bits_estimated[i];
3810
3811
2.93k
                        {
3812
2.93k
                            ps_enc_ctxt->ai4_rc_query[i]++;
3813
2.93k
                        }
3814
2.93k
                    }
3815
3816
                    /* SGI & Enc Loop Parallelism related changes*/
3817
2.93k
                    ihevce_rc_interface_update(
3818
2.93k
                        (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
3819
2.93k
                        (IV_PICTURE_CODING_TYPE_T)ps_curr_inp->s_lap_out.i4_pic_type,
3820
2.93k
                        &ps_curr_inp->s_rc_lap_out,
3821
2.93k
                        ai4_cur_qp[i],
3822
2.93k
                        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.93k
                    osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
3828
3829
2.93k
                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3830
2.93k
                        ->s_slice_hdr.i1_slice_qp_delta =
3831
2.93k
                        (WORD8)ai4_cur_qp[i] - ps_enc_ctxt->as_pps[i].i1_pic_init_qp;
3832
3833
2.93k
                    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.93k
                    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.93k
                    ihevce_get_frame_lambda_prms(
3844
2.93k
                        ps_enc_ctxt,
3845
2.93k
                        ps_curr_inp_from_me,
3846
2.93k
                        ai4_cur_qp[i],
3847
2.93k
                        first_field,
3848
2.93k
                        ps_curr_inp->s_lap_out.i4_is_ref_pic,
3849
2.93k
                        ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
3850
2.93k
                        ps_curr_inp->s_lap_out.f_i_pic_lamda_modifier,
3851
2.93k
                        i,
3852
2.93k
                        ENC_LOOP_LAMBDA_TYPE);
3853
3854
2.93k
#if ADAPT_COLOCATED_FROM_L0_FLAG
3855
2.93k
                    ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i]->i4_frame_qp =
3856
2.93k
                        ai4_cur_qp[i];
3857
2.93k
#endif
3858
2.93k
                }  //bitrate counter ends
3859
3860
                /* Reset the Dependency Mngrs local to EncLoop., ie CU_TopRight and Dblk */
3861
2.93k
                ihevce_enc_loop_dep_mngr_frame_reset(
3862
2.93k
                    ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt, i4_enc_frm_id);
3863
2.93k
            }
3864
3865
3.13k
            {
3866
                /*Set the master done flag for frame init so that other
3867
                * threads can skip it
3868
                */
3869
3.13k
                ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 1;
3870
3.13k
            }
3871
3872
            /************************************/
3873
            /******  EXIT CRITICAL SECTION ******/
3874
            /************************************/
3875
3876
            /****** Unlock the critical section ******/
3877
3.13k
            if(NULL != pv_mutex_handle_frame_init)
3878
3.13k
            {
3879
3.13k
                result_frame_init = osal_mutex_unlock(pv_mutex_handle_frame_init);
3880
3.13k
                if(OSAL_SUCCESS != result_frame_init)
3881
0
                    return 0;
3882
3.13k
            }
3883
3.13k
            ps_enc_ctxt->s_multi_thrd.i4_encode = 1;
3884
3.13k
            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
3.13k
            if((i4_enc_end_flag == 0) &&
3892
2.93k
               (NULL != ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]) &&
3893
2.93k
               (1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3894
2.93k
                         ->i4_frm_proc_valid_flag))
3895
2.93k
            {
3896
2.93k
                while(1)
3897
2.93k
                {
3898
2.93k
                    ctb_enc_loop_out_t *ps_ctb_enc_loop_frm[IHEVCE_MAX_NUM_BITRATES];
3899
2.93k
                    cu_enc_loop_out_t *ps_cu_enc_loop_frm[IHEVCE_MAX_NUM_BITRATES];
3900
2.93k
                    tu_enc_loop_out_t *ps_tu_frm[IHEVCE_MAX_NUM_BITRATES];
3901
2.93k
                    pu_t *ps_pu_frm[IHEVCE_MAX_NUM_BITRATES];
3902
2.93k
                    UWORD8 *pu1_frm_coeffs[IHEVCE_MAX_NUM_BITRATES];
3903
2.93k
                    me_master_ctxt_t *ps_master_me_ctxt =
3904
2.93k
                        (me_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_me_ctxt;
3905
2.93k
                    ihevce_enc_loop_master_ctxt_t *ps_master_ctxt =
3906
2.93k
                        (ihevce_enc_loop_master_ctxt_t *)ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt;
3907
3908
5.87k
                    for(i = 0; i < i4_num_bitrates; i++)
3909
2.93k
                    {
3910
2.93k
                        if(i4_thrd_id == 0)
3911
2.93k
                        {
3912
2.93k
                            PROFILE_START(
3913
2.93k
                                &ps_hle_ctxt->profile_enc[ps_enc_ctxt->i4_resolution_id][i]);
3914
2.93k
                        }
3915
2.93k
                        if(NULL != ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id])
3916
2.93k
                        {
3917
2.93k
                            ps_ctb_enc_loop_frm[i] =
3918
2.93k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3919
2.93k
                                    ->ps_frm_ctb_data;
3920
2.93k
                            ps_cu_enc_loop_frm[i] =
3921
2.93k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3922
2.93k
                                    ->ps_frm_cu_data;
3923
2.93k
                            ps_tu_frm[i] =
3924
2.93k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3925
2.93k
                                    ->ps_frm_tu_data;
3926
2.93k
                            ps_pu_frm[i] =
3927
2.93k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3928
2.93k
                                    ->ps_frm_pu_data;
3929
2.93k
                            pu1_frm_coeffs[i] = (UWORD8 *)ps_enc_ctxt->s_multi_thrd
3930
2.93k
                                                    .ps_curr_out_enc_grp[i4_enc_frm_id][i]
3931
2.93k
                                                    ->pv_coeff_data;
3932
2.93k
                        }
3933
                        /*derive reference picture list based on ping or pong instnace */
3934
2.93k
                        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.93k
                        ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id]->i4_consider_chroma_cost =
3938
2.93k
                            1;
3939
3940
                        /*************************
3941
                        * MULTI BITRATE CODE START
3942
                        **************************/
3943
2.93k
                        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.93k
                        ihevce_enc_loop_frame_init(
3954
2.93k
                            ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
3955
2.93k
                            ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i],
3956
2.93k
                            aps_ref_list,
3957
2.93k
                            ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i],
3958
2.93k
                            &ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
3959
2.93k
                                 ->s_slice_hdr,
3960
2.93k
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_pps,
3961
2.93k
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_sps,
3962
2.93k
                            ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]->ps_vps,
3963
2.93k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i1_weighted_pred_flag,
3964
2.93k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i1_weighted_bipred_flag,
3965
2.93k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_log2_luma_wght_denom,
3966
2.93k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_log2_chroma_wght_denom,
3967
2.93k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_poc,
3968
2.93k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_display_num,
3969
2.93k
                            ps_enc_ctxt,
3970
2.93k
                            ps_curr_inp_enc,
3971
2.93k
                            i,
3972
2.93k
                            i4_thrd_id,
3973
2.93k
                            i4_enc_frm_id,  // update this to enc_loop_ctxt struct
3974
2.93k
                            i4_num_bitrates,
3975
2.93k
                            ps_curr_inp_enc->ps_curr_inp->s_lap_out.i4_quality_preset,
3976
2.93k
                            ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
3977
2.93k
                                ->pv_dep_mngr_encloop_dep_me);
3978
3979
2.93k
                        ihevce_enc_loop_process(
3980
2.93k
                            ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
3981
2.93k
                            ps_curr_inp,
3982
2.93k
                            ps_curr_inp_from_me->ps_ctb_analyse,
3983
2.93k
                            ps_curr_L0_IPE_inp_prms->ps_ipe_analyse_ctb,
3984
2.93k
                            ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_enc_frm_id][i],
3985
2.93k
                            ps_curr_inp_enc->ps_cur_ctb_cu_tree,
3986
2.93k
                            ps_ctb_enc_loop_frm[i],
3987
2.93k
                            ps_cu_enc_loop_frm[i],
3988
2.93k
                            ps_tu_frm[i],
3989
2.93k
                            ps_pu_frm[i],
3990
2.93k
                            pu1_frm_coeffs[i],
3991
2.93k
                            &ps_enc_ctxt->s_frm_ctb_prms,
3992
2.93k
                            &ps_curr_inp_from_me->as_lambda_prms[i],
3993
2.93k
                            &ps_enc_ctxt->s_multi_thrd,
3994
2.93k
                            i4_thrd_id,
3995
2.93k
                            i4_enc_frm_id,
3996
2.93k
                            ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass);
3997
2.93k
                        if(i4_thrd_id == 0)
3998
2.93k
                        {
3999
2.93k
                            PROFILE_STOP(
4000
2.93k
                                &ps_hle_ctxt->profile_enc[ps_enc_ctxt->i4_resolution_id][i], NULL);
4001
2.93k
                        }
4002
2.93k
                    }  //loop over bitrate ends
4003
2.93k
                    {
4004
2.93k
                        break;
4005
2.93k
                    }
4006
2.93k
                } /*end of while(ps_enc_ctxt->s_multi_thrd.ai4_encode[i4_enc_frm_id] == 1)*/
4007
2.93k
            }
4008
4009
            /************************************/
4010
            /****** ENTER CRITICAL SECTION ******/
4011
            /************************************/
4012
4013
            /****** Lock the critical section ******/
4014
3.13k
            if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4015
3.13k
            {
4016
3.13k
                result = osal_mutex_lock(
4017
3.13k
                    ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4018
4019
3.13k
                if(OSAL_SUCCESS != result)
4020
0
                    return 0;
4021
3.13k
            }
4022
3.13k
            if(ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] != NULL)
4023
3.13k
            {
4024
                /* Increment the counter to keep track of no of threads exiting the current mutex*/
4025
3.13k
                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
3.13k
                if(i4_enc_end_flag == 1)
4029
195
                {
4030
195
                    if(ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4031
195
                       ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds - 1)
4032
195
                    {
4033
195
                        ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] =
4034
195
                            ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
4035
195
                    }
4036
195
                }
4037
4038
3.13k
                {
4039
                    /*Last slave thread comming out of enc loop will execute next critical section*/
4040
3.13k
                    if(ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] ==
4041
3.13k
                       ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds)
4042
3.13k
                    {
4043
3.13k
                        iv_enc_recon_data_buffs_t *ps_recon_out_temp = NULL;
4044
3.13k
                        recon_pic_buf_t *ps_frm_recon_temp = NULL;
4045
3.13k
                        ihevce_lap_enc_buf_t *ps_curr_inp;
4046
3.13k
                        rc_lap_out_params_t *ps_rc_lap_out_next_encode;
4047
4048
3.13k
                        WORD32 ai4_act_qp[IHEVCE_MAX_NUM_BITRATES];
4049
3.13k
                        ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_enc_frm_id] = 0;
4050
4051
3.13k
                        ps_curr_inp = ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
4052
3.13k
                                          ->ps_curr_inp;
4053
4054
6.26k
                        for(i = 0; i < i4_num_bitrates; i++)
4055
3.13k
                        {
4056
3.13k
                            {
4057
3.13k
                                WORD32 j, i4_avg_QP;
4058
3.13k
                                ihevce_enc_loop_master_ctxt_t *ps_master_ctxt =
4059
3.13k
                                    (ihevce_enc_loop_master_ctxt_t *)
4060
3.13k
                                        ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt;
4061
3.13k
                                ihevce_enc_loop_ctxt_t *ps_ctxt, *ps_ctxt_temp;
4062
3.13k
                                ihevce_enc_loop_ctxt_t *ps_ctxt_last_thrd;
4063
3.13k
                                LWORD64 i8_total_cu_bits_into_qscale = 0, i8_total_cu_bits = 0;
4064
3.13k
                                UWORD32 total_frame_intra_sad = 0;
4065
3.13k
                                UWORD32 total_frame_inter_sad = 0;
4066
3.13k
                                UWORD32 total_frame_sad = 0;
4067
4068
3.13k
                                LWORD64 total_frame_intra_cost = 0;
4069
3.13k
                                LWORD64 total_frame_inter_cost = 0;
4070
3.13k
                                LWORD64 total_frame_cost = 0;
4071
4072
3.13k
                                ps_ctxt_last_thrd =
4073
3.13k
                                    ps_master_ctxt->aps_enc_loop_thrd_ctxt[i4_thrd_id];
4074
3.13k
                                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
3.13k
                                else
4086
3.13k
                                {
4087
3.13k
                                    ai4_act_qp[i] =
4088
3.13k
                                        ps_enc_ctxt->s_multi_thrd.cur_qp[i4_enc_frm_id][i];
4089
3.13k
                                }
4090
4091
3.13k
                                ps_enc_ctxt->s_multi_thrd
4092
3.13k
                                    .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
3.13k
                                {
4096
3.13k
                                    ps_enc_ctxt->s_multi_thrd
4097
3.13k
                                        .ai4_acc_ctb_ctr[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4098
3.13k
                                    ps_enc_ctxt->s_multi_thrd
4099
3.13k
                                        .ai4_ctb_ctr[ps_ctxt_last_thrd->i4_enc_frm_id][i] = 0;
4100
4101
3.13k
                                    ps_enc_ctxt->s_multi_thrd
4102
3.13k
                                        .ai4_threshold_reached[ps_ctxt_last_thrd->i4_enc_frm_id][i] =
4103
3.13k
                                        0;
4104
4105
3.13k
                                    ps_enc_ctxt->s_multi_thrd
4106
3.13k
                                        .ai4_curr_qp_estimated[ps_ctxt_last_thrd->i4_enc_frm_id][i] =
4107
3.13k
                                        (1 << QP_LEVEL_MOD_ACT_FACTOR);
4108
4109
3.13k
                                    ps_enc_ctxt->s_multi_thrd
4110
3.13k
                                        .af_acc_hdr_bits_scale_err[ps_ctxt_last_thrd->i4_enc_frm_id]
4111
3.13k
                                                                  [i] = 0;
4112
3.13k
                                }
4113
6.26k
                                for(j = 0; j < ps_master_ctxt->i4_num_proc_thrds; j++)
4114
3.13k
                                {
4115
                                    /* ENC_LOOP state structure */
4116
3.13k
                                    ps_ctxt = ps_master_ctxt->aps_enc_loop_thrd_ctxt[j];
4117
4118
3.13k
                                    total_frame_intra_sad +=
4119
3.13k
                                        ps_ctxt
4120
3.13k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4121
3.13k
                                                                          ->i4_enc_frm_id][i]
4122
3.13k
                                            ->u4_frame_intra_sad_acc;
4123
3.13k
                                    total_frame_inter_sad +=
4124
3.13k
                                        ps_ctxt
4125
3.13k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4126
3.13k
                                                                          ->i4_enc_frm_id][i]
4127
3.13k
                                            ->u4_frame_inter_sad_acc;
4128
3.13k
                                    total_frame_sad +=
4129
3.13k
                                        ps_ctxt
4130
3.13k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4131
3.13k
                                                                          ->i4_enc_frm_id][i]
4132
3.13k
                                            ->u4_frame_sad_acc;
4133
4134
3.13k
                                    total_frame_intra_cost +=
4135
3.13k
                                        ps_ctxt
4136
3.13k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4137
3.13k
                                                                          ->i4_enc_frm_id][i]
4138
3.13k
                                            ->i8_frame_intra_cost_acc;
4139
3.13k
                                    total_frame_inter_cost +=
4140
3.13k
                                        ps_ctxt
4141
3.13k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4142
3.13k
                                                                          ->i4_enc_frm_id][i]
4143
3.13k
                                            ->i8_frame_inter_cost_acc;
4144
3.13k
                                    total_frame_cost +=
4145
3.13k
                                        ps_ctxt
4146
3.13k
                                            ->aaps_enc_loop_rc_params[ps_ctxt_last_thrd
4147
3.13k
                                                                          ->i4_enc_frm_id][i]
4148
3.13k
                                            ->i8_frame_cost_acc;
4149
                                    /*Reset thrd id flag once the frame is completed */
4150
3.13k
                                    ps_enc_ctxt->s_multi_thrd
4151
3.13k
                                        .ai4_thrd_id_valid_flag[ps_ctxt_last_thrd->i4_enc_frm_id][i]
4152
3.13k
                                                               [j] = -1;
4153
3.13k
                                }
4154
3.13k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4155
3.13k
                                    ->s_pic_level_info.u4_frame_sad = total_frame_sad;
4156
3.13k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4157
3.13k
                                    ->s_pic_level_info.u4_frame_intra_sad = total_frame_intra_sad;
4158
3.13k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4159
3.13k
                                    ->s_pic_level_info.u4_frame_inter_sad = total_frame_inter_sad;
4160
4161
3.13k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4162
3.13k
                                    ->s_pic_level_info.i8_frame_cost = total_frame_cost;
4163
3.13k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4164
3.13k
                                    ->s_pic_level_info.i8_frame_intra_cost = total_frame_intra_cost;
4165
3.13k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4166
3.13k
                                    ->s_pic_level_info.i8_frame_inter_cost = total_frame_inter_cost;
4167
3.13k
                            }
4168
3.13k
                            ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] = 1;
4169
3.13k
                            ps_recon_out_temp =
4170
3.13k
                                ps_enc_ctxt->s_multi_thrd.ps_recon_out[i4_enc_frm_id][i];
4171
3.13k
                            ps_frm_recon_temp =
4172
3.13k
                                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
3.13k
                            if(1 == ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id]
4176
3.13k
                                        ->i4_frm_proc_valid_flag)
4177
2.93k
                            {
4178
2.93k
#ifndef DISABLE_SEI
4179
                                /* Calculate the SEI Hash if enabled */
4180
2.93k
                                if(0 !=
4181
2.93k
                                   ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4182
2.93k
                                       ->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.93k
#endif
4210
                                /* Sending qp, poc and pic-type to entropy thread for printing on console */
4211
2.93k
                                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.93k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4223
2.93k
                                    ->i4_is_I_scenecut =
4224
2.93k
                                    ((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.93k
                                ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4229
2.93k
                                    ->i4_is_non_I_scenecut =
4230
2.93k
                                    ((ps_curr_inp->s_lap_out.i4_scene_type ==
4231
2.93k
                                      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.93k
                                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.93k
                                if(0 == ps_frm_recon_temp->i4_is_reference)
4257
28
                                {
4258
28
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i]
4259
28
                                        ->i4_pic_type += 2;
4260
28
                                }
4261
4262
2.93k
#define FORCE_EXT_REF_PIC 0
4263
4264
                                /* -------------------------------------------- */
4265
                                /*        Dumping of recon to App Queue         */
4266
                                /* -------------------------------------------- */
4267
2.93k
                                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.93k
                                ps_frm_recon_temp->i4_non_ref_free_flag = 1;
4333
                                /* -------------------------------------------- */
4334
                                /*        End of picture updates                */
4335
                                /* -------------------------------------------- */
4336
2.93k
                            }
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
3.13k
                            if(ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] == 1)
4342
3.13k
                            {
4343
                                /* set the output buffer as produced */
4344
3.13k
                                ihevce_q_set_buff_prod(
4345
3.13k
                                    (void *)ps_enc_ctxt,
4346
3.13k
                                    IHEVCE_FRM_PRS_ENT_COD_Q + i,
4347
3.13k
                                    ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i]);
4348
4349
3.13k
                                ps_enc_ctxt->s_multi_thrd.is_out_buf_freed[i4_enc_frm_id][i] = 1;
4350
3.13k
                                ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_enc_frm_id][i] = 0;
4351
3.13k
                            }
4352
4353
3.13k
                        }  //bit-rate counter ends
4354
                        /* -------------------------------------------- */
4355
                        /*        Frame level RC update                 */
4356
                        /* -------------------------------------------- */
4357
                        /* Query enc_loop to get the Parameters for Rate control */
4358
3.13k
                        if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
4359
2.93k
                        {
4360
2.93k
                            frm_proc_ent_cod_ctxt_t *ps_curr_out = NULL;
4361
                            /*HEVC_RC*/
4362
2.93k
                            rc_bits_sad_t as_rc_frame_stat[IHEVCE_MAX_NUM_BITRATES];
4363
2.93k
                            osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4364
4365
5.87k
                            for(i = 0; i < i4_num_bitrates; i++)
4366
2.93k
                            {
4367
                                /*each bit-rate RC params are collated by master thread */
4368
2.93k
                                ihevce_enc_loop_get_frame_rc_prms(
4369
2.93k
                                    ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt,
4370
2.93k
                                    &as_rc_frame_stat[i],
4371
2.93k
                                    i,
4372
2.93k
                                    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.93k
                                ps_curr_out =
4376
2.93k
                                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_enc_frm_id][i];
4377
4378
2.93k
                                ps_rc_lap_out_next_encode =
4379
2.93k
                                    (rc_lap_out_params_t *)
4380
2.93k
                                        ps_curr_inp->s_rc_lap_out.ps_rc_lap_out_next_encode;
4381
4382
2.93k
                                ps_curr_out->i4_is_end_of_idr_gop = 0;
4383
4384
2.93k
                                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.93k
                                else if(NULL == ps_rc_lap_out_next_encode)
4393
2.93k
                                {
4394
                                    /*If the lap out next is NULL, then end of sequence reached*/
4395
2.93k
                                    ps_curr_out->i4_is_end_of_idr_gop = 1;
4396
2.93k
                                }
4397
4398
2.93k
                                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.93k
                                {
4413
2.93k
                                    ihevce_rc_store_retrive_update_info(
4414
2.93k
                                        (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4415
2.93k
                                        &as_rc_frame_stat[i],
4416
2.93k
                                        i4_enc_frm_id_rc,
4417
2.93k
                                        i,
4418
2.93k
                                        1,
4419
2.93k
                                        &ps_enc_ctxt->s_multi_thrd.out_buf_id[i4_enc_frm_id][i],
4420
2.93k
                                        &ps_curr_inp->s_lap_out.i4_pic_type,
4421
2.93k
                                        &ai4_act_qp[i],
4422
2.93k
                                        (void *)&ps_curr_inp->s_lap_out,
4423
2.93k
                                        (void *)&ps_curr_inp->s_rc_lap_out);  // STORE
4424
2.93k
                                }
4425
2.93k
                            }
4426
4427
                            /* release mutex lock after rate control calls */
4428
2.93k
                            osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4429
2.93k
                        }
4430
3.13k
                        if((ps_enc_ctxt->ps_stat_prms->i4_save_recon != 0) /*&&
4431
3.13k
                                                                   (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
3.13k
                        if(i4_enc_end_flag == 1)
4471
195
                        {
4472
195
                            if(ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] == 0)
4473
195
                            {
4474
                                /* release the pre_enc/enc queue buffer */
4475
195
                                ihevce_q_rel_buf(
4476
195
                                    (void *)ps_enc_ctxt,
4477
195
                                    IHEVCE_PRE_ENC_ME_Q,
4478
195
                                    ps_curr_inp_enc->curr_inp_from_me_buf_id);
4479
4480
195
                                ps_enc_ctxt->s_multi_thrd.is_in_buf_freed[i4_enc_frm_id] = 1;
4481
195
                            }
4482
195
                        }
4483
                        /* release encoder owned input buffer*/
4484
3.13k
                        ihevce_q_rel_buf(
4485
3.13k
                            (void *)ps_enc_ctxt,
4486
3.13k
                            IHEVCE_INPUT_DATA_CTRL_Q,
4487
3.13k
                            ps_curr_inp_enc->curr_inp_buf_id);
4488
                        /* release the pre_enc/enc queue buffer */
4489
3.13k
                        ihevce_q_rel_buf(
4490
3.13k
                            ps_enc_ctxt,
4491
3.13k
                            IHEVCE_PRE_ENC_ME_Q,
4492
3.13k
                            ps_curr_inp_enc->curr_inp_from_me_buf_id);
4493
4494
3.13k
                        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
3.13k
                        ihevce_q_rel_buf(
4498
3.13k
                            ps_enc_ctxt,
4499
3.13k
                            IHEVCE_L0_IPE_ENC_Q,
4500
3.13k
                            ps_curr_inp_enc->curr_inp_from_l0_ipe_buf_id);
4501
4502
3.13k
                        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
3.13k
                        ihevce_q_rel_buf(
4505
3.13k
                            ps_enc_ctxt,
4506
3.13k
                            IHEVCE_ME_ENC_RDOPT_Q,
4507
3.13k
                            ps_enc_ctxt->s_multi_thrd.i4_enc_in_buf_id[i4_enc_frm_id]);
4508
4509
                        /* reset the pointers to NULL */
4510
3.13k
                        ps_enc_ctxt->s_multi_thrd.aps_cur_inp_enc_prms[i4_enc_frm_id] = NULL;
4511
3.13k
                        ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_enc_frm_id] = 0;
4512
6.26k
                        for(i = 0; i < i4_num_bitrates; i++)
4513
3.13k
                            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
3.13k
                        ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_done);
4518
3.13k
                    }
4519
3.13k
                }
4520
3.13k
            }
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
3.13k
        }
4550
4551
        /************************************/
4552
        /******  EXIT CRITICAL SECTION ******/
4553
        /************************************/
4554
        /****** Unlock the critical section ******/
4555
3.13k
        if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4556
3.13k
        {
4557
3.13k
            result = osal_mutex_unlock(
4558
3.13k
                ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4559
3.13k
            if(OSAL_SUCCESS != result)
4560
0
                return 0;
4561
3.13k
        }
4562
4563
3.13k
        if((0 == i4_me_end_flag) && (0 == i4_enc_end_flag))
4564
2.93k
        {
4565
2.93k
            i4_enc_frm_id++;
4566
2.93k
            i4_enc_frm_id_rc++;
4567
4568
2.93k
            if(i4_enc_frm_id == NUM_ME_ENC_BUFS)
4569
2.93k
            {
4570
2.93k
                i4_enc_frm_id = 0;
4571
2.93k
            }
4572
4573
2.93k
            if(i4_enc_frm_id_rc == ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc)
4574
2.93k
            {
4575
2.93k
                i4_enc_frm_id_rc = 0;
4576
2.93k
            }
4577
2.93k
            i4_me_frm_id++;
4578
4579
2.93k
            if(i4_me_frm_id == NUM_ME_ENC_BUFS)
4580
2.93k
                i4_me_frm_id = 0;
4581
2.93k
        }
4582
3.13k
        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
3.13k
    }
4588
4589
    /****** Lock the critical section ******/
4590
4591
195
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4592
195
    {
4593
195
        WORD32 result;
4594
4595
195
        result =
4596
195
            osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4597
4598
195
        if(OSAL_SUCCESS != result)
4599
0
            return 0;
4600
195
    }
4601
4602
195
    if(ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4603
195
       (ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds - 1))
4604
195
    {
4605
195
        if(1 != ps_enc_ctxt->s_multi_thrd.i4_force_end_flag)
4606
195
        {
4607
195
            osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4608
390
            for(i = 0; i < ps_enc_ctxt->i4_num_bitrates; i++)
4609
195
            {
4610
195
                ihevce_rc_close(
4611
195
                    ps_enc_ctxt,
4612
195
                    ps_enc_ctxt->i4_active_enc_frame_id,
4613
195
                    2,
4614
195
                    MIN(ps_enc_ctxt->ai4_rc_query[i], ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc),
4615
195
                    i);
4616
195
            }
4617
195
            osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4618
195
        }
4619
195
    }
4620
4621
195
    ps_enc_ctxt->s_multi_thrd.num_thrds_done++;
4622
4623
    /****** UnLock the critical section ******/
4624
195
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4625
195
    {
4626
195
        WORD32 result;
4627
4628
195
        result =
4629
195
            osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4630
4631
195
        if(OSAL_SUCCESS != result)
4632
0
            return 0;
4633
195
    }
4634
4635
    /****** Lock the critical section ******/
4636
195
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4637
195
    {
4638
195
        WORD32 result;
4639
195
        result =
4640
195
            osal_mutex_lock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4641
4642
195
        if(OSAL_SUCCESS != result)
4643
0
            return 0;
4644
195
    }
4645
195
    if((ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4646
195
        ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) &&
4647
195
       (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
195
    if((ps_enc_ctxt->s_multi_thrd.num_thrds_done ==
4722
195
        ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) &&
4723
195
       (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
195
    if(NULL != ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id])
4788
195
    {
4789
195
        WORD32 result;
4790
195
        result =
4791
195
            osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i4_enc_frm_id]);
4792
4793
195
        if(OSAL_SUCCESS != result)
4794
0
            return 0;
4795
195
    }
4796
4797
195
    return (0);
4798
195
}
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
195
{
4822
195
    WORD32 i;
4823
195
    WORD32 i4_num_instance,
4824
195
        i4_resolution_id = ps_enc_ctxt->i4_resolution_id;  //number of bit-rate instances
4825
4826
195
    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
195
    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd =
4850
195
        ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width +
4851
195
        SET_CTB_ALIGN(
4852
195
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width,
4853
195
            ps_enc_ctxt->s_frm_ctb_prms.i4_min_cu_size);
4854
4855
195
    ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4856
195
        ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4857
4858
195
    if((ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd %
4859
195
        ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size) != 0)
4860
112
        ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz =
4861
112
            ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz + 1;
4862
4863
    /* Allign the frame hieght to min CU size */
4864
195
    ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht =
4865
195
        ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height +
4866
195
        SET_CTB_ALIGN(
4867
195
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height,
4868
195
            ps_enc_ctxt->s_frm_ctb_prms.i4_min_cu_size);
4869
4870
195
    ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4871
195
        ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht / ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size;
4872
4873
195
    if((ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht %
4874
195
        ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size) != 0)
4875
113
        ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert =
4876
113
            ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_vert + 1;
4877
4878
195
#endif  // PIC_ALIGN_CTB_SIZE
4879
4880
195
    ps_enc_ctxt->s_frm_ctb_prms.i4_max_cus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4881
195
                                                    ps_enc_ctxt->s_frm_ctb_prms.i4_num_cus_in_ctb;
4882
4883
195
    ps_enc_ctxt->s_frm_ctb_prms.i4_max_pus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4884
195
                                                    ps_enc_ctxt->s_frm_ctb_prms.i4_num_pus_in_ctb;
4885
4886
195
    ps_enc_ctxt->s_frm_ctb_prms.i4_max_tus_in_row = ps_enc_ctxt->s_frm_ctb_prms.i4_num_ctbs_horz *
4887
195
                                                    ps_enc_ctxt->s_frm_ctb_prms.i4_num_tus_in_ctb;
4888
195
    ihevce_coarse_me_set_resolution(
4889
195
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
4890
195
        1,
4891
195
        &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd,
4892
195
        &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
195
    ihevce_me_set_resolution(
4896
195
        ps_enc_ctxt->s_module_ctxt.pv_me_ctxt,
4897
195
        1,
4898
195
        &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_wd,
4899
195
        &ps_enc_ctxt->s_frm_ctb_prms.i4_cu_aligned_pic_ht);
4900
195
    i4_num_instance = ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
4901
195
                          .i4_num_bitrate_instances;
4902
390
    for(i = 0; i < i4_num_instance; i++)
4903
195
    {
4904
195
        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
195
        if(i == 0)
4909
195
        {
4910
195
            i4_id = ps_enc_ctxt->i4_ref_mbr_id;
4911
195
        }
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
195
        ihevce_populate_vps(
4922
195
            ps_enc_ctxt,
4923
195
            &ps_enc_ctxt->as_vps[i],
4924
195
            &ps_enc_ctxt->s_runtime_src_prms,
4925
195
            &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4926
195
            &ps_enc_ctxt->s_runtime_coding_prms,
4927
195
            &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4928
195
            ps_enc_ctxt->ps_stat_prms,
4929
195
            i4_resolution_id);
4930
4931
        /* populate sps based on encoder configuration and tools */
4932
195
        ihevce_populate_sps(
4933
195
            ps_enc_ctxt,
4934
195
            &ps_enc_ctxt->as_sps[i],
4935
195
            &ps_enc_ctxt->as_vps[i],
4936
195
            &ps_enc_ctxt->s_runtime_src_prms,
4937
195
            &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4938
195
            &ps_enc_ctxt->s_runtime_coding_prms,
4939
195
            &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4940
195
            &ps_enc_ctxt->s_frm_ctb_prms,
4941
195
            ps_enc_ctxt->ps_stat_prms,
4942
195
            i4_resolution_id);
4943
4944
        /* populate pps based on encoder configuration and tools */
4945
195
        ihevce_populate_pps(
4946
195
            &ps_enc_ctxt->as_pps[i],
4947
195
            &ps_enc_ctxt->as_sps[i],
4948
195
            &ps_enc_ctxt->s_runtime_src_prms,
4949
195
            &ps_enc_ctxt->ps_stat_prms->s_out_strm_prms,
4950
195
            &ps_enc_ctxt->s_runtime_coding_prms,
4951
195
            &ps_enc_ctxt->ps_stat_prms->s_config_prms,
4952
195
            ps_enc_ctxt->ps_stat_prms,
4953
195
            i4_id,
4954
195
            i4_resolution_id,
4955
195
            ps_enc_ctxt->ps_tile_params_base,
4956
195
            &ps_enc_ctxt->ai4_column_width_array[0],
4957
195
            &ps_enc_ctxt->ai4_row_height_array[0]);
4958
4959
        // if(ps_enc_ctxt->as_sps[i].i1_vui_parameters_present_flag == 1)
4960
195
        {
4961
195
            WORD32 error_code = ihevce_populate_vui(
4962
195
                                    &ps_enc_ctxt->as_sps[i].s_vui_parameters,
4963
195
                                    &ps_enc_ctxt->as_sps[i],
4964
195
                                    &ps_enc_ctxt->s_runtime_src_prms,
4965
195
                                    &ps_enc_ctxt->ps_stat_prms->s_vui_sei_prms,
4966
195
                                    i4_resolution_id,
4967
195
                                    &ps_enc_ctxt->s_runtime_tgt_params,
4968
195
                                    ps_enc_ctxt->ps_stat_prms,
4969
195
                                    i4_id);
4970
195
            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
195
        }
4976
195
    }
4977
4978
195
    osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4979
    /* run the loop over all bit-rate instnaces */
4980
390
    for(i = 0; i < i4_num_instance; i++)
4981
195
    {
4982
        /*HEVC_RC Do one time initialization of rate control*/
4983
195
        ihevce_rc_init(
4984
195
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4985
195
            &ps_enc_ctxt->s_runtime_src_prms,
4986
195
            &ps_enc_ctxt->s_runtime_tgt_params,
4987
195
            &ps_enc_ctxt->s_rc_quant,
4988
195
            &ps_enc_ctxt->ps_stat_prms->s_sys_api,
4989
195
            &ps_enc_ctxt->ps_stat_prms->s_lap_prms,
4990
195
            ps_enc_ctxt->i4_max_fr_enc_loop_parallel_rc);
4991
4992
195
        ihevce_vbv_complaince_init_level(
4993
195
            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[i],
4994
195
            &ps_enc_ctxt->as_sps[i].s_vui_parameters);
4995
195
    }
4996
195
    osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
4997
195
}
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.93k
{
5029
2.93k
    WORD32 end_flag = 0;
5030
2.93k
    WORD32 cur_qp;
5031
    //recon_pic_buf_t *ps_frm_recon;
5032
2.93k
    WORD32 first_field = 1;
5033
2.93k
    WORD32 i4_field_pic = ps_enc_ctxt->s_runtime_src_prms.i4_field_pic;
5034
2.93k
    WORD32 i4_decomp_lyrs_idx = 0;
5035
2.93k
    WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
5036
2.93k
    WORD32 slice_type = ISLICE;
5037
2.93k
    WORD32 nal_type;
5038
2.93k
    WORD32 min_cu_size;
5039
5040
2.93k
    WORD32 stasino_enabled;
5041
5042
    /* copy the time stamps from inp to entropy inp */
5043
2.93k
    ps_curr_out->i4_inp_timestamp_low = ps_curr_inp->s_input_buf.i4_inp_timestamp_low;
5044
2.93k
    ps_curr_out->i4_inp_timestamp_high = ps_curr_inp->s_input_buf.i4_inp_timestamp_high;
5045
2.93k
    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.93k
    min_cu_size = ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_min_log2_cu_size;
5049
5050
2.93k
    min_cu_size = 1 << min_cu_size;
5051
5052
2.93k
    ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd =
5053
2.93k
        ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd +
5054
2.93k
        SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_y_wd, min_cu_size);
5055
5056
2.93k
    ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht =
5057
2.93k
        ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht +
5058
2.93k
        SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht, min_cu_size);
5059
5060
2.93k
    ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd =
5061
2.93k
        ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd +
5062
2.93k
        SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_wd, min_cu_size);
5063
5064
2.93k
    if(IV_YUV_420SP_UV == ps_enc_ctxt->ps_stat_prms->s_src_prms.i4_chr_format)
5065
2.93k
    {
5066
2.93k
        ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht =
5067
2.93k
            ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht +
5068
2.93k
            SET_CTB_ALIGN(ps_curr_inp->s_lap_out.s_input_buf.i4_uv_ht, (min_cu_size >> 1));
5069
2.93k
    }
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.93k
    end_flag = ps_curr_inp->s_lap_out.i4_end_flag;
5079
2.93k
    ps_curr_out->i4_end_flag = end_flag;
5080
2.93k
    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.93k
    {
5086
2.93k
        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.93k
        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.93k
        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.93k
        else
5117
2.93k
        {
5118
2.93k
            if(ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5119
408
            {
5120
408
                nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5121
408
                               ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RASL_R : NAL_RASL_N)
5122
408
                               : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TRAIL_R : NAL_TRAIL_N);
5123
408
            }
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.52k
            else
5127
2.52k
            {
5128
2.52k
                nal_type = (cur_poc < ps_curr_inp->s_lap_out.i4_assoc_IRAP_poc)
5129
2.52k
                               ? (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_RADL_R : NAL_RADL_N)
5130
2.52k
                               : (ps_curr_inp->s_lap_out.i4_is_ref_pic ? NAL_TRAIL_R : NAL_TRAIL_N);
5131
2.52k
            }
5132
2.93k
        }
5133
5134
2.93k
        switch(ps_curr_inp->s_lap_out.i4_pic_type)
5135
2.93k
        {
5136
450
        case IV_IDR_FRAME:
5137
            /*  IDR pic */
5138
450
            slice_type = ISLICE;
5139
450
            nal_type = NAL_IDR_W_LP;
5140
450
            cur_poc = 0;
5141
450
            ps_enc_ctxt->i4_cra_poc = cur_poc;
5142
450
            break;
5143
5144
133
        case IV_I_FRAME:
5145
133
            slice_type = ISLICE;
5146
5147
133
            if(ps_curr_inp->s_lap_out.i4_is_cra_pic)
5148
68
            {
5149
68
                nal_type = NAL_CRA;
5150
68
            }
5151
5152
133
            ps_enc_ctxt->i4_cra_poc = cur_poc;
5153
133
            break;
5154
5155
2.31k
        case IV_P_FRAME:
5156
2.31k
            slice_type = PSLICE;
5157
2.31k
            break;
5158
5159
43
        case IV_B_FRAME:
5160
            /* TODO : Mark the nal type as NAL_TRAIL_N for non ref pics */
5161
43
            slice_type = BSLICE;
5162
43
            break;
5163
5164
0
        default:
5165
            /* This should never occur */
5166
0
            ASSERT(0);
5167
2.93k
        }
5168
5169
        /* number of merge candidates and error metric chosen based on quality preset */
5170
2.93k
        switch(ps_curr_inp->s_lap_out.i4_quality_preset)
5171
2.93k
        {
5172
697
        case IHEVCE_QUALITY_P0:
5173
697
            max_merge_candidates = 5;
5174
697
            break;
5175
5176
207
        case IHEVCE_QUALITY_P2:
5177
207
            max_merge_candidates = 5;
5178
207
            break;
5179
5180
1.01k
        case IHEVCE_QUALITY_P3:
5181
1.01k
            max_merge_candidates = 3;
5182
1.01k
            break;
5183
5184
288
        case IHEVCE_QUALITY_P4:
5185
381
        case IHEVCE_QUALITY_P5:
5186
771
        case IHEVCE_QUALITY_P6:
5187
1.01k
        case IHEVCE_QUALITY_P7:
5188
1.01k
            max_merge_candidates = 2;
5189
1.01k
            break;
5190
5191
0
        default:
5192
0
            ASSERT(0);
5193
2.93k
        }
5194
5195
        /* acquire mutex lock for rate control calls */
5196
2.93k
        osal_mutex_lock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
5197
2.93k
        {
5198
2.93k
            ps_curr_inp->s_rc_lap_out.i4_num_pels_in_frame_considered =
5199
2.93k
                ps_curr_inp->s_lap_out.s_input_buf.i4_y_ht *
5200
2.93k
                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.93k
            ps_curr_inp->s_rc_lap_out.ps_frame_info = &ps_curr_inp->s_frame_info;
5204
5205
2.93k
            ps_curr_inp->s_rc_lap_out.i4_is_bottom_field = ps_curr_inp->s_input_buf.i4_bottom_field;
5206
2.93k
            if(ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode == 3)
5207
965
            {
5208
                /*for constant qp use same qp*/
5209
                /*HEVC_RC query rate control for qp*/
5210
965
                cur_qp = ihevce_rc_pre_enc_qp_query(
5211
965
                    (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
5212
965
                    &ps_curr_inp->s_rc_lap_out,
5213
965
                    0);
5214
965
            }
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.93k
        }
5221
        /* release mutex lock after rate control calls */
5222
2.93k
        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.93k
        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.93k
        ps_curr_out->s_slice_hdr.pu4_entry_point_offset = NULL;
5230
5231
        /* derive the flag which indicates if stasino is enabled */
5232
2.93k
        stasino_enabled = (ps_enc_ctxt->s_runtime_coding_prms.i4_vqet &
5233
2.93k
                           (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.93k
        ihevce_populate_slice_header(
5239
2.93k
            &ps_curr_out->s_slice_hdr,
5240
2.93k
            &ps_enc_ctxt->as_pps[0],
5241
2.93k
            &ps_enc_ctxt->as_sps[0],
5242
2.93k
            nal_type,
5243
2.93k
            slice_type,
5244
2.93k
            0,
5245
2.93k
            0,
5246
2.93k
            ps_curr_inp->s_lap_out.i4_poc,
5247
2.93k
            cur_qp,
5248
2.93k
            max_merge_candidates,
5249
2.93k
            ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass,
5250
2.93k
            ps_enc_ctxt->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
5251
2.93k
                .i4_quality_preset,
5252
2.93k
            stasino_enabled);
5253
5254
2.93k
        ps_curr_out->i4_slice_nal_type = nal_type;
5255
5256
2.93k
        ps_curr_out->s_slice_hdr.u4_nuh_temporal_id = 0;
5257
5258
2.93k
        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.93k
        ps_curr_out->ps_pps = &ps_enc_ctxt->as_pps[0];
5267
2.93k
        ps_curr_out->ps_sps = &ps_enc_ctxt->as_sps[0];
5268
2.93k
        ps_curr_out->ps_vps = &ps_enc_ctxt->as_vps[0];
5269
2.93k
    }
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.93k
    ps_curr_out->s_sei.i1_sei_parameters_present_flag = 0;
5277
2.93k
    ps_curr_out->s_sei.i1_buf_period_params_present_flag = 0;
5278
2.93k
    ps_curr_out->s_sei.i1_pic_timing_params_present_flag = 0;
5279
2.93k
    ps_curr_out->s_sei.i1_recovery_point_params_present_flag = 0;
5280
2.93k
    ps_curr_out->s_sei.i1_decoded_pic_hash_sei_flag = 0;
5281
2.93k
    ps_curr_out->s_sei.i4_sei_mastering_disp_colour_vol_params_present_flags = 0;
5282
5283
2.93k
    if(ps_enc_ctxt->ps_stat_prms->s_out_strm_prms.i4_sei_enable_flag == 1)
5284
808
    {
5285
        /* insert buffering period, display volume, recovery point only at irap points */
5286
808
        WORD32 insert_per_irap =
5287
808
            ((slice_type == ISLICE) &&
5288
202
             (((NAL_IDR_N_LP == nal_type) || (NAL_CRA == nal_type)) || (NAL_IDR_W_LP == nal_type)));
5289
5290
808
        ps_curr_out->s_sei.i1_sei_parameters_present_flag = 1;
5291
5292
        /* populate Sei buffering period based on encoder configuration and tools */
5293
808
        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
808
        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
808
        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
808
        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
808
        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
808
    }
5353
2.93k
#endif
5354
5355
    /* For interlace pictures, first_field depends on topfield_first and bottom field */
5356
2.93k
    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.93k
    ihevce_get_frame_lambda_prms(
5364
2.93k
        ps_enc_ctxt,
5365
2.93k
        ps_curr_out,
5366
2.93k
        cur_qp,
5367
2.93k
        first_field,
5368
2.93k
        ps_curr_inp->s_lap_out.i4_is_ref_pic,
5369
2.93k
        ps_curr_inp->s_lap_out.i4_temporal_lyr_id,
5370
2.93k
        lamda_modifier_for_I_pic[4] /*mean TRF*/,
5371
2.93k
        0,
5372
2.93k
        PRE_ENC_LAMBDA_TYPE);
5373
    /* Coarse ME and Decomp buffers sharing */
5374
2.93k
    {
5375
2.93k
        UWORD8 *apu1_lyr_bufs[MAX_NUM_HME_LAYERS];
5376
2.93k
        WORD32 ai4_lyr_buf_strd[MAX_NUM_HME_LAYERS];
5377
5378
        /* get the Decomposition frame buffer from ME */
5379
2.93k
        i4_decomp_lyrs_idx = ihevce_coarse_me_get_lyr_buf_desc(
5380
2.93k
            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.93k
        ihevce_decomp_pre_intra_frame_init(
5383
2.93k
            ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
5384
2.93k
            &apu1_lyr_bufs[0],
5385
2.93k
            &ai4_lyr_buf_strd[0],
5386
2.93k
            ps_curr_out->ps_layer1_buf,
5387
2.93k
            ps_curr_out->ps_layer2_buf,
5388
2.93k
            ps_curr_out->ps_ed_ctb_l1,
5389
2.93k
            ps_curr_out->as_lambda_prms[0].i4_ol_sad_lambda_qf,
5390
2.93k
            ps_curr_out->ps_ctb_analyse);
5391
2.93k
    }
5392
5393
    /* -------------------------------------------------------- */
5394
    /*   Preparing Pre encode Passes Job Queue                  */
5395
    /* -------------------------------------------------------- */
5396
2.93k
    ihevce_prepare_pre_enc_job_queue(ps_enc_ctxt, ps_curr_inp, i4_ping_pong);
5397
5398
    /*assign return variables */
5399
2.93k
    *pi4_end_flag_ret = end_flag;
5400
2.93k
    *pi4_cur_qp_ret = cur_qp;
5401
2.93k
    *pi4_decomp_lyr_idx = i4_decomp_lyrs_idx;
5402
    //*pps_frm_recon_ret = ps_frm_recon;
5403
2.93k
}
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.93k
{
5436
    /* local variables */
5437
2.93k
    recon_pic_buf_t *ps_frm_recon;
5438
2.93k
    coarse_me_master_ctxt_t *ps_ctxt = NULL;
5439
2.93k
    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.93k
    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.93k
    {
5445
2.93k
        WORD32 ctr;
5446
5447
2.93k
        ps_frm_recon = NULL;
5448
7.76k
        for(ctr = 0; ctr < ps_enc_ctxt->i4_pre_enc_num_buf_recon_q; ctr++)
5449
7.76k
        {
5450
7.76k
            if(1 == ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr]->i4_is_free)
5451
2.93k
            {
5452
2.93k
                ps_frm_recon = ps_enc_ctxt->pps_pre_enc_recon_buf_q[ctr];
5453
2.93k
                break;
5454
2.93k
            }
5455
7.76k
        }
5456
2.93k
    }
5457
    /* should not be NULL */
5458
2.93k
    ASSERT(ps_frm_recon != NULL);
5459
5460
    /* populate reference /recon params based on LAP output */
5461
2.93k
    ps_frm_recon->i4_is_free = 0;
5462
    /* top first field is set to 1 by application */
5463
2.93k
    ps_frm_recon->i4_topfield_first = ps_curr_inp->s_input_buf.i4_topfield_first;
5464
2.93k
    ps_frm_recon->i4_poc = ps_curr_inp->s_lap_out.i4_poc;
5465
2.93k
    ps_frm_recon->i4_pic_type = ps_curr_inp->s_lap_out.i4_pic_type;
5466
2.93k
    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.93k
    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.93k
    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.93k
    ps_frm_recon->i4_deblk_pad_hpel_cur_pic = ps_frm_recon->i4_is_reference ||
5476
28
                                              (ps_enc_ctxt->ps_stat_prms->i4_save_recon);
5477
5478
    /* set the width, height and stride to defalut values */
5479
2.93k
    ps_frm_recon->s_yuv_buf_desc.i4_y_ht = 0;
5480
2.93k
    ps_frm_recon->s_yuv_buf_desc.i4_uv_ht = 0;
5481
2.93k
    ps_frm_recon->s_yuv_buf_desc.i4_y_wd = 0;
5482
2.93k
    ps_frm_recon->s_yuv_buf_desc.i4_uv_wd = 0;
5483
2.93k
    ps_frm_recon->s_yuv_buf_desc.i4_y_strd = 0;
5484
2.93k
    ps_frm_recon->s_yuv_buf_desc.i4_uv_strd = 0;
5485
5486
    /* register the Layer1 MV bank pointer with ME module */
5487
2.93k
    ihevce_coarse_me_set_lyr1_mv_bank(
5488
2.93k
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
5489
2.93k
        ps_curr_inp,
5490
2.93k
        ps_curr_out->pv_me_mv_bank,
5491
2.93k
        ps_curr_out->pv_me_ref_idx,
5492
2.93k
        i4_decomp_lyrs_idx);
5493
5494
    /* Coarse picture level init of ME */
5495
2.93k
    ihevce_coarse_me_frame_init(
5496
2.93k
        ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
5497
2.93k
        ps_enc_ctxt->ps_stat_prms,
5498
2.93k
        &ps_enc_ctxt->s_frm_ctb_prms,
5499
2.93k
        &ps_curr_out->as_lambda_prms[0],
5500
2.93k
        ps_enc_ctxt->i4_pre_enc_num_ref_l0,
5501
2.93k
        ps_enc_ctxt->i4_pre_enc_num_ref_l1,
5502
2.93k
        ps_enc_ctxt->i4_pre_enc_num_ref_l0_active,
5503
2.93k
        ps_enc_ctxt->i4_pre_enc_num_ref_l1_active,
5504
2.93k
        &ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong][LIST_0][0],
5505
2.93k
        &ps_enc_ctxt->aps_pre_enc_ref_lists[i4_ping_pong][LIST_1][0],
5506
2.93k
        ps_curr_inp,
5507
2.93k
        i4_cur_qp,
5508
2.93k
        ps_curr_out->ps_layer1_buf,
5509
2.93k
        ps_curr_out->ps_ed_ctb_l1,
5510
2.93k
        ps_curr_out->pu1_me_reverse_map_info,
5511
2.93k
        ps_curr_inp->s_lap_out.i4_temporal_lyr_id);
5512
5513
    /*assign return variables */
5514
2.93k
    *pps_frm_recon_ret = ps_frm_recon;
5515
2.93k
}
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.93k
{
5526
2.93k
    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.93k
    WORD32 is_curr_bslice = (ps_curr_out->s_slice_hdr.i1_slice_type == BSLICE);
5528
2.93k
#if MODULATION_OVER_LAP
5529
2.93k
    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.93k
    WORD32 i4_delay_loop = ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe;
5534
2.93k
    WORD32 i, j;
5535
5536
2.93k
    ps_curr_out->i8_acc_frame_8x8_sum_act_sqr = 0;
5537
2.93k
    ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength = 0;
5538
8.81k
    for(i = 0; i < 2; i++)
5539
5.87k
    {
5540
5.87k
        ps_curr_out->i8_acc_frame_8x8_sum_act[i] = 0;
5541
5.87k
        ps_curr_out->i4_acc_frame_8x8_num_blks[i] = 0;
5542
5.87k
        ps_curr_out->i8_acc_frame_16x16_sum_act[i] = 0;
5543
5.87k
        ps_curr_out->i4_acc_frame_16x16_num_blks[i] = 0;
5544
5.87k
        ps_curr_out->i8_acc_frame_32x32_sum_act[i] = 0;
5545
5.87k
        ps_curr_out->i4_acc_frame_32x32_num_blks[i] = 0;
5546
5.87k
    }
5547
2.93k
    ps_curr_out->i8_acc_frame_16x16_sum_act[i] = 0;
5548
2.93k
    ps_curr_out->i4_acc_frame_16x16_num_blks[i] = 0;
5549
2.93k
    ps_curr_out->i8_acc_frame_32x32_sum_act[i] = 0;
5550
2.93k
    ps_curr_out->i4_acc_frame_32x32_num_blks[i] = 0;
5551
5552
2.93k
    if(!is_curr_bslice)
5553
2.89k
    {
5554
2.89k
        for(i = 0; i < loop_lap2; i++)
5555
2.89k
        {
5556
2.89k
            WORD32 ipe_idx_tmp = (i4_cur_ipe_idx + i) % i4_delay_loop;
5557
2.89k
            ihevce_lap_enc_buf_t *ps_in = ps_enc_ctxt->s_multi_thrd.aps_curr_inp_pre_enc[ipe_idx_tmp];
5558
2.89k
            pre_enc_me_ctxt_t *ps_out = ps_enc_ctxt->s_multi_thrd.aps_curr_out_pre_enc[ipe_idx_tmp];
5559
2.89k
            UWORD8 is_bslice = (ps_out->s_slice_hdr.i1_slice_type == BSLICE);
5560
5561
2.89k
            if(!is_bslice)
5562
2.89k
            {
5563
2.89k
                ps_curr_out->i8_acc_frame_8x8_sum_act_sqr += ps_out->u8_curr_frame_8x8_sum_act_sqr;
5564
2.89k
                ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength += ps_out->i4_curr_frame_8x8_sum_act_for_strength[0];
5565
8.68k
                for(j = 0; j < 2; j++)
5566
5.78k
                {
5567
5.78k
                    ps_curr_out->i8_acc_frame_8x8_sum_act[j] += ps_out->i8_curr_frame_8x8_sum_act[j];
5568
5.78k
                    ps_curr_out->i4_acc_frame_8x8_num_blks[j] += ps_out->i4_curr_frame_8x8_num_blks[j];
5569
5.78k
                    ps_curr_out->i8_acc_frame_16x16_sum_act[j] += ps_out->i8_curr_frame_16x16_sum_act[j];
5570
5.78k
                    ps_curr_out->i4_acc_frame_16x16_num_blks[j] += ps_out->i4_curr_frame_16x16_num_blks[j];
5571
5.78k
                    ps_curr_out->i8_acc_frame_32x32_sum_act[j] += ps_out->i8_curr_frame_32x32_sum_act[j];
5572
5.78k
                    ps_curr_out->i4_acc_frame_32x32_num_blks[j] += ps_out->i4_curr_frame_32x32_num_blks[j];
5573
5.78k
                }
5574
2.89k
                ps_curr_out->i8_acc_frame_16x16_sum_act[j] += ps_out->i8_curr_frame_16x16_sum_act[j];
5575
2.89k
                ps_curr_out->i4_acc_frame_16x16_num_blks[j] += ps_out->i4_curr_frame_16x16_num_blks[j];
5576
2.89k
                ps_curr_out->i8_acc_frame_32x32_sum_act[j] += ps_out->i8_curr_frame_32x32_sum_act[j];
5577
2.89k
                ps_curr_out->i4_acc_frame_32x32_num_blks[j] += ps_out->i4_curr_frame_32x32_num_blks[j];
5578
2.89k
            }
5579
2.89k
            if(NULL == ps_in->s_rc_lap_out.ps_rc_lap_out_next_encode)
5580
2.89k
                break;
5581
2.89k
        }
5582
5583
11.5k
        for(j = 0; j < 3; j++)
5584
8.68k
        {
5585
8.68k
            if(j < 2)
5586
8.68k
                ASSERT(0 != ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5587
8.68k
            ASSERT(0 != ps_curr_out->i4_acc_frame_16x16_num_blks[j]);
5588
8.68k
            ASSERT(0 != ps_curr_out->i4_acc_frame_32x32_num_blks[j]);
5589
5590
31.8k
#define AVG_ACTIVITY(a, b, c) a = ((b + (c >> 1)) / c)
5591
5592
8.68k
            if(j < 2)
5593
5.78k
            {
5594
5.78k
                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.78k
                else
5599
5.78k
                {
5600
5.78k
                    AVG_ACTIVITY(ps_curr_out->i8_curr_frame_8x8_sum_act_for_strength,
5601
5.78k
                                 ps_curr_out->i8_acc_frame_8x8_sum_act_for_strength,
5602
5.78k
                                 ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5603
5.78k
                    AVG_ACTIVITY(ps_curr_out->i8_curr_frame_8x8_avg_act[j],
5604
5.78k
                                 ps_curr_out->i8_acc_frame_8x8_sum_act[j],
5605
5.78k
                                 ps_curr_out->i4_acc_frame_8x8_num_blks[j]);
5606
5.78k
                    ps_curr_out->ld_curr_frame_8x8_log_avg[j] =
5607
5.78k
                        fast_log2(1 + ps_curr_out->i8_curr_frame_8x8_avg_act[j]);
5608
5.78k
                }
5609
5.78k
            }
5610
5611
8.68k
            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.68k
            else
5616
8.68k
            {
5617
8.68k
                AVG_ACTIVITY(ps_curr_out->i8_curr_frame_16x16_avg_act[j],
5618
8.68k
                             ps_curr_out->i8_acc_frame_16x16_sum_act[j],
5619
8.68k
                             ps_curr_out->i4_acc_frame_16x16_num_blks[j]);
5620
8.68k
                ps_curr_out->ld_curr_frame_16x16_log_avg[j] =
5621
8.68k
                    fast_log2(1 + ps_curr_out->i8_curr_frame_16x16_avg_act[j]);
5622
8.68k
            }
5623
5624
8.68k
            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.68k
            else
5629
8.68k
            {
5630
8.68k
                AVG_ACTIVITY(ps_curr_out->i8_curr_frame_32x32_avg_act[j],
5631
8.68k
                             ps_curr_out->i8_acc_frame_32x32_sum_act[j],
5632
8.68k
                             ps_curr_out->i4_acc_frame_32x32_num_blks[j]);
5633
8.68k
                ps_curr_out->ld_curr_frame_32x32_log_avg[j] =
5634
8.68k
                    fast_log2(1 + ps_curr_out->i8_curr_frame_32x32_avg_act[j]);
5635
8.68k
            }
5636
8.68k
        }
5637
5638
        /* store the avg activity for B pictures */
5639
2.89k
#if POW_OPT
5640
2.89k
        ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_8x8_log_avg[0];
5641
2.89k
        ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_8x8_log_avg[1];
5642
2.89k
        ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_16x16_log_avg[0];
5643
2.89k
        ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_16x16_log_avg[1];
5644
2.89k
        ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[2] = ps_curr_out->ld_curr_frame_16x16_log_avg[2];
5645
2.89k
        ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[0] = ps_curr_out->ld_curr_frame_32x32_log_avg[0];
5646
2.89k
        ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[1] = ps_curr_out->ld_curr_frame_32x32_log_avg[1];
5647
2.89k
        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.89k
        {
5661
2.89k
            LWORD64 i8_mean, i8_mean_sqr, i8_variance;
5662
2.89k
            LWORD64 i8_deviation;
5663
2.89k
            WORD32 i4_mod_factor;
5664
2.89k
            float f_strength;
5665
5666
2.89k
            if(ps_curr_out->i4_acc_frame_8x8_num_blks[0] > 0)
5667
2.89k
            {
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.89k
                AVG_ACTIVITY(i8_mean_sqr, ps_curr_out->i8_acc_frame_8x8_sum_act_sqr,
5673
2.89k
                             ps_curr_out->i4_acc_frame_8x8_num_blks[0]);
5674
2.89k
#endif
5675
2.89k
                i8_mean = ps_curr_out->i8_curr_frame_8x8_sum_act_for_strength;
5676
2.89k
                i8_variance = i8_mean_sqr - (i8_mean * i8_mean);
5677
2.89k
                i8_deviation = sqrt(i8_variance);
5678
5679
2.89k
#if STRENGTH_BASED_ON_DEVIATION
5680
2.89k
                if(i8_deviation <= REF_MOD_DEVIATION)
5681
1.71k
                {
5682
1.71k
                    f_strength = ((i8_deviation - BELOW_REF_DEVIATION) * REF_MOD_STRENGTH) / (REF_MOD_DEVIATION - BELOW_REF_DEVIATION);
5683
1.71k
                }
5684
1.17k
                else
5685
1.17k
                {
5686
1.17k
                    f_strength = ((i8_deviation - ABOVE_REF_DEVIATION) * REF_MOD_STRENGTH) / (REF_MOD_DEVIATION - ABOVE_REF_DEVIATION);
5687
1.17k
                }
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.89k
                i4_mod_factor = (WORD32)(i8_deviation / 60);
5692
2.89k
                f_strength = CLIP3(f_strength, 0.0, REF_MAX_STRENGTH);
5693
2.89k
            }
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.89k
            ps_curr_out->ai4_mod_factor_derived_by_variance[0] = i4_mod_factor;
5701
2.89k
            ps_curr_out->ai4_mod_factor_derived_by_variance[1] = i4_mod_factor;
5702
2.89k
            ps_curr_out->f_strength = f_strength;
5703
5704
2.89k
            ps_enc_ctxt->ai4_mod_factor_derived_by_variance[0] = i4_mod_factor;
5705
2.89k
            ps_enc_ctxt->ai4_mod_factor_derived_by_variance[1] = i4_mod_factor;
5706
2.89k
            ps_enc_ctxt->f_strength = f_strength;
5707
2.89k
        }
5708
2.89k
    }
5709
43
    else
5710
43
    {
5711
43
        ps_curr_out->ai4_mod_factor_derived_by_variance[0] = ps_enc_ctxt->ai4_mod_factor_derived_by_variance[0];
5712
43
        ps_curr_out->ai4_mod_factor_derived_by_variance[1] = ps_enc_ctxt->ai4_mod_factor_derived_by_variance[1];
5713
43
        ps_curr_out->f_strength = ps_enc_ctxt->f_strength;
5714
5715
        /* copy the prev avg activity from Tid 0 for B pictures*/
5716
43
#if POW_OPT
5717
43
        ps_curr_out->ld_curr_frame_8x8_log_avg[0] = ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[0];
5718
43
        ps_curr_out->ld_curr_frame_8x8_log_avg[1] = ps_enc_ctxt->ald_lap2_8x8_log_avg_act_from_T0[1];
5719
43
        ps_curr_out->ld_curr_frame_16x16_log_avg[0] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[0];
5720
43
        ps_curr_out->ld_curr_frame_16x16_log_avg[1] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[1];
5721
43
        ps_curr_out->ld_curr_frame_16x16_log_avg[2] = ps_enc_ctxt->ald_lap2_16x16_log_avg_act_from_T0[2];
5722
43
        ps_curr_out->ld_curr_frame_32x32_log_avg[0] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[0];
5723
43
        ps_curr_out->ld_curr_frame_32x32_log_avg[1] = ps_enc_ctxt->ald_lap2_32x32_log_avg_act_from_T0[1];
5724
43
        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
43
    }
5736
2.93k
#undef AVG_ACTIVITY
5737
2.93k
}
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
195
{
5758
195
    frm_proc_thrd_ctxt_t *ps_thrd_ctxt = (frm_proc_thrd_ctxt_t *)pv_frm_proc_thrd_ctxt;
5759
195
    ihevce_hle_ctxt_t *ps_hle_ctxt = ps_thrd_ctxt->ps_hle_ctxt;
5760
195
    enc_ctxt_t *ps_enc_ctxt = (enc_ctxt_t *)ps_thrd_ctxt->pv_enc_ctxt;
5761
195
    multi_thrd_ctxt_t *ps_multi_thrd = &ps_enc_ctxt->s_multi_thrd;
5762
195
    WORD32 i4_thrd_id = ps_thrd_ctxt->i4_thrd_id;
5763
195
    WORD32 i4_resolution_id = ps_enc_ctxt->i4_resolution_id;
5764
195
    WORD32 i4_end_flag = 0;
5765
195
    WORD32 i4_out_flush_flag = 0;
5766
195
    WORD32 i4_cur_decomp_idx = 0;
5767
195
    WORD32 i4_cur_coarse_me_idx = 0;
5768
195
    WORD32 i4_cur_ipe_idx = 0;
5769
195
    ihevce_lap_enc_buf_t *ps_lap_inp_buf = NULL;
5770
195
    void *pv_dep_mngr_prev_frame_pre_enc_l1 = ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_l1;
5771
195
    void *pv_dep_mngr_prev_frame_pre_enc_l0 = ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_l0;
5772
195
    void *pv_dep_mngr_prev_frame_pre_enc_coarse_me =
5773
195
        ps_multi_thrd->pv_dep_mngr_prev_frame_pre_enc_coarse_me;
5774
195
    WORD32 i4_num_buf_prod_for_l0_ipe = 0;
5775
195
    WORD32 i4_decomp_end_flag = 0;
5776
5777
195
    (void)ps_hle_ctxt;
5778
195
    (void)i4_resolution_id;
5779
5780
    /* ---------- Processing Loop until Flush command is received --------- */
5781
3.32k
    while(0 == i4_end_flag)
5782
3.13k
    {
5783
        /* Wait till previous frame(instance)'s decomp_intra is processed */
5784
3.13k
        {
5785
3.13k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l1, i4_thrd_id);
5786
3.13k
        }
5787
5788
        /* ----------------------------------------------------------- */
5789
        /*     decomp pre_intra init                                   */
5790
        /* ----------------------------------------------------------- */
5791
5792
        /****** Lock the critical section for decomp pre_intra init ******/
5793
3.13k
        {
5794
3.13k
            WORD32 i4_status;
5795
5796
3.13k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_init);
5797
3.13k
            if(OSAL_SUCCESS != i4_status)
5798
0
                return 0;
5799
3.13k
        }
5800
5801
3.13k
        ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_decomp_idx] = 0;
5802
5803
        /* init */
5804
3.13k
        if((ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] == 0) &&
5805
3.13k
           (0 == i4_decomp_end_flag))
5806
3.13k
        {
5807
3.13k
            ihevce_lap_enc_buf_t *ps_curr_inp = NULL;
5808
3.13k
            pre_enc_me_ctxt_t *ps_curr_out = NULL;
5809
3.13k
            WORD32 in_buf_id;
5810
3.13k
            WORD32 out_buf_id;
5811
5812
3.13k
            do
5813
3.26k
            {
5814
3.26k
                ps_lap_inp_buf = NULL;
5815
3.26k
                if(0 == ps_multi_thrd->i4_last_inp_buf)
5816
3.13k
                {
5817
                    /* ------- get input buffer input data que ---------- */
5818
3.13k
                    ps_lap_inp_buf = (ihevce_lap_enc_buf_t *)ihevce_q_get_filled_buff(
5819
3.13k
                        (void *)ps_enc_ctxt,
5820
3.13k
                        IHEVCE_INPUT_DATA_CTRL_Q,
5821
3.13k
                        &in_buf_id,
5822
3.13k
                        BUFF_QUE_BLOCKING_MODE);
5823
3.13k
                    ps_multi_thrd->i4_last_inp_buf = ihevce_check_last_inp_buf(
5824
3.13k
                        (WORD32 *)ps_lap_inp_buf->s_input_buf.pv_synch_ctrl_bufs);
5825
3.13k
                }
5826
5827
3.26k
                ps_curr_inp =
5828
3.26k
                    ihevce_lap_process(ps_enc_ctxt->pv_lap_interface_ctxt, ps_lap_inp_buf);
5829
5830
3.26k
            } while(NULL == ps_curr_inp);
5831
5832
            /* set the flag saying init is done so that other cores dont do it */
5833
3.13k
            ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_decomp_idx] = 1;
5834
5835
3.13k
            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_decomp_idx] = ps_curr_inp;
5836
3.13k
            ps_multi_thrd->ai4_in_buf_id_pre_enc[i4_cur_decomp_idx] =
5837
3.13k
                ps_curr_inp->s_input_buf.i4_buf_id;
5838
5839
            /* ------- get free output buffer from pre-enc/enc buffer que ---------- */
5840
3.13k
            ps_curr_out = (pre_enc_me_ctxt_t *)ihevce_q_get_free_buff(
5841
3.13k
                (void *)ps_enc_ctxt, IHEVCE_PRE_ENC_ME_Q, &out_buf_id, BUFF_QUE_BLOCKING_MODE);
5842
3.13k
            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_decomp_idx] = ps_curr_out;
5843
3.13k
            ps_multi_thrd->ai4_out_buf_id_pre_enc[i4_cur_decomp_idx] = out_buf_id;
5844
5845
3.13k
            if((NULL != ps_curr_inp) && (NULL != ps_curr_out))
5846
3.13k
            {
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
3.13k
                ps_multi_thrd->i4_last_pic_flag = 0;
5850
5851
                /* store the buffer id */
5852
3.13k
                ps_curr_out->i4_buf_id = out_buf_id;
5853
5854
3.13k
                ps_curr_out->i8_acc_num_blks_high_sad = 0;
5855
3.13k
                ps_curr_out->i8_total_blks = 0;
5856
3.13k
                ps_curr_out->i4_is_high_complex_region = -1;
5857
5858
                /* set the parameters for sync b/w pre-encode and encode threads */
5859
3.13k
                ps_curr_out->i4_end_flag = ps_curr_inp->s_lap_out.i4_end_flag;
5860
3.13k
                ps_curr_out->i4_frm_proc_valid_flag = 1;
5861
3.13k
                if(ps_curr_out->i4_end_flag)
5862
195
                {
5863
195
                    ps_curr_out->i4_frm_proc_valid_flag =
5864
195
                        ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag;
5865
195
                    ps_multi_thrd->i4_last_pic_flag = 1;
5866
195
                    ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = 1;
5867
195
                }
5868
3.13k
                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
3.13k
                if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
5876
2.93k
                {
5877
2.93k
                    WORD32 end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx];
5878
2.93k
                    WORD32 cur_qp = 0, count;
5879
5880
2.93k
                    ihevce_pre_enc_init(
5881
2.93k
                        ps_enc_ctxt,
5882
2.93k
                        ps_curr_inp,
5883
2.93k
                        ps_curr_out,
5884
2.93k
                        &end_flag,
5885
2.93k
                        &cur_qp,
5886
2.93k
                        &ps_multi_thrd->ai4_decomp_lyr_buf_idx[i4_cur_decomp_idx],
5887
2.93k
                        i4_cur_decomp_idx);
5888
5889
2.93k
                    ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx] = end_flag;
5890
2.93k
                    ps_multi_thrd->ai4_cur_frame_qp_pre_enc[i4_cur_decomp_idx] = cur_qp;
5891
5892
202k
                    for(count = 0; count < ((HEVCE_MAX_HEIGHT >> 1) / 8); count++)
5893
199k
                    {
5894
199k
                        ps_multi_thrd->aai4_l1_pre_intra_done[i4_cur_decomp_idx][count] = 0;
5895
199k
                    }
5896
2.93k
                }
5897
3.13k
            }
5898
3.13k
        }
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
3.13k
        {
5907
3.13k
            WORD32 i4_status;
5908
3.13k
            i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_init);
5909
5910
3.13k
            if(OSAL_SUCCESS != i4_status)
5911
0
                return 0;
5912
3.13k
        }
5913
3.13k
        if(i4_thrd_id == 0)
5914
3.13k
        {
5915
3.13k
            PROFILE_START(&ps_hle_ctxt->profile_pre_enc_l1l2[i4_resolution_id]);
5916
3.13k
        }
5917
        /* ------------------------------------------------------------ */
5918
        /*        Layer Decomp and Pre Intra Analysis                   */
5919
        /* ------------------------------------------------------------ */
5920
3.13k
        if(0 == i4_decomp_end_flag)
5921
3.13k
        {
5922
3.13k
            pre_enc_me_ctxt_t *ps_curr_out = ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_decomp_idx];
5923
5924
3.13k
            if(1 == ps_curr_out->i4_frm_proc_valid_flag)
5925
2.93k
            {
5926
2.93k
                ihevce_decomp_pre_intra_process(
5927
2.93k
                    ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
5928
2.93k
                    &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_decomp_idx]->s_lap_out,
5929
2.93k
                    &ps_enc_ctxt->s_frm_ctb_prms,
5930
2.93k
                    ps_multi_thrd,
5931
2.93k
                    i4_thrd_id,
5932
2.93k
                    i4_cur_decomp_idx);
5933
2.93k
            }
5934
3.13k
        }
5935
5936
        /* ------------------------------------------------------------ */
5937
        /*        Layer Decomp and Pre Intra Deinit                     */
5938
        /* ------------------------------------------------------------ */
5939
5940
        /****** Lock the critical section for decomp deinit ******/
5941
3.13k
        {
5942
3.13k
            WORD32 i4_status;
5943
3.13k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_decomp_deinit);
5944
5945
3.13k
            if(OSAL_SUCCESS != i4_status)
5946
0
                return 0;
5947
3.13k
        }
5948
5949
3.13k
        ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx]++;
5950
3.13k
        i4_decomp_end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_decomp_idx];
5951
5952
        /* check for last thread condition */
5953
3.13k
        if(ps_multi_thrd->ai4_num_thrds_processed_decomp[i4_cur_decomp_idx] ==
5954
3.13k
           ps_multi_thrd->i4_num_pre_enc_proc_thrds)
5955
3.13k
        {
5956
3.13k
            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
3.13k
            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
3.13k
            ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l1);
5964
3.13k
        }
5965
5966
        /* index increment */
5967
3.13k
        i4_cur_decomp_idx = i4_cur_decomp_idx + 1;
5968
5969
        /* wrap around case */
5970
3.13k
        if(i4_cur_decomp_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
5971
1.51k
        {
5972
1.51k
            i4_cur_decomp_idx = 0;
5973
1.51k
        }
5974
5975
        /****** UnLock the critical section after decomp pre_intra deinit ******/
5976
3.13k
        {
5977
3.13k
            WORD32 i4_status;
5978
3.13k
            i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_decomp_deinit);
5979
5980
3.13k
            if(OSAL_SUCCESS != i4_status)
5981
0
                return 0;
5982
3.13k
        }
5983
5984
        /* ------------------------------------------------------------ */
5985
        /*                     HME Init                                 */
5986
        /* ------------------------------------------------------------ */
5987
5988
        /* Wait till previous frame(instance)'s coarse_me is processed */
5989
3.13k
        {
5990
3.13k
            ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me, i4_thrd_id);
5991
3.13k
        }
5992
5993
        /****** Lock the critical section for hme init ******/
5994
3.13k
        {
5995
3.13k
            WORD32 i4_status;
5996
5997
3.13k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_init);
5998
3.13k
            if(OSAL_SUCCESS != i4_status)
5999
0
                return 0;
6000
3.13k
        }
6001
6002
3.13k
        if(0 == ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx])
6003
3.13k
        {
6004
            /* do the init processing if input frm data is valid */
6005
3.13k
            if(1 ==
6006
3.13k
               ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6007
2.93k
            {
6008
2.93k
                recon_pic_buf_t *ps_frm_recon = NULL;
6009
6010
                /* DPB management for coarse me + HME init */
6011
2.93k
                ihevce_pre_enc_coarse_me_init(
6012
2.93k
                    ps_enc_ctxt,
6013
2.93k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6014
2.93k
                    ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6015
2.93k
                    &ps_frm_recon,
6016
2.93k
                    ps_multi_thrd->ai4_decomp_lyr_buf_idx[i4_cur_coarse_me_idx],
6017
2.93k
                    ps_multi_thrd->ai4_cur_frame_qp_pre_enc[i4_cur_coarse_me_idx],
6018
2.93k
                    i4_cur_coarse_me_idx);
6019
2.93k
            }
6020
6021
3.13k
            ps_multi_thrd->ai4_pre_enc_hme_init_done[i4_cur_coarse_me_idx] = 1;
6022
3.13k
        }
6023
6024
        /****** Unlock the critical section for hme init ******/
6025
3.13k
        {
6026
3.13k
            WORD32 i4_status;
6027
6028
3.13k
            i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_init);
6029
3.13k
            if(OSAL_SUCCESS != i4_status)
6030
0
                return 0;
6031
3.13k
        }
6032
6033
        /* ------------------------------------------------------------ */
6034
        /*  Coarse Motion estimation and early intra-inter decision     */
6035
        /* ------------------------------------------------------------ */
6036
3.13k
        if(1 == ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6037
2.93k
        {
6038
2.93k
            ihevce_coarse_me_process(
6039
2.93k
                ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
6040
2.93k
                ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6041
2.93k
                &ps_enc_ctxt->s_multi_thrd,
6042
2.93k
                i4_thrd_id,
6043
2.93k
                i4_cur_coarse_me_idx);
6044
2.93k
        }
6045
6046
        /* update the end flag */
6047
3.13k
        i4_end_flag = ps_multi_thrd->ai4_end_flag_pre_enc[i4_cur_coarse_me_idx];
6048
3.13k
        i4_out_flush_flag =
6049
3.13k
            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
3.13k
        {
6053
3.13k
            WORD32 i4_status;
6054
3.13k
            i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_hme_deinit);
6055
6056
3.13k
            if(OSAL_SUCCESS != i4_status)
6057
0
                return 0;
6058
3.13k
        }
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
3.13k
        if(1 == ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->i4_frm_proc_valid_flag)
6064
2.93k
        {
6065
2.93k
            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.93k
            {
6071
2.93k
                ihevce_lap_enc_buf_t *ps_curr_inp =
6072
2.93k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx];
6073
6074
2.93k
                if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
6075
2.93k
                {
6076
2.93k
                    WORD32 i4_prev_coarse_me_idx;
6077
6078
                    /* wrap around case */
6079
2.93k
                    if(i4_cur_coarse_me_idx == 0)
6080
1.51k
                    {
6081
1.51k
                        i4_prev_coarse_me_idx = ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe - 1;
6082
1.51k
                    }
6083
1.42k
                    else
6084
1.42k
                    {
6085
1.42k
                        i4_prev_coarse_me_idx = i4_cur_coarse_me_idx - 1;
6086
1.42k
                    }
6087
6088
2.93k
                    ihevce_update_qp_L1_sad_based(
6089
2.93k
                        ps_enc_ctxt,
6090
2.93k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx],
6091
2.93k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_prev_coarse_me_idx],
6092
2.93k
                        ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6093
2.93k
                        ((ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6094
2.93k
                          ps_multi_thrd->i4_num_pre_enc_proc_thrds)));
6095
2.93k
                }
6096
2.93k
            }
6097
            /* check for last thread condition */
6098
2.93k
            if(ps_multi_thrd->ai4_num_thrds_processed_coarse_me[i4_cur_coarse_me_idx] ==
6099
2.93k
               ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6100
2.93k
            {
6101
2.93k
                ihevce_lap_enc_buf_t *ps_curr_inp =
6102
2.93k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_coarse_me_idx];
6103
6104
                /*        Frame END processing                  */
6105
2.93k
                ihevce_coarse_me_frame_end(ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt);
6106
6107
2.93k
                if(1 == ps_curr_inp->s_input_buf.i4_inp_frm_data_valid_flag)
6108
2.93k
                {
6109
2.93k
                    WORD32 i4_enable_noise_detection = 0;
6110
2.93k
                    WORD32 i4_vqet = ps_enc_ctxt->ps_stat_prms->s_coding_tools_prms.i4_vqet;
6111
6112
2.93k
                    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.93k
                    if(1 != ((ps_curr_inp->s_lap_out.i4_pic_type == IV_B_FRAME) &&
6121
43
                             (ps_enc_ctxt->s_lap_stat_prms.ai4_quality_preset[i4_resolution_id] ==
6122
43
                              IHEVCE_QUALITY_P6)))
6123
2.93k
                    {
6124
2.93k
                        ihevce_decomp_pre_intra_curr_frame_pre_intra_deinit(
6125
2.93k
                            ps_enc_ctxt->s_module_ctxt.pv_decomp_pre_intra_ctxt,
6126
2.93k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx],
6127
2.93k
                            &ps_enc_ctxt->s_frm_ctb_prms);
6128
2.93k
                    }
6129
2.93k
                }
6130
6131
2.93k
                ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6132
6133
2.93k
                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.93k
                ihevce_coarse_me_get_lyr1_ctxt(
6137
2.93k
                    ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
6138
2.93k
                    ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_coarse_me_idx]->pv_me_lyr_ctxt,
6139
2.93k
                    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.93k
                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.93k
                ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_coarse_me);
6147
2.93k
            }
6148
6149
2.93k
            i4_num_buf_prod_for_l0_ipe++;
6150
6151
            /* index increment */
6152
2.93k
            i4_cur_coarse_me_idx = i4_cur_coarse_me_idx + 1;
6153
6154
            /* wrap around case */
6155
2.93k
            if(i4_cur_coarse_me_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6156
1.42k
            {
6157
1.42k
                i4_cur_coarse_me_idx = 0;
6158
1.42k
            }
6159
2.93k
        }
6160
195
        else
6161
195
        {
6162
            /* for invalid frame set the processed flag to 1 for L0 IPE */
6163
195
            ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_coarse_me_idx] = 1;
6164
6165
195
            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
195
            i4_num_buf_prod_for_l0_ipe++;
6186
6187
            /* index increment */
6188
195
            i4_cur_coarse_me_idx = i4_cur_coarse_me_idx + 1;
6189
6190
            /* wrap around case */
6191
195
            if(i4_cur_coarse_me_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6192
97
            {
6193
97
                i4_cur_coarse_me_idx = 0;
6194
97
            }
6195
195
        }
6196
6197
        /****** UnLock the critical section after hme deinit ******/
6198
3.13k
        {
6199
3.13k
            WORD32 i4_status;
6200
3.13k
            i4_status =
6201
3.13k
                osal_mutex_unlock(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit);
6202
6203
3.13k
            if(OSAL_SUCCESS != i4_status)
6204
0
                return 0;
6205
3.13k
        }
6206
6207
3.13k
        if(i4_thrd_id == 0)
6208
3.13k
        {
6209
3.13k
            PROFILE_STOP(&ps_hle_ctxt->profile_pre_enc_l1l2[i4_resolution_id], NULL);
6210
3.13k
        }
6211
6212
        /* ----------------------------------------------------------- */
6213
        /*     IPE init and process                                    */
6214
        /* ----------------------------------------------------------- */
6215
3.13k
        if(i4_thrd_id == 0)
6216
3.13k
        {
6217
3.13k
            PROFILE_START(&ps_hle_ctxt->profile_pre_enc_l0ipe[i4_resolution_id]);
6218
3.13k
        }
6219
3.13k
        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
3.13k
        {
6222
3.13k
            do
6223
3.13k
            {
6224
                /* Wait till previous frame(instance)'s IPE is processed */
6225
3.13k
                {
6226
3.13k
                    ihevce_dmgr_chk_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l0, i4_thrd_id);
6227
3.13k
                }
6228
6229
                /* Wait till current frame(instance)'s L1 and below layers are processed */
6230
3.13k
                {
6231
3.13k
                    volatile WORD32 *pi4_cur_l1_complete =
6232
3.13k
                        &ps_multi_thrd->ai4_decomp_coarse_me_complete_flag[i4_cur_ipe_idx];
6233
6234
3.13k
                    while(1)
6235
3.13k
                    {
6236
3.13k
                        if(*pi4_cur_l1_complete)
6237
3.13k
                            break;
6238
3.13k
                    }
6239
3.13k
                }
6240
6241
                /* ----------------------------------------------------------- */
6242
                /*     L0 IPE qp init                                          */
6243
                /* ----------------------------------------------------------- */
6244
6245
                /****** Lock the critical section for init ******/
6246
3.13k
                {
6247
3.13k
                    WORD32 i4_status;
6248
3.13k
                    i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_l0_ipe_init);
6249
6250
3.13k
                    if(OSAL_SUCCESS != i4_status)
6251
0
                        return 0;
6252
3.13k
                }
6253
6254
                /* first thread that enters will calculate qp and write that to shared variable
6255
                   that will be accessed by other threads */
6256
3.13k
                if(ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] == 0)
6257
3.13k
                {
6258
3.13k
                    volatile WORD32 i4_is_qp_valid = -1;
6259
3.13k
                    WORD32 i4_update_qp;
6260
3.13k
                    WORD32 i4_cur_q_scale;
6261
6262
3.13k
                    i4_cur_q_scale =
6263
3.13k
                        ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp;
6264
3.13k
                    i4_cur_q_scale = ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale[i4_cur_q_scale];
6265
3.13k
                    i4_cur_q_scale = (i4_cur_q_scale + (1 << (QSCALE_Q_FAC_3 - 1))) >>
6266
3.13k
                                     QSCALE_Q_FAC_3;
6267
                    /* Get free buffer to store L0 IPE output to enc loop */
6268
3.13k
                    ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc =
6269
3.13k
                        (pre_enc_L0_ipe_encloop_ctxt_t *)ihevce_q_get_free_buff(
6270
3.13k
                            (void *)ps_enc_ctxt,
6271
3.13k
                            IHEVCE_L0_IPE_ENC_Q,
6272
3.13k
                            &ps_multi_thrd->i4_L0_IPE_out_buf_id,
6273
3.13k
                            BUFF_QUE_BLOCKING_MODE);
6274
3.13k
                    if(ps_enc_ctxt->ps_stat_prms->s_pass_prms.i4_pass != 2 &&
6275
3.13k
                       ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_rate_control_mode != 3)
6276
2.12k
                    {
6277
2.12k
                        complexity_RC_reset_marking(
6278
2.12k
                            ps_enc_ctxt, i4_cur_ipe_idx, (i4_end_flag || i4_out_flush_flag));
6279
2.12k
                    }
6280
3.13k
                    if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6281
3.13k
                                ->s_input_buf.i4_inp_frm_data_valid_flag)
6282
2.93k
                    {
6283
5.87k
                        while(i4_is_qp_valid == -1)
6284
2.93k
                        {
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.93k
                            i4_is_qp_valid = ihevce_rc_check_is_pre_enc_qp_valid(
6288
2.93k
                                (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6289
2.93k
                                (volatile WORD32 *)&ps_enc_ctxt->s_multi_thrd.i4_force_end_flag);
6290
2.93k
                            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.93k
                        }
6297
6298
                        /*lock rate control context*/
6299
2.93k
                        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.93k
                        i4_update_qp = ihevce_rc_pre_enc_qp_query(
6303
2.93k
                            (void *)ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6304
2.93k
                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out,
6305
2.93k
                            0);
6306
6307
2.93k
                        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.90k
                                   ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6326
1.90k
                                           ->s_rc_lap_out.i4_is_non_I_scd == 1)
6327
156
                                {
6328
156
                                    float i_to_avg_rest_ratio;
6329
156
                                    WORD32 i4_count = 0;
6330
6331
312
                                    while(1)
6332
312
                                    {
6333
312
                                        i_to_avg_rest_ratio = ihevce_get_i_to_avg_ratio(
6334
312
                                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6335
312
                                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6336
312
                                                 ->s_rc_lap_out,
6337
312
                                            1,
6338
312
                                            0,
6339
312
                                            0,
6340
312
                                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6341
312
                                                ->s_rc_lap_out.ai4_offsets,
6342
312
                                            0);
6343
                                        /* HEVC_RC query rate control for qp */
6344
312
                                        i4_update_qp = ihevce_get_L0_est_satd_based_scd_qp(
6345
312
                                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6346
312
                                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6347
312
                                                 ->s_rc_lap_out,
6348
312
                                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6349
312
                                                ->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1,
6350
312
                                            i_to_avg_rest_ratio);
6351
6352
312
                                        ihevce_set_L0_scd_qp(
6353
312
                                            ps_enc_ctxt->s_module_ctxt.apv_rc_ctxt[0],
6354
312
                                            i4_update_qp);
6355
6356
312
                                        if(ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6357
312
                                                   ->s_lap_out.i4_pic_type != IV_IDR_FRAME &&
6358
236
                                           ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6359
236
                                                   ->s_lap_out.i4_pic_type != IV_I_FRAME)
6360
184
                                        {
6361
184
                                            i4_update_qp +=
6362
184
                                                ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6363
184
                                                    ->s_lap_out.i4_temporal_lyr_id +
6364
184
                                                1;
6365
6366
184
                                            i4_update_qp =
6367
184
                                                CLIP3(i4_update_qp, MIN_HEVC_QP, MAX_HEVC_QP);
6368
184
                                        }
6369
6370
312
                                        i4_count++;
6371
312
                                        if((i4_update_qp ==
6372
312
                                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6373
312
                                                ->s_rc_lap_out.i4_L0_qp) ||
6374
156
                                           i4_count > 4)
6375
156
                                            break;
6376
6377
156
                                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6378
156
                                            ->s_rc_lap_out.i4_L0_qp = i4_update_qp;
6379
156
                                    }
6380
156
                                }
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.93k
                        {
6391
2.93k
                            WORD32 i4_index = 0;
6392
2.93k
                            rc_lap_out_params_t *ps_rc_lap_temp =
6393
2.93k
                                &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_rc_lap_out;
6394
2.93k
                            WORD32 i4_offset;
6395
6396
2.93k
                            if(ps_rc_lap_temp->i4_rc_pic_type != IV_IDR_FRAME &&
6397
2.48k
                               ps_rc_lap_temp->i4_rc_pic_type != IV_I_FRAME)
6398
2.35k
                            {
6399
2.35k
                                i4_index = ps_rc_lap_temp->i4_rc_temporal_lyr_id + 1;
6400
2.35k
                            }
6401
2.93k
                            i4_offset = ps_rc_lap_temp->ai4_offsets[i4_index];
6402
2.93k
                            ASSERT(i4_offset >= 0);
6403
                            /* Map the current frame Qp to L0 Qp */
6404
2.93k
                            ps_rc_lap_temp->i4_L0_qp = i4_update_qp - i4_offset;
6405
2.93k
                        }
6406
2.93k
                        osal_mutex_unlock(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
6407
2.93k
                        ASSERT(ps_multi_thrd->i4_qp_update_l0_ipe == -1);
6408
2.93k
                        ps_multi_thrd->i4_qp_update_l0_ipe = i4_update_qp;
6409
2.93k
                        ps_multi_thrd->i4_rc_l0_qp = i4_update_qp;
6410
2.93k
                    }
6411
3.13k
                    ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6412
3.13k
                        ->s_lap_out.f_i_pic_lamda_modifier = CONST_LAMDA_MOD_VAL;
6413
3.13k
                }
6414
                /* update qp only if it is not scene cut since it has already been
6415
                   populated in L1 for scene cut frames */
6416
3.13k
                if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6417
3.13k
                            ->s_input_buf.i4_inp_frm_data_valid_flag &&
6418
2.93k
                   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
3.13k
                if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6439
3.13k
                            ->s_input_buf.i4_inp_frm_data_valid_flag &&
6440
2.93k
                   ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] == 0)
6441
2.93k
                {
6442
2.93k
                    ihevce_variance_calc_acc_activity(ps_enc_ctxt, i4_cur_ipe_idx);
6443
2.93k
                }
6444
6445
                /* Mark qp as read by last thread */
6446
3.13k
                ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx]++;
6447
3.13k
                if(ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] ==
6448
3.13k
                   ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6449
3.13k
                {
6450
3.13k
                    ps_multi_thrd->ai4_num_thrds_processed_L0_ipe_qp_init[i4_cur_ipe_idx] = 0;
6451
3.13k
                    ps_multi_thrd->i4_qp_update_l0_ipe = -1;
6452
3.13k
                }
6453
6454
                /****** UnLock the critical section after deinit ******/
6455
3.13k
                {
6456
3.13k
                    WORD32 i4_status;
6457
3.13k
                    i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_l0_ipe_init);
6458
6459
3.13k
                    if(OSAL_SUCCESS != i4_status)
6460
0
                        return 0;
6461
3.13k
                }
6462
6463
3.13k
                if(1 == ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6464
3.13k
                            ->s_input_buf.i4_inp_frm_data_valid_flag)
6465
2.93k
                {
6466
2.93k
                    WORD32 i4_slice_type =
6467
2.93k
                        (WORD32)ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]
6468
2.93k
                            ->s_slice_hdr.i1_slice_type;
6469
2.93k
                    WORD32 i4_quality_preset =
6470
2.93k
                        (WORD32)ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6471
2.93k
                            ->s_lap_out.i4_quality_preset;
6472
2.93k
                    WORD32 i4_temporal_layer_id =
6473
2.93k
                        (WORD32)ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]
6474
2.93k
                            ->s_lap_out.i4_temporal_lyr_id;
6475
2.93k
#if DISABLE_L0_IPE_INTRA_IN_BPICS
6476
2.93k
                    if(1 != ((i4_quality_preset == IHEVCE_QUALITY_P6) &&
6477
390
                             (i4_temporal_layer_id > TEMPORAL_LAYER_DISABLE)))
6478
2.93k
#endif
6479
2.93k
                    {
6480
2.93k
                        UWORD8 i1_cu_qp_delta_enabled_flag =
6481
2.93k
                            ps_enc_ctxt->ps_stat_prms->s_config_prms.i4_cu_level_rc;
6482
6483
2.93k
                        ihevce_populate_ipe_frame_init(
6484
2.93k
                            ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6485
2.93k
                            ps_enc_ctxt->ps_stat_prms,
6486
2.93k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->i4_curr_frm_qp,
6487
2.93k
                            i4_slice_type,
6488
2.93k
                            i4_thrd_id,
6489
2.93k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx],
6490
2.93k
                            i1_cu_qp_delta_enabled_flag,
6491
2.93k
                            &ps_enc_ctxt->s_rc_quant,
6492
2.93k
                            i4_quality_preset,
6493
2.93k
                            i4_temporal_layer_id,
6494
2.93k
                            &ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx]->s_lap_out);
6495
6496
2.93k
                        ihevce_ipe_process(
6497
2.93k
                            ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6498
2.93k
                            &ps_enc_ctxt->s_frm_ctb_prms,
6499
2.93k
                            &ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->as_lambda_prms[0],
6500
2.93k
                            ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx],
6501
2.93k
                            ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc,
6502
2.93k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_ctb_analyse,
6503
2.93k
                            ps_multi_thrd->ps_L0_IPE_curr_out_pre_enc->ps_ipe_analyse_ctb,
6504
2.93k
                            &ps_enc_ctxt->s_multi_thrd,
6505
2.93k
                            i4_slice_type,
6506
2.93k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_layer1_buf,
6507
2.93k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_layer2_buf,
6508
2.93k
                            ps_multi_thrd->aps_curr_out_pre_enc[i4_cur_ipe_idx]->ps_ed_ctb_l1,
6509
2.93k
                            i4_thrd_id,
6510
2.93k
                            i4_cur_ipe_idx);
6511
2.93k
                    }
6512
2.93k
                }
6513
6514
                /* ----------------------------------------------------------- */
6515
                /*     pre-enc de-init                                         */
6516
                /* ----------------------------------------------------------- */
6517
6518
                /****** Lock the critical section for deinit ******/
6519
3.13k
                {
6520
3.13k
                    WORD32 i4_status;
6521
3.13k
                    i4_status = osal_mutex_lock(ps_multi_thrd->pv_mutex_hdl_pre_enc_deinit);
6522
6523
3.13k
                    if(OSAL_SUCCESS != i4_status)
6524
0
                        return 0;
6525
3.13k
                }
6526
6527
3.13k
                ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx]++;
6528
3.13k
                if(ps_multi_thrd->ai4_num_thrds_processed_pre_enc[i4_cur_ipe_idx] ==
6529
3.13k
                   ps_multi_thrd->i4_num_pre_enc_proc_thrds)
6530
3.13k
                {
6531
3.13k
                    ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx] = 0;
6532
3.13k
                    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
3.13k
                    ps_multi_thrd->ai4_pre_enc_init_done[i4_cur_ipe_idx] = 0;
6537
3.13k
                }
6538
6539
                /* de-init */
6540
3.13k
                if(0 == ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx])
6541
3.13k
                {
6542
3.13k
                    ihevce_lap_enc_buf_t *ps_curr_inp =
6543
3.13k
                        ps_multi_thrd->aps_curr_inp_pre_enc[i4_cur_ipe_idx];
6544
3.13k
                    pre_enc_me_ctxt_t *ps_curr_out =
6545
3.13k
                        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
3.13k
                    ps_multi_thrd->ai4_pre_enc_deinit_done[i4_cur_ipe_idx] = 1;
6549
6550
3.13k
                    if(1 == ps_curr_out->i4_frm_proc_valid_flag)
6551
2.93k
                    {
6552
2.93k
                        LWORD64 frame_acc_satd_by_modqp;
6553
2.93k
                        float L1_full_processed_ratio;
6554
6555
2.93k
                        if(ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated)
6556
2.74k
                        {
6557
2.74k
                            L1_full_processed_ratio =
6558
2.74k
                                ((float)ps_curr_inp->s_rc_lap_out.i8_frame_satd_by_act_L1_accum /
6559
2.74k
                                 ps_curr_inp->s_rc_lap_out.i8_satd_by_act_L1_accum_evaluated);
6560
2.74k
                        }
6561
190
                        else
6562
190
                        {
6563
190
                            L1_full_processed_ratio = 1.0;
6564
190
                        }
6565
                        /* Get frame-level satd cost and mode bit cost from IPE */
6566
2.93k
                        ps_curr_out->i8_frame_acc_satd_cost = ihevce_ipe_get_frame_intra_satd_cost(
6567
2.93k
                            ps_enc_ctxt->s_module_ctxt.pv_ipe_ctxt,
6568
2.93k
                            &frame_acc_satd_by_modqp,
6569
2.93k
                            &ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits,
6570
2.93k
                            &ps_curr_inp->s_lap_out.i8_frame_level_activity_fact,
6571
2.93k
                            &ps_curr_inp->s_lap_out.i8_frame_l0_acc_satd);
6572
6573
2.93k
                        if((ps_curr_inp->s_lap_out.i4_quality_preset == IHEVCE_QUALITY_P6) &&
6574
390
                           (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.93k
                        {
6580
2.93k
                            WORD32 i4_cur_q_scale = (ps_enc_ctxt->s_rc_quant.pi4_qp_to_qscale
6581
2.93k
                                                         [ps_enc_ctxt->s_multi_thrd.i4_rc_l0_qp +
6582
2.93k
                                                          ps_enc_ctxt->s_rc_quant.i1_qp_offset] +
6583
2.93k
                                                     (1 << (QSCALE_Q_FAC_3 - 1))) >>
6584
2.93k
                                                    QSCALE_Q_FAC_3;
6585
6586
                            /* calculate satd/act_fac = satd/qm * (qp_used_at_L0_analysis) */
6587
2.93k
                            ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum =
6588
2.93k
                                frame_acc_satd_by_modqp * i4_cur_q_scale;
6589
2.93k
                        }
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.93k
                        ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits = (LWORD64)(
6594
2.93k
                            ps_curr_inp->s_rc_lap_out.i8_est_I_pic_header_bits *
6595
2.93k
                            L1_full_processed_ratio);
6596
6597
2.93k
                        if(L1_full_processed_ratio < 1.5)
6598
2.13k
                        {
6599
2.13k
                            ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum = (LWORD64)(
6600
2.13k
                                ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum *
6601
2.13k
                                L1_full_processed_ratio);
6602
2.13k
                        }
6603
803
                        else
6604
803
                        {
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
803
                            ps_curr_inp->s_rc_lap_out.i8_frame_satd_act_accum =
6608
803
                                ps_curr_inp->s_rc_lap_out.i8_frm_satd_act_accum_L0_frm_L1;
6609
803
                        }
6610
2.93k
                    }
6611
6612
                    /* register the current input buffer to be cnosumed by encode group threads */
6613
3.13k
                    ps_curr_out->curr_inp_buf_id =
6614
3.13k
                        ps_multi_thrd->ai4_in_buf_id_pre_enc[i4_cur_ipe_idx];
6615
3.13k
                    ps_curr_out->ps_curr_inp = ps_curr_inp;
6616
6617
                    /* set the output buffer as produced */
6618
3.13k
                    ihevce_q_set_buff_prod(
6619
3.13k
                        (void *)ps_enc_ctxt,
6620
3.13k
                        IHEVCE_PRE_ENC_ME_Q,
6621
3.13k
                        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
3.13k
                    ihevce_q_set_buff_prod(
6625
3.13k
                        (void *)ps_enc_ctxt,
6626
3.13k
                        IHEVCE_L0_IPE_ENC_Q,
6627
3.13k
                        ps_multi_thrd->i4_L0_IPE_out_buf_id);
6628
6629
                    /* update flag indicating ipe is done */
6630
3.13k
                    ihevce_dmgr_update_frm_frm_sync(pv_dep_mngr_prev_frame_pre_enc_l0);
6631
3.13k
                }
6632
6633
3.13k
                {
6634
                    /* index increment */
6635
3.13k
                    i4_cur_ipe_idx = i4_cur_ipe_idx + 1;
6636
6637
                    /* wrap around case */
6638
3.13k
                    if(i4_cur_ipe_idx >= ps_multi_thrd->i4_max_delay_pre_me_btw_l0_ipe)
6639
1.51k
                    {
6640
1.51k
                        i4_cur_ipe_idx = 0;
6641
1.51k
                    }
6642
6643
3.13k
                    i4_num_buf_prod_for_l0_ipe--;
6644
3.13k
                }
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
3.13k
                {
6649
3.13k
                    WORD32 i4_status;
6650
3.13k
                    i4_status = osal_mutex_unlock(ps_multi_thrd->pv_mutex_hdl_pre_enc_deinit);
6651
6652
3.13k
                    if(OSAL_SUCCESS != i4_status)
6653
0
                        return 0;
6654
3.13k
                }
6655
6656
3.13k
                if(1 == ps_multi_thrd->i4_force_end_flag)
6657
0
                {
6658
0
                    i4_end_flag = 1;
6659
0
                    break;
6660
0
                }
6661
3.13k
            } while((i4_end_flag || i4_out_flush_flag) && i4_num_buf_prod_for_l0_ipe);
6662
3.13k
        }
6663
3.13k
        if(i4_thrd_id == 0)
6664
3.13k
        {
6665
3.13k
            PROFILE_STOP(&ps_hle_ctxt->profile_pre_enc_l0ipe[i4_resolution_id], NULL);
6666
3.13k
        }
6667
3.13k
    }
6668
6669
195
    return 0;
6670
195
}
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.93k
{
6679
2.93k
    ihevce_ed_ctb_l1_t *ps_ed_ctb_l1;
6680
2.93k
    WORD32 i4_qp_counter, i4_qp_start = 0, i4_qp_end = 0, i, i4_j, i4_new_frame_qp;
6681
2.93k
    LWORD64 i8_l1_intra_sad_nc_accounted = 0, cur_intra_sad, raw_hme_sad = 0;
6682
2.93k
    LWORD64 cur_hme_sad = 0, cur_hme_sad_for_offset = 0, acc_hme_l1_sad = 0,
6683
2.93k
            acc_hme_l1_sad_for_offset = 0;
6684
2.93k
    i4_qp_start = 1;
6685
2.93k
    i4_qp_end = 51;
6686
6687
52.8k
    for(i4_qp_counter = i4_qp_start; i4_qp_counter <= i4_qp_end; i4_qp_counter = i4_qp_counter + 3)
6688
49.9k
    {
6689
49.9k
        i8_l1_intra_sad_nc_accounted = 0;
6690
49.9k
        cur_intra_sad = 0;
6691
49.9k
        raw_hme_sad = 0;
6692
49.9k
        cur_hme_sad = 0;
6693
49.9k
        cur_hme_sad_for_offset = 0;
6694
49.9k
        acc_hme_l1_sad = 0;
6695
49.9k
        ps_ed_ctb_l1 = ps_curr_out->ps_ed_ctb_l1;
6696
49.9k
        i4_new_frame_qp = i4_qp_counter;
6697
49.9k
        acc_hme_l1_sad = 0;
6698
6699
293k
        for(i = 0; i < (i4_tot_ctb_l1_x * i4_tot_ctb_l1_y); i += 1)
6700
244k
        {
6701
4.14M
            for(i4_j = 0; i4_j < 16; i4_j++)
6702
3.90M
            {
6703
3.90M
                if(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] != -1)
6704
3.37M
                {
6705
3.37M
                    ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] >= 0);
6706
3.37M
                    if(ps_curr_inp->s_rc_lap_out.i4_rc_pic_type != IV_I_FRAME &&
6707
3.25M
                       ps_curr_inp->s_rc_lap_out.i4_rc_pic_type != IV_IDR_FRAME)
6708
1.81M
                    {
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.81M
                        if(ps_curr_inp->s_rc_lap_out.i4_rc_quality_preset == IHEVCE_QUALITY_P6)
6712
146k
                        {
6713
146k
                            if(ps_curr_inp->s_rc_lap_out.i4_rc_pic_type == IV_P_FRAME)
6714
146k
                            {
6715
146k
                                ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] >= 0);
6716
146k
                                ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me_for_decide[i4_j] >= 0);
6717
146k
                            }
6718
146k
                        }
6719
1.67M
                        else
6720
1.67M
                        {
6721
1.67M
                            ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] >= 0);
6722
1.67M
                            ASSERT(ps_ed_ctb_l1->i4_best_sad_8x8_l1_me_for_decide[i4_j] >= 0);
6723
1.67M
                        }
6724
6725
1.81M
#if 1  //DISABLE_L1_L2_IPE_INTRA_IN_BPICS && RC_DEPENDENCY_FOR_BPIC
6726
1.81M
                        if((ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] != -1))
6727
1.81M
#endif
6728
1.81M
                        {
6729
1.81M
                            cur_hme_sad = ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j] -
6730
1.81M
                                          (QP2QUANT_MD[i4_new_frame_qp] << 3);
6731
1.81M
                        }
6732
1.81M
                        raw_hme_sad += ps_ed_ctb_l1->i4_best_sad_8x8_l1_me[i4_j];
6733
6734
1.81M
                        if(cur_hme_sad > 0)
6735
519k
                            acc_hme_l1_sad += cur_hme_sad;
6736
1.81M
                    }
6737
3.37M
                    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.37M
                    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.37M
                    cur_intra_sad = (LWORD64)(
6744
3.37M
                        (ps_ed_ctb_l1->i4_best_sad_8x8_l1_ipe[i4_j] * 1.17) -
6745
3.37M
                        (QP2QUANT_MD[i4_new_frame_qp] << 3));
6746
6747
3.37M
                    if(cur_intra_sad > 0)
6748
1.29M
                        i8_l1_intra_sad_nc_accounted += cur_intra_sad;
6749
3.37M
                }
6750
3.90M
            }
6751
244k
            ps_ed_ctb_l1 += 1;
6752
244k
        }
6753
49.9k
        if((ps_curr_inp->s_rc_lap_out.i4_rc_quality_preset == IHEVCE_QUALITY_P6) &&
6754
6.63k
           (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
49.9k
        else
6761
49.9k
        {
6762
49.9k
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter] =
6763
49.9k
                i8_l1_intra_sad_nc_accounted;
6764
49.9k
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 1] =
6765
49.9k
                i8_l1_intra_sad_nc_accounted;
6766
49.9k
            ps_curr_inp->s_rc_lap_out.ai8_pre_intra_sad[i4_qp_counter + 2] =
6767
49.9k
                i8_l1_intra_sad_nc_accounted;
6768
49.9k
        }
6769
49.9k
        ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter] = acc_hme_l1_sad;
6770
49.9k
        ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter + 1] = acc_hme_l1_sad;
6771
49.9k
        ps_curr_inp->s_rc_lap_out.ai8_frame_acc_coarse_me_sad[i4_qp_counter + 2] = acc_hme_l1_sad;
6772
49.9k
        ps_curr_inp->s_rc_lap_out.i8_raw_l1_coarse_me_sad = raw_hme_sad;
6773
49.9k
    }
6774
2.93k
}