Coverage Report

Created: 2026-04-12 06:57

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