Coverage Report

Created: 2026-01-10 07:08

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