Coverage Report

Created: 2023-06-07 07:34

/src/libhevc/encoder/ihevce_rc_interface.c
Line
Count
Source (jump to first uncovered line)
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_rc_interface.c
24
*
25
* @brief
26
*  This file contains function definitions for rc api interface
27
*
28
* @author
29
*  Ittiam
30
*
31
* List of Functions
32
*  <TODO: Update this>
33
*
34
******************************************************************************
35
*/
36
37
/*****************************************************************************/
38
/* File Includes                                                             */
39
/*****************************************************************************/
40
41
/* System include files */
42
#include <stdio.h>
43
#include <string.h>
44
#include <stdlib.h>
45
#include <assert.h>
46
#include <stdarg.h>
47
#include <math.h>
48
49
/* User include files */
50
#include "ihevc_typedefs.h"
51
#include "itt_video_api.h"
52
#include "ihevce_api.h"
53
54
#include "rc_cntrl_param.h"
55
#include "rc_frame_info_collector.h"
56
#include "rc_look_ahead_params.h"
57
#include "mem_req_and_acq.h"
58
#include "rate_control_api.h"
59
#include "var_q_operator.h"
60
61
#include "ihevc_defs.h"
62
#include "ihevc_debug.h"
63
#include "ihevc_macros.h"
64
#include "ihevc_structs.h"
65
#include "ihevc_platform_macros.h"
66
#include "ihevc_deblk.h"
67
#include "ihevc_itrans_recon.h"
68
#include "ihevc_chroma_itrans_recon.h"
69
#include "ihevc_chroma_intra_pred.h"
70
#include "ihevc_intra_pred.h"
71
#include "ihevc_inter_pred.h"
72
#include "ihevc_mem_fns.h"
73
#include "ihevc_padding.h"
74
#include "ihevc_weighted_pred.h"
75
#include "ihevc_sao.h"
76
#include "ihevc_resi_trans.h"
77
#include "ihevc_quant_iquant_ssd.h"
78
79
#include "ihevce_defs.h"
80
#include "ihevce_hle_interface.h"
81
#include "ihevce_lap_enc_structs.h"
82
#include "ihevce_lap_interface.h"
83
#include "ihevce_multi_thrd_structs.h"
84
#include "ihevce_me_common_defs.h"
85
#include "ihevce_had_satd.h"
86
#include "ihevce_function_selector.h"
87
#include "ihevce_enc_structs.h"
88
#include "ihevce_cmn_utils_instr_set_router.h"
89
#include "hme_datatype.h"
90
#include "hme_interface.h"
91
#include "hme_common_defs.h"
92
#include "hme_defs.h"
93
#include "ihevce_rc_enc_structs.h"
94
#include "ihevce_rc_structs.h"
95
#include "ihevce_rc_interface.h"
96
#include "ihevce_frame_process_utils.h"
97
98
/*****************************************************************************/
99
/* Constant Macros                                                           */
100
/*****************************************************************************/
101
#define USE_USER_FIRST_FRAME_QP 0
102
#define DEBUG_PRINT 0
103
#define DETERMINISTIC_RC 1
104
#define USE_QP_OFFSET_POST_SCD 1
105
#define USE_SQRT 0
106
#define K_SCALING_FACTOR 8
107
#define ENABLE_2_PASS_BIT_ALLOC_FRM_1ST 0
108
109
0
#define VBV_THRSH_I_PIC_DELTA_QP_1 (0.85)
110
0
#define VBV_THRSH_I_PIC_DELTA_QP_2 (0.75)
111
0
#define VBV_THRSH_P_PIC_DELTA_QP_1 (0.80)
112
0
#define VBV_THRSH_P_PIC_DELTA_QP_2 (0.70)
113
0
#define VBV_THRSH_BR_PIC_DELTA_QP_1 (0.75)
114
0
#define VBV_THRSH_BR_PIC_DELTA_QP_2 (0.65)
115
0
#define VBV_THRSH_BNR_PIC_DELTA_QP_1 (0.75)
116
0
#define VBV_THRSH_BNR_PIC_DELTA_QP_2 (0.65)
117
0
#define VBV_THRSH_DELTA_QP (0.6)
118
119
0
#define VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_1 (0.70)
120
0
#define VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_2 (0.60)
121
0
#define VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_1 (0.65)
122
0
#define VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_2 (0.55)
123
0
#define VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_1 (0.60)
124
0
#define VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_2 (0.50)
125
0
#define VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_1 (0.60)
126
0
#define VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_2 (0.50)
127
0
#define VBV_THRSH_FRM_PRLL_DELTA_QP (0.45)
128
129
#define TRACE_SUPPORT 0
130
131
/*****************************************************************************/
132
/* Globals                                                                   */
133
/*****************************************************************************/
134
135
/*
136
Modified bpp vs nor satd/act/qp :
137
=================================
138
139
Prestine Quality
140
-----------------
141
480p  y = -0.1331x3 - 0.0589x2 + 2.5091x - 0.0626
142
720p  y = -0.3603x3 + 0.4504x2 + 2.2056x - 0.0411
143
1080p y = -0.7085x3 + 0.9743x2 + 1.939x - 0.0238
144
2160p y = -1.2447x3 + 2.1218x2 + 1.4995x - 0.0108
145
146
High Quality
147
-------------
148
480p  y = -0.1348x3 - 0.0557x2 + 2.5055x - 0.0655
149
720p  y = -0.0811x3 + 0.1988x2 + 1.246x - 0.0385
150
1080p y = -0.74x3 + 1.0552x2 + 1.8942x - 0.0251
151
2160p y = -1.3851x3 + 2.3372x2 + 1.4255x - 0.0113
152
153
Medium Speed
154
-------------
155
480p  y = -0.143x3 - 0.0452x2 + 2.5581x - 0.0765
156
720p  y = -0.3997x3 + 0.542x2 + 2.201x - 0.0507
157
1080p y = -0.816x3 + 1.2048x2 + 1.8689x - 0.0298
158
2160p y = -1.5169x3 + 2.5857x2 + 1.3478x - 0.0126
159
160
High Speed
161
-----------
162
480p  y = -0.1472x3 - 0.0341x2 + 2.5605x - 0.0755
163
720p  y = -0.3967x3 + 0.526x2 + 2.2228x - 0.0504
164
1080p y = -0.8008x3 + 1.1713x2 + 1.8897x - 0.0297
165
2160p y = -1.503x3 + 2.576x2 + 1.3476x - 0.0123
166
167
Extreme Speed
168
--------------
169
480p  y = -0.1379x3 - 0.059x2 + 2.5716x - 0.0756
170
720p  y = -0.3938x3 + 0.521x2 + 2.2239x - 0.0505
171
1080p y = -0.8041x3 + 1.1725x2 + 1.8874x - 0.0293
172
2160p y = -1.4863x3 + 2.556x2 + 1.344x - 0.0122
173
174
*/
175
176
const double g_offline_i_model_coeff[20][4] = {
177
178
    /*ultra_HD*/
179
    { -1.2447, 2.1218, 1.4995, -0.0108 }, /*Prestine quality*/
180
    { -1.3851, 2.3372, 1.4255, -0.0113 }, /*High quality*/
181
    { -1.5169, 2.5857, 1.3478, -0.0126 }, /*Medium speed*/
182
    { -1.503, 2.576, 1.3476, -0.0123 }, /*high speed*/
183
    { -1.4863, 2.556, 1.344, -0.0122 }, /*Extreme Speed*/
184
185
    /*Full HD*/
186
    { -0.7085, 0.9743, 1.939, -0.0238 }, /*Prestine quality*/
187
    { -0.74, 1.0552, 1.8942, -0.0251 }, /*High quality*/
188
    { -0.816, 1.2048, 1.8689, -0.0298 }, /*Medium speed*/
189
    { -0.8008, 1.1713, 1.8897, -0.0297 }, /*high speed*/
190
    { -0.8041, 1.1725, 1.8874, -0.0293 }, /*Extreme Speed*/
191
192
    /*720p*/
193
    { -0.3603, 0.4504, 2.2056, -0.0411 }, /*Prestine quality*/
194
    // {-0.0811, 0.1988, 1.246, - 0.0385},/*High quality*/
195
    { -0.3997, 0.542, 2.201, -0.0507 },
196
    { -0.3997, 0.542, 2.201, -0.0507 }, /*Medium speed*/
197
    { -0.3967, 0.526, 2.2228, -0.0504 }, /*high speed*/
198
    { -0.3938, 0.521, 2.2239, -0.0505 }, /*Extreme Speed*/
199
200
    /*SD*/
201
    { -0.1331, -0.0589, 2.5091, -0.0626 }, /*Prestine quality*/
202
    { -0.1348, -0.0557, 2.5055, -0.0655 }, /*High quality*/
203
    { -0.143, -0.0452, 2.5581, -0.0765 }, /*Medium speed*/
204
    { -0.1472, -0.0341, 2.5605, -0.0755 }, /*high speed*/
205
    { -0.1379, -0.059, 2.5716, -0.0756 } /*Extreme Speed*/
206
207
};
208
209
/*****************************************************************************/
210
/* Function Declarations                                                     */
211
/*****************************************************************************/
212
213
picture_type_e ihevce_rc_conv_pic_type(
214
    IV_PICTURE_CODING_TYPE_T pic_type,
215
    WORD32 i4_field_pic,
216
    WORD32 i4_temporal_layer_id,
217
    WORD32 i4_is_bottom_field,
218
    WORD32 i4_top_field_first);
219
220
WORD32 ihevce_rc_get_scaled_mpeg2_qp(WORD32 i4_frame_qp, rc_quant_t *ps_rc_quant_ctxt);
221
222
static WORD32 ihevce_get_offline_index(rc_context_t *ps_rc_ctxt, WORD32 i4_num_pels_in_frame);
223
224
static void ihevce_rc_get_pic_param(
225
    picture_type_e rc_pic_type, WORD32 *pi4_tem_lyr, WORD32 *pi4_is_bottom_field);
226
227
static double ihevce_get_frame_lambda_modifier(
228
    WORD8 slice_type,
229
    WORD32 i4_rc_temporal_lyr_id,
230
    WORD32 i4_first_field,
231
    WORD32 i4_rc_is_ref_pic,
232
    WORD32 i4_num_b_frms);
233
234
static WORD32 ihevce_clip_min_max_qp(
235
    rc_context_t *ps_rc_ctxt,
236
    WORD32 i4_hevc_frame_qp,
237
    picture_type_e rc_pic_type,
238
    WORD32 i4_rc_temporal_lyr_id);
239
240
WORD32 ihevce_ebf_based_rc_correction_to_avoid_overflow(
241
    rc_context_t *ps_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out, WORD32 *pi4_tot_bits_estimated);
242
243
/*****************************************************************************/
244
/* Function Definitions                                                      */
245
/*****************************************************************************/
246
247
/*!
248
************************************************************************
249
* @brief
250
*    return number of records used by RC
251
************************************************************************
252
*/
253
WORD32 ihevce_rc_get_num_mem_recs(void)
254
0
{
255
0
    WORD32 i4_num_rc_mem_tab = 0;
256
257
    /*get the number of memtab request from RC*/
258
0
    rate_control_handle ps_rate_control_api;
259
0
    itt_memtab_t *ps_memtab = NULL;
260
0
    i4_num_rc_mem_tab =
261
0
        rate_control_num_fill_use_free_memtab(&ps_rate_control_api, ps_memtab, GET_NUM_MEMTAB);
262
263
0
    return ((NUM_RC_MEM_RECS + i4_num_rc_mem_tab));
264
0
}
265
266
/*!
267
************************************************************************
268
* @brief
269
*    return each record attributes of RC
270
************************************************************************
271
*/
272
WORD32 ihevce_rc_get_mem_recs(
273
    iv_mem_rec_t *ps_mem_tab,
274
    ihevce_static_cfg_params_t *ps_init_prms,
275
    WORD32 mem_space,
276
    ihevce_sys_api_t *ps_sys_api)
277
0
{
278
0
    float f_temp;
279
0
    WORD32 i4_temp_size;
280
0
    WORD32 i4_num_memtab = 0;
281
0
    WORD32 i4_num_rc_mem_tab, i;
282
0
    rate_control_handle ps_rate_control_api;
283
0
    itt_memtab_t *ps_itt_memtab = NULL;
284
0
    itt_memtab_t as_rc_mem_tab[30];
285
286
    /*memory requirements to store RC context */
287
0
    ps_mem_tab[RC_CTXT].i4_mem_size = sizeof(rc_context_t);
288
    //DBG_PRINTF("size of RC context = %d\n",sizeof(rc_context_t));
289
0
    ps_mem_tab[RC_CTXT].e_mem_type = (IV_MEM_TYPE_T)mem_space;
290
291
0
    ps_mem_tab[RC_CTXT].i4_mem_alignment = 64;
292
293
0
    (void)ps_sys_api;
294
    //i4_temp_size = (51 + ((ps_init_prms->s_src_prms.i4_bit_depth - 8) * 6));
295
0
    i4_temp_size = (51 + ((ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8) * 6));
296
297
0
    ps_mem_tab[RC_QP_TO_QSCALE].i4_mem_size = (i4_temp_size + 1) * 4;
298
0
    ps_mem_tab[RC_QP_TO_QSCALE].e_mem_type = (IV_MEM_TYPE_T)mem_space;
299
0
    ps_mem_tab[RC_QP_TO_QSCALE].i4_mem_alignment = 64;
300
301
0
    ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].i4_mem_size = (i4_temp_size + 1) * 4;
302
0
    ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].e_mem_type = (IV_MEM_TYPE_T)mem_space;
303
0
    ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].i4_mem_alignment = 64;
304
305
0
    f_temp = (float)(51 + ((ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8) * 6));
306
0
    f_temp = ((float)(f_temp - 4) / 6);
307
0
    i4_temp_size = (WORD32)((float)pow(2, f_temp) + 0.5);
308
0
    i4_temp_size = (i4_temp_size << 3);  // Q3 format is mantained for accuarate calc at lower qp
309
310
0
    ps_mem_tab[RC_QSCALE_TO_QP].i4_mem_size = (i4_temp_size + 1) * sizeof(UWORD32);
311
0
    ps_mem_tab[RC_QSCALE_TO_QP].e_mem_type = (IV_MEM_TYPE_T)mem_space;
312
0
    ps_mem_tab[RC_QSCALE_TO_QP].i4_mem_alignment = 64;
313
314
    /*memory requirements to store RC context */
315
0
    ps_mem_tab[RC_MULTI_PASS_GOP_STAT].i4_mem_size = sizeof(gop_level_stat_t);
316
0
    ps_mem_tab[RC_MULTI_PASS_GOP_STAT].e_mem_type = (IV_MEM_TYPE_T)mem_space;
317
0
    ps_mem_tab[RC_MULTI_PASS_GOP_STAT].i4_mem_alignment = 64;
318
319
0
    i4_num_rc_mem_tab =
320
0
        rate_control_num_fill_use_free_memtab(&ps_rate_control_api, ps_itt_memtab, GET_NUM_MEMTAB);
321
322
0
    i4_num_memtab =
323
0
        rate_control_num_fill_use_free_memtab(&ps_rate_control_api, as_rc_mem_tab, FILL_MEMTAB);
324
325
0
    for(i = 0; i < i4_num_memtab; i++)
326
0
    {
327
0
        ps_mem_tab[i + NUM_RC_MEM_RECS].i4_mem_size = as_rc_mem_tab[i].u4_size;
328
0
        ps_mem_tab[i + NUM_RC_MEM_RECS].i4_mem_alignment = as_rc_mem_tab[i].i4_alignment;
329
0
        ps_mem_tab[i + NUM_RC_MEM_RECS].e_mem_type = (IV_MEM_TYPE_T)mem_space;
330
0
    }
331
0
    return (i4_num_memtab + NUM_RC_MEM_RECS);
332
0
}
333
334
/**
335
******************************************************************************
336
*
337
*  @brief Initilizes the rate control module
338
*
339
*  @par   Description
340
*
341
*  @param[inout]   ps_mem_tab
342
*  pointer to memory descriptors table
343
*
344
*  @param[in]      ps_init_prms
345
*  Create time static parameters
346
*
347
*  @return      void
348
*
349
******************************************************************************
350
*/
351
void *ihevce_rc_mem_init(
352
    iv_mem_rec_t *ps_mem_tab,
353
    ihevce_static_cfg_params_t *ps_init_prms,
354
    WORD32 i4_bitrate_instance_id,
355
    rc_quant_t *ps_rc_quant,
356
    WORD32 i4_resolution_id,
357
    WORD32 i4_look_ahead_frames_in_first_pass)
358
0
{
359
0
    rc_context_t *ps_rc_ctxt;
360
0
    WORD32 i4_num_memtab, i, j, i4_avg_bitrate, u4_buf_size;
361
0
    WORD32 i4_cdr_period = 0, i4_idr_period = 0;
362
0
    WORD32 i4_peak_bitrate_factor;
363
0
    rate_control_handle ps_rate_control_api;
364
0
    itt_memtab_t as_rc_mem_tab[30];
365
0
    itt_memtab_t *ps_itt_memtab = NULL;
366
0
    ps_rc_ctxt = (rc_context_t *)ps_mem_tab[RC_CTXT].pv_base;
367
0
    memset(ps_rc_ctxt, 0, sizeof(rc_context_t));
368
369
0
    ps_rc_ctxt->i4_br_id_for_2pass = i4_bitrate_instance_id;
370
0
    if(ps_init_prms->s_coding_tools_prms.i4_max_cra_open_gop_period)
371
0
    {
372
0
        i4_cdr_period = ps_init_prms->s_coding_tools_prms.i4_max_cra_open_gop_period;
373
0
    }
374
0
    if(ps_init_prms->s_coding_tools_prms.i4_max_i_open_gop_period)
375
0
    {
376
0
        i4_cdr_period = ps_init_prms->s_coding_tools_prms.i4_max_i_open_gop_period;
377
0
    }
378
0
    i4_idr_period = ps_init_prms->s_coding_tools_prms.i4_max_closed_gop_period;
379
380
0
    ps_rc_quant->pi4_qscale_to_qp = (WORD32 *)ps_mem_tab[RC_QSCALE_TO_QP].pv_base;
381
382
0
    ps_rc_quant->pi4_qp_to_qscale_q_factor = (WORD32 *)ps_mem_tab[RC_QP_TO_QSCALE_Q_FACTOR].pv_base;
383
384
0
    ps_rc_quant->pi4_qp_to_qscale = (WORD32 *)ps_mem_tab[RC_QP_TO_QSCALE].pv_base;
385
386
0
    ps_rc_ctxt->pv_gop_stat = (void *)ps_mem_tab[RC_MULTI_PASS_GOP_STAT].pv_base;
387
388
    /*assign memtabs to rc module*/
389
0
    i4_num_memtab =
390
0
        rate_control_num_fill_use_free_memtab(&ps_rate_control_api, ps_itt_memtab, GET_NUM_MEMTAB);
391
392
0
    i4_num_memtab =
393
0
        rate_control_num_fill_use_free_memtab(&ps_rate_control_api, as_rc_mem_tab, FILL_MEMTAB);
394
0
    for(i = 0; i < i4_num_memtab; i++)
395
0
    {
396
0
        as_rc_mem_tab[i].pv_base = ps_mem_tab[i + NUM_RC_MEM_RECS].pv_base;
397
0
    }
398
0
    i4_num_memtab =
399
0
        rate_control_num_fill_use_free_memtab(&ps_rate_control_api, as_rc_mem_tab, USE_BASE);
400
401
0
    ps_rc_ctxt->rc_hdl =
402
0
        ps_rate_control_api; /*handle to entire RC structure private to RC library*/
403
0
    ps_rc_ctxt->i4_field_pic = ps_init_prms->s_src_prms.i4_field_pic;
404
405
0
    ps_rc_ctxt->i4_is_first_frame_encoded = 0;
406
    /*added for field encoding*/
407
0
    ps_rc_ctxt->i4_max_inter_frm_int =
408
0
        1 << (ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers + ps_rc_ctxt->i4_field_pic);
409
0
    ps_rc_ctxt->i4_max_temporal_lyr = ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers;
410
    /*Number of picture types used if different models are used for hierarchial B frames*/
411
412
0
    if(i4_idr_period == 1 || i4_cdr_period == 1)
413
0
        ps_rc_ctxt->i4_num_active_pic_type = 1;
414
0
    else
415
0
        ps_rc_ctxt->i4_num_active_pic_type =
416
0
            2 + ps_init_prms->s_coding_tools_prms.i4_max_temporal_layers;
417
418
0
    ps_rc_ctxt->i4_quality_preset =
419
0
        ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_quality_preset;
420
421
0
    if(ps_rc_ctxt->i4_quality_preset == IHEVCE_QUALITY_P7)
422
0
    {
423
0
        ps_rc_ctxt->i4_quality_preset = IHEVCE_QUALITY_P6;
424
0
    }
425
426
0
    ps_rc_ctxt->i4_rc_pass = ps_init_prms->s_pass_prms.i4_pass;
427
0
    ps_rc_ctxt->i8_num_gop_mem_alloc = 0;
428
429
0
    ps_rc_ctxt->u1_is_mb_level_rc_on = 0; /*no mb level RC*/
430
431
0
    ps_rc_ctxt->i4_is_infinite_gop = 0;
432
0
    ps_rc_ctxt->u1_bit_depth = (UWORD8)ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth;
433
434
    //ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset = ((ps_init_prms->s_src_prms.i4_bit_depth-8)*6);
435
0
    ps_rc_quant->i1_qp_offset = ((ps_init_prms->s_tgt_lyr_prms.i4_internal_bit_depth - 8) * 6);
436
437
0
    ps_rc_quant->i2_max_qp = MIN(ps_init_prms->s_config_prms.i4_max_frame_qp,
438
0
                                 51);  // FOR Encoder
439
0
    ps_rc_quant->i2_min_qp =
440
0
        MAX(-(ps_rc_quant->i1_qp_offset), ps_init_prms->s_config_prms.i4_min_frame_qp);
441
442
0
    if(ps_init_prms->s_lap_prms.i4_rc_look_ahead_pics)
443
0
    {
444
0
        ps_rc_ctxt->i4_num_frame_in_lap_window =
445
0
            ps_init_prms->s_lap_prms.i4_rc_look_ahead_pics + MIN_L1_L0_STAGGER_NON_SEQ;
446
0
    }
447
0
    else
448
0
        ps_rc_ctxt->i4_num_frame_in_lap_window = 0;
449
450
0
    if(i4_cdr_period > 0 && i4_idr_period > 0)
451
0
    {
452
        /*both IDR and CDR are positive*/
453
        //WORD32 i4_rem;
454
0
        ps_rc_ctxt->u4_intra_frame_interval = i4_cdr_period;
455
0
        ps_rc_ctxt->u4_idr_period = i4_idr_period;
456
457
        /*Allow configuration where IDR period is multiple of CDR period. Though any configuiration is supported by LAP rate control
458
        does not handle assymeteric GOPS, Bit-allocation is exposed to CDR or IDR. It treats everything as I pic*/
459
0
    }
460
0
    else if(!i4_idr_period && i4_cdr_period > 0)
461
0
    {
462
0
        ps_rc_ctxt->u4_intra_frame_interval = i4_cdr_period;
463
0
        ps_rc_ctxt->u4_idr_period = 0;
464
0
    }
465
0
    else if(!i4_cdr_period && i4_idr_period > 0)
466
0
    {
467
0
        ps_rc_ctxt->u4_intra_frame_interval = i4_idr_period;
468
0
        ps_rc_ctxt->u4_idr_period = i4_idr_period;
469
0
    }
470
0
    else
471
0
    {
472
        /*ASSERT(0);*/
473
474
0
        ps_rc_ctxt->u4_intra_frame_interval =
475
0
            INFINITE_GOP_CDR_TIME_S *
476
0
            ((ps_init_prms->s_src_prms.i4_frm_rate_num /
477
0
              (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_frm_rate_scale_factor *
478
0
               ps_init_prms->s_src_prms.i4_frm_rate_denom)));
479
0
        ps_rc_ctxt->u4_idr_period = 0;
480
0
        ps_rc_ctxt->i4_is_infinite_gop = 1;
481
0
    }
482
483
    /*If cdr period is 0 then only it is closed gop*/
484
0
    ps_rc_ctxt->i4_is_gop_closed = 0;
485
0
    if(i4_cdr_period == 0)
486
0
    {
487
0
        ps_rc_ctxt->i4_is_gop_closed = 1;
488
0
    }
489
    /*This is required because the intra sad returned by non I pic is not correct. Use only I pic sad for next I pic qp calculation*/
490
0
    ps_rc_ctxt->i4_use_est_intra_sad = 0;
491
0
    ps_rc_ctxt->u4_src_ticks = 1000;
492
0
    ps_rc_ctxt->u4_tgt_ticks = 1000;
493
0
    ps_rc_ctxt->i4_auto_generate_init_qp = 1;
494
495
0
    ps_rc_ctxt->i8_prev_i_frm_cost = 0;
496
497
0
    for(i = 0; i < MAX_PIC_TYPE; i++)
498
0
    {
499
        /* -1 cost indicates the picture type not been encoded*/
500
0
        ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
501
0
        ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i] = -1;
502
0
        ps_rc_ctxt->ai8_prev_frame_hme_sad[i] = -1;
503
0
        ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i] = -1;
504
        /*L1 state metrics*/
505
0
        ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[i] = -1;
506
0
        ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[i] = -1;
507
0
        ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[i] = -1;
508
        /* SGI & Enc Loop Parallelism related changes*/
509
0
        ps_rc_ctxt->s_l1_state_metric.au4_prev_scene_num[i] = 0;
510
0
        ps_rc_ctxt->au4_prev_scene_num_pre_enc[i] = 0xFFFFFFFF;
511
0
        ps_rc_ctxt->ai4_qp_for_previous_scene_pre_enc[i] = 0;
512
0
    }
513
0
    ps_rc_ctxt->u4_scene_num_est_L0_intra_sad_available = 0xFFFFFFFF;
514
515
0
    for(i = 0; i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i++)
516
0
    {
517
0
        ps_rc_ctxt->as_non_ref_b_qp[i].i4_enc_order_num_rc = 0x7FFFFFFF;
518
0
        ps_rc_ctxt->as_non_ref_b_qp[i].i4_non_ref_B_pic_qp = 0x7FFFFFFF;
519
0
        ps_rc_ctxt->as_non_ref_b_qp[i].u4_scene_num_rc = MAX_SCENE_NUM + 1;
520
0
    }
521
0
    ps_rc_ctxt->i4_non_ref_B_ctr = 0;
522
0
    ps_rc_ctxt->i4_prev_qp_ctr = 0;
523
0
    ps_rc_ctxt->i4_cur_scene_num = 0;
524
525
    /*init = 0 set to 1 when atleast one frame of each picture type has completed L1 stage*/
526
0
    ps_rc_ctxt->i4_is_est_L0_intra_sad_available = 0;
527
528
    /*Min and max qp from user*/
529
0
    ps_rc_ctxt->i4_min_frame_qp = ps_init_prms->s_config_prms.i4_min_frame_qp;
530
0
    ps_rc_ctxt->i4_max_frame_qp = ps_init_prms->s_config_prms.i4_max_frame_qp;
531
0
    ASSERT(ps_rc_ctxt->i4_min_frame_qp >= ps_rc_quant->i2_min_qp);
532
0
    ASSERT(ps_rc_ctxt->i4_max_frame_qp <= ps_rc_quant->i2_max_qp);
533
    /*bitrate init*/
534
    /*take average bitrate from comfig file*/
535
0
    i4_avg_bitrate = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
536
0
                         .ai4_tgt_bitrate[i4_bitrate_instance_id];
537
538
0
    if((ps_init_prms->s_config_prms.i4_rate_control_mode == VBR_STREAMING) &&
539
0
       (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
540
0
            .ai4_peak_bitrate[i4_bitrate_instance_id] < (1050 * (i4_avg_bitrate / 1000))))
541
0
    {
542
0
        ps_init_prms->s_config_prms.i4_rate_control_mode = CBR_NLDRC;
543
0
    }
544
545
0
    ps_rc_ctxt->e_rate_control_type = (rc_type_e)ps_init_prms->s_config_prms.i4_rate_control_mode;
546
0
    ps_rc_ctxt->i4_capped_vbr_flag = 0;
547
0
    if(1 == ps_init_prms->s_config_prms.i4_rate_control_mode)
548
0
    {
549
        /* The path taken by capped vbr mode is same as normal VBR mode. Only a flag needs to be enabled
550
           which tells the rc module that encoder is running in capped vbr mode */
551
0
        ps_rc_ctxt->e_rate_control_type = VBR_STREAMING;
552
0
        ps_rc_ctxt->i4_capped_vbr_flag = 1;
553
0
    }
554
0
    ASSERT(
555
0
        (ps_rc_ctxt->e_rate_control_type == CBR_NLDRC) ||
556
0
        (ps_rc_ctxt->e_rate_control_type == CONST_QP) ||
557
0
        (ps_rc_ctxt->e_rate_control_type == VBR_STREAMING));
558
559
0
    ps_rc_ctxt->u4_avg_bit_rate = i4_avg_bitrate;
560
0
    for(i = 0; i < MAX_PIC_TYPE; i++)
561
0
    {
562
0
        if(ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)
563
0
        {
564
0
            ps_rc_ctxt->au4_peak_bit_rate[i] =
565
0
                ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
566
0
                    .ai4_peak_bitrate[i4_bitrate_instance_id];
567
0
        }
568
0
        else
569
0
        {
570
            /*peak bitrate parameter is ignored in CBR*/
571
0
            ps_rc_ctxt->au4_peak_bit_rate[i] = i4_avg_bitrate;
572
0
        }
573
0
    }
574
0
    ps_rc_ctxt->u4_min_bit_rate = i4_avg_bitrate;
575
576
    /*buffer size init*/
577
0
    u4_buf_size = (WORD32)(ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
578
0
                               .ai4_max_vbv_buffer_size[i4_bitrate_instance_id]);
579
0
    ps_rc_ctxt->u4_max_delay = (UWORD32)(
580
0
        (float)u4_buf_size / i4_avg_bitrate * 1000); /*delay in milli-seconds based on buffer size*/
581
0
    ps_rc_ctxt->u4_max_vbv_buff_size = u4_buf_size; /*buffer size should be in bits*/
582
    /*This dictates the max deviaiton allowed for file size in VBR mode. */
583
0
    ps_rc_ctxt->f_vbr_max_peak_sustain_dur =
584
0
        ((float)ps_init_prms->s_config_prms.i4_vbr_max_peak_rate_dur) / 1000;
585
0
    ps_rc_ctxt->i8_num_frms_to_encode = (WORD32)ps_init_prms->s_config_prms.i4_num_frms_to_encode;
586
0
    i4_peak_bitrate_factor = (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
587
0
                                  .ai4_peak_bitrate[i4_bitrate_instance_id] /
588
0
                              i4_avg_bitrate) *
589
0
                             1000;
590
0
    {
591
        //float f_delay = ((float)ps_init_prms->s_config_prms.i4_max_vbv_buffer_size*1000)/i4_peak_bitrate_factor;
592
0
        float f_delay = ((float)ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
593
0
                             .ai4_max_vbv_buffer_size[i4_bitrate_instance_id] *
594
0
                         1000) /
595
0
                        ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
596
0
                            .ai4_peak_bitrate[i4_bitrate_instance_id];
597
0
        ps_rc_ctxt->i4_initial_decoder_delay_frames = (WORD32)(
598
0
            ((f_delay) * (ps_init_prms->s_src_prms.i4_frm_rate_num /
599
0
                          (ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
600
0
                               .i4_frm_rate_scale_factor *
601
0
                           ps_init_prms->s_src_prms.i4_frm_rate_denom))) /
602
0
            1000);
603
0
    }
604
    /*Initial buffer fullness*/
605
0
    ps_rc_ctxt->i4_init_vbv_fullness = ps_init_prms->s_config_prms.i4_init_vbv_fullness;
606
607
    /*Init Qp updation. This seems to be used for pre enc stage of second frame. Needs to be looked into*/
608
0
    ps_rc_ctxt->i4_init_frame_qp_user = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id]
609
0
                                            .ai4_frame_qp[i4_bitrate_instance_id];
610
611
0
    for(i = 0; i < MAX_SCENE_NUM; i++)
612
0
    {
613
0
        for(j = 0; j < MAX_PIC_TYPE; j++)
614
0
            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i][j] = INIT_HEVCE_QP_RC;
615
0
    }
616
0
    memset(&ps_rc_ctxt->ai4_scene_numbers[0], 0, sizeof(ps_rc_ctxt->ai4_scene_numbers));
617
0
    memset(&ps_rc_ctxt->ai4_scene_num_last_pic[0], 0, sizeof(ps_rc_ctxt->ai4_scene_num_last_pic));
618
0
    ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0] = ps_rc_ctxt->i4_min_frame_qp - 1;
619
0
    ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1] = ps_rc_ctxt->i4_min_frame_qp - 1;
620
    /* SGI & Enc Loop Parallelism related changes*/
621
0
    for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
622
0
    {
623
0
        ps_rc_ctxt->ai8_cur_frm_intra_cost[i] = 0;
624
0
        ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i] = 0;
625
0
        ps_rc_ctxt->ai4_I_model_only_reset[i] = 0;
626
0
        ps_rc_ctxt->ai4_is_non_I_scd_pic[i] = 0;
627
0
        ps_rc_ctxt->ai4_is_pause_to_resume[i] = 0;
628
0
        ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i] = 0;
629
0
        ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i] = 0;
630
        /*initialize assuming 30 percent intra and 70 percent inter weightage*/
631
0
        ps_rc_ctxt->ai4_lap_complexity_q7[i] = MODERATE_LAP2_COMPLEXITY_Q7;
632
633
0
        ps_rc_ctxt->ai4_lap_f_sim[i] = MODERATE_FSIM_VALUE;
634
0
    }
635
636
    /*Init variables required to handle entropy and rdopt consumption mismatch*/
637
0
    ps_rc_ctxt->i4_rdopt_bit_count = 0;
638
0
    ps_rc_ctxt->i4_entropy_bit_count = 0;
639
0
    for(i = 0; i < NUM_BUF_RDOPT_ENT_CORRECT; i++)
640
0
    {
641
0
        ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[i] =
642
0
            -1; /*negative bit signifies that value is not populated*/
643
0
        ps_rc_ctxt->ai4_rdopt_bit_consumption_buf_id[i] = -1;
644
0
        ps_rc_ctxt->ai4_entropy_bit_consumption[i] = -1;
645
0
        ps_rc_ctxt->ai4_entropy_bit_consumption_buf_id[i] = -1;
646
0
    }
647
648
    /** scd model reset related param init*/
649
0
    for(i = 0; i < MAX_NUM_TEMPORAL_LAYERS; i++)
650
0
    {
651
0
        ps_rc_ctxt->au4_scene_num_temp_id[i] = 0;
652
0
    }
653
    /* SGI & Enc Loop Parallelism related changes*/
654
0
    for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
655
0
    {
656
0
        ps_rc_ctxt->ai4_is_frame_scd[i] = 0;
657
0
    }
658
659
    /*Stat file pointer passed from applicaition*/
660
0
    ps_rc_ctxt->pf_stat_file = NULL;
661
0
    ps_rc_ctxt->i8_num_frame_read = 0;
662
663
0
    return ps_rc_ctxt;
664
0
}
665
666
/*###############################################*/
667
/******* END OF RC MEM INIT FUNCTIONS **********/
668
/*###############################################*/
669
670
/*###############################################*/
671
/******* START OF RC INIT FUNCTIONS **************/
672
/*###############################################*/
673
/**
674
******************************************************************************
675
*
676
*  @brief Initialises teh Rate control ctxt
677
*
678
*  @par   Description
679
*
680
*  @param[inout]   pv_ctxt
681
*  pointer to memory descriptors table
682
*
683
*  @param[in]      ps_run_time_src_param
684
*  Create time static parameters
685
*
686
*  @return      void
687
*
688
******************************************************************************
689
*/
690
void ihevce_rc_init(
691
    void *pv_ctxt,
692
    ihevce_src_params_t *ps_run_time_src_param,
693
    ihevce_tgt_params_t *ps_tgt_params,
694
    rc_quant_t *ps_rc_quant,
695
    ihevce_sys_api_t *ps_sys_api,
696
    ihevce_lap_params_t *ps_lap_prms,
697
    WORD32 i4_num_frame_parallel)
698
0
{
699
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
700
0
    WORD32 i, i_temp, j;
701
0
    float f_temp;
702
703
    /*run time width and height has to considered*/
704
0
    ps_rc_ctxt->i4_frame_height = ps_tgt_params->i4_height;
705
0
    ps_rc_ctxt->i4_frame_width = ps_tgt_params->i4_width;
706
0
    ps_rc_ctxt->i4_field_pic = ps_run_time_src_param->i4_field_pic;
707
0
    ps_rc_ctxt->i8_num_bit_alloc_period = 0;
708
0
    ps_rc_ctxt->i8_new_bitrate = -1; /*-1 indicates no dynamic change in bitrate request pending*/
709
0
    ps_rc_ctxt->i8_new_peak_bitrate = -1;
710
711
0
    ps_rc_ctxt->i4_is_last_frame_scan = 0;
712
713
0
    memset(ps_rc_ctxt->ai4_offsets, 0, 5 * sizeof(WORD32));
714
715
0
    ps_rc_ctxt->i4_complexity_bin = 5;
716
0
    ps_rc_ctxt->i4_last_p_or_i_frame_gop = 0;
717
0
    ps_rc_ctxt->i4_qp_at_I_frame_for_skip_sad = 1;
718
0
    ps_rc_ctxt->i4_denominator_i_to_avg = 1;
719
0
    ps_rc_ctxt->i4_fp_bit_alloc_in_sp = 0;
720
721
0
    ps_rc_ctxt->ai4_offsets[0] = 0;
722
0
    ps_rc_ctxt->ai4_offsets[1] = 1;
723
0
    ps_rc_ctxt->ai4_offsets[2] = 2;
724
0
    ps_rc_ctxt->ai4_offsets[3] = 3;
725
0
    ps_rc_ctxt->ai4_offsets[4] = 4;
726
727
0
    ps_rc_ctxt->i4_num_frames_subgop = 0;
728
0
    ps_rc_ctxt->i8_total_acc_coarse_me_sad = 0;
729
730
0
    ps_rc_ctxt->i4_L0_frame_qp = 1;
731
732
0
    ps_rc_ctxt->i4_est_text_bits_ctr_get_qp = 0;
733
0
    ps_rc_ctxt->i4_est_text_bits_ctr_update_qp = 0;
734
735
    /*CAllback functions need to be copied for use inside RC*/
736
0
    ps_rc_ctxt->ps_sys_rc_api = ps_sys_api;
737
738
0
    f_temp = ((float)(ps_rc_quant->i2_max_qp + ps_rc_quant->i1_qp_offset - 4) / 6);
739
740
0
    ps_rc_quant->i2_max_qscale = (WORD16)((float)pow(2, f_temp) + 0.5) << 3;
741
742
0
    f_temp = ((float)(ps_rc_quant->i2_min_qp + ps_rc_quant->i1_qp_offset - 4) / 6);
743
744
0
    ps_rc_quant->i2_min_qscale = (WORD16)((float)pow(2, f_temp) + 0.5);
745
746
0
    f_temp =
747
0
        ((float)(51 + ps_rc_quant->i1_qp_offset - 4) /
748
0
         6);  // default MPEG2 to HEVC and HEVC to MPEG2 Qp conversion tables
749
0
    i_temp = (WORD16)((float)pow(2, f_temp) + 0.5);
750
751
0
    i_temp = (i_temp << 3);  // Q3 format is mantained for accuarate calc at lower qp
752
753
0
    for(i = 0; i <= i_temp; i++)
754
0
    {
755
0
        ps_rc_quant->pi4_qscale_to_qp[i] =
756
0
            ihevce_rc_get_scaled_hevce_qp_q3(i, ps_rc_ctxt->u1_bit_depth);
757
0
    }
758
759
0
    for(i = (0 - ps_rc_quant->i1_qp_offset); i <= 51; i++)
760
0
    {
761
0
        ps_rc_quant->pi4_qp_to_qscale_q_factor[i + ps_rc_quant->i1_qp_offset] =
762
0
            ihevce_rc_get_scaled_mpeg2_qp_q6(
763
0
                i + ps_rc_quant->i1_qp_offset, ps_rc_ctxt->u1_bit_depth);
764
0
        ps_rc_quant->pi4_qp_to_qscale[i + ps_rc_quant->i1_qp_offset] =
765
0
            ((ps_rc_quant->pi4_qp_to_qscale_q_factor[i + ps_rc_quant->i1_qp_offset] +
766
0
              (1 << (QSCALE_Q_FAC_3 - 1))) >>
767
0
             QSCALE_Q_FAC_3);
768
0
    }
769
770
0
    if(ps_rc_quant->i2_min_qscale < 1)
771
0
    {
772
0
        ps_rc_quant->i2_min_qscale = 1;
773
0
    }
774
775
0
    ps_rc_ctxt->ps_rc_quant_ctxt = ps_rc_quant;
776
777
    /*Frame rate init*/
778
0
    ps_rc_ctxt->u4_max_frame_rate =
779
0
        ps_run_time_src_param->i4_frm_rate_num / ps_tgt_params->i4_frm_rate_scale_factor;
780
0
    ps_rc_ctxt->i4_top_field_first = ps_run_time_src_param->i4_topfield_first; /**/
781
    /*min and max qp initialization*/
782
0
    if(ps_rc_ctxt->i4_field_pic == 0)
783
0
    {
784
0
        WORD32 i4_max_qp = 0;
785
786
0
        if(ps_rc_ctxt->u1_bit_depth == 10)
787
0
        {
788
0
            i4_max_qp = MAX_HEVC_QP_10bit;
789
0
        }
790
0
        else if(ps_rc_ctxt->u1_bit_depth == 12)
791
0
        {
792
0
            i4_max_qp = MAX_HEVC_QP_12bit;
793
0
        }
794
0
        else
795
0
        {
796
0
            i4_max_qp = MAX_HEVC_QP;
797
0
        }
798
799
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
800
0
        {
801
0
            if((ps_rc_ctxt->i4_init_frame_qp_user + (2 * i) +
802
0
                ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset) <=
803
0
               i4_max_qp)  //BUG_FIX related to init QP allocation
804
0
            {
805
0
                ps_rc_ctxt->ai4_init_qp[i] = (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale
806
0
                                                  [(ps_rc_ctxt->i4_init_frame_qp_user + (2 * i)) +
807
0
                                                   ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset] +
808
0
                                              (1 << (QSCALE_Q_FAC_3 - 1))) >>
809
0
                                             QSCALE_Q_FAC_3;
810
0
            }
811
0
            else
812
0
            {
813
0
                ps_rc_ctxt->ai4_init_qp[i] =
814
0
                    (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale[i4_max_qp] +
815
0
                     (1 << (QSCALE_Q_FAC_3 - 1))) >>
816
0
                    QSCALE_Q_FAC_3;  // + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
817
0
            }
818
0
            ps_rc_ctxt->ai4_min_max_qp[i * 2] =
819
0
                ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qscale; /*min qp for each picture type*/
820
0
            ps_rc_ctxt->ai4_min_max_qp[i * 2 + 1] = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qscale >>
821
0
                                                    QSCALE_Q_FAC_3; /*max qp for each picture type*/
822
0
        }
823
0
    }
824
0
    else
825
0
    {
826
0
        WORD32 i4_num_pic_types = MAX_PIC_TYPE;
827
0
        WORD32 i4_max_qp = 0;
828
829
0
        if(ps_rc_ctxt->u1_bit_depth == 10)
830
0
        {
831
0
            i4_max_qp = MAX_HEVC_QP_10bit;
832
0
        }
833
0
        else if(ps_rc_ctxt->u1_bit_depth == 12)
834
0
        {
835
0
            i4_max_qp = MAX_HEVC_QP_12bit;
836
0
        }
837
0
        else
838
0
        {
839
0
            i4_max_qp = MAX_HEVC_QP;
840
0
        }
841
842
0
        i4_num_pic_types >>= 1;
843
844
0
        for(i = 0; i < i4_num_pic_types; i++)
845
0
        {
846
0
            if((ps_rc_ctxt->i4_init_frame_qp_user + (2 * i) +
847
0
                ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset) <= i4_max_qp)
848
0
            {
849
0
                ps_rc_ctxt->ai4_init_qp[i] = (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale
850
0
                                                  [(ps_rc_ctxt->i4_init_frame_qp_user + (2 * i)) +
851
0
                                                   ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset] +
852
0
                                              (1 << (QSCALE_Q_FAC_3 - 1))) >>
853
0
                                             QSCALE_Q_FAC_3;
854
855
0
                if(i != 0)
856
0
                    ps_rc_ctxt->ai4_init_qp[i + FIELD_OFFSET] = ps_rc_ctxt->ai4_init_qp[i];
857
0
            }
858
0
            else
859
0
            {
860
0
                ps_rc_ctxt->ai4_init_qp[i] =
861
0
                    (ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale[i4_max_qp] +
862
0
                     (1 << (QSCALE_Q_FAC_3 - 1))) >>
863
0
                    QSCALE_Q_FAC_3;  // + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
864
865
0
                if(i != 0)
866
0
                    ps_rc_ctxt->ai4_init_qp[i + FIELD_OFFSET] = ps_rc_ctxt->ai4_init_qp[i];
867
0
            }
868
0
            ps_rc_ctxt->ai4_min_max_qp[i * 2] =
869
0
                ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qscale; /*min qp for each picture type*/
870
0
            ps_rc_ctxt->ai4_min_max_qp[i * 2 + 1] = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qscale >>
871
0
                                                    QSCALE_Q_FAC_3; /*max qp for each picture type*/
872
0
            if(i != 0)
873
0
            {
874
0
                ps_rc_ctxt->ai4_min_max_qp[(i + FIELD_OFFSET) * 2] =
875
0
                    ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qscale; /*min qp for each picture type*/
876
0
                ps_rc_ctxt->ai4_min_max_qp[(i + FIELD_OFFSET) * 2 + 1] =
877
0
                    ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qscale; /*max qp for each picture type*/
878
0
            }
879
0
        }
880
0
    }
881
882
0
    for(j = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
883
0
    {
884
        /*initialise the coeffs to 1 in case lap is not used */
885
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
886
0
        {
887
0
            ps_rc_ctxt->af_sum_weigh[j][i][0] = 1.0;
888
0
            ps_rc_ctxt->af_sum_weigh[j][i][1] = 0.0;
889
0
            ps_rc_ctxt->af_sum_weigh[j][i][2] = 0.0;
890
0
        }
891
0
    }
892
893
0
    ps_rc_ctxt->i4_num_frame_parallel = i4_num_frame_parallel;  //ELP_RC
894
0
    i4_num_frame_parallel = (i4_num_frame_parallel > 1) ? i4_num_frame_parallel : 0;
895
896
0
    if(ps_rc_ctxt->i4_num_frame_parallel > 1)
897
0
    {
898
0
        ps_rc_ctxt->i4_pre_enc_rc_delay = MAX_PRE_ENC_RC_DELAY;
899
0
    }
900
0
    else
901
0
    {
902
0
        ps_rc_ctxt->i4_pre_enc_rc_delay = MIN_PRE_ENC_RC_DELAY;
903
0
    }
904
    /*Bitrate and resolutioon based scene cut min qp*/
905
0
    {
906
        /*The min qp for scene cut frame is chosen based on bitrate*/
907
0
        float i4_bpp = ((float)ps_rc_ctxt->u4_avg_bit_rate / ps_rc_ctxt->u4_max_frame_rate) * 1000 /
908
0
                       (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
909
0
        if(ps_rc_ctxt->u4_intra_frame_interval == 1)
910
0
        {
911
            /*Ultra High resolution)*/
912
0
            if((ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) > 5000000)
913
0
            {
914
0
                if(i4_bpp > 0.24)
915
0
                {
916
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
917
0
                }
918
0
                else if(i4_bpp > 0.16)
919
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp =
920
0
                        SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 40mbps for 4k 30p*/
921
0
                else
922
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
923
0
            }
924
0
            else
925
0
            {
926
0
                if(i4_bpp > 0.32)
927
0
                {
928
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
929
0
                }
930
0
                else if(i4_bpp > 0.24)
931
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp =
932
0
                        SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 15mbps for 1080 30p*/
933
0
                else
934
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
935
0
            }
936
0
        }
937
0
        else
938
0
        {
939
            /*Ultra High resolution)*/
940
0
            if((ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) > 5000000)
941
0
            {
942
0
                if(i4_bpp > 0.16)
943
0
                {
944
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
945
0
                }
946
0
                else if(i4_bpp > 0.08)
947
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp =
948
0
                        SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 20mbps for 4k 30p*/
949
0
                else
950
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
951
0
            }
952
0
            else
953
0
            {
954
                /*Resolution lesser than full HD (including )*/
955
0
                if(i4_bpp > 0.24)
956
0
                {
957
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP_VHBR;
958
0
                }
959
0
                else if(i4_bpp > 0.16)
960
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp =
961
0
                        SCD_MIN_HEVC_QP_HBR; /*corresponds to bitrate greater than 10mbps for 1080 30p*/
962
0
                else
963
0
                    ps_rc_ctxt->i4_min_scd_hevc_qp = SCD_MIN_HEVC_QP;
964
0
            }
965
0
        }
966
0
    }
967
968
0
    initialise_rate_control(
969
0
        ps_rc_ctxt->rc_hdl,
970
0
        ps_rc_ctxt->e_rate_control_type,
971
0
        ps_rc_ctxt->u1_is_mb_level_rc_on,  //0,/*disabling MB level RC*/
972
0
        ps_rc_ctxt->u4_avg_bit_rate,
973
0
        ps_rc_ctxt->au4_peak_bit_rate,
974
0
        ps_rc_ctxt->u4_min_bit_rate,
975
0
        ps_rc_ctxt->u4_max_frame_rate,
976
0
        ps_rc_ctxt->u4_max_delay, /*max delay in milli seconds based on buffer size*/
977
0
        ps_rc_ctxt->u4_intra_frame_interval,
978
0
        ps_rc_ctxt->u4_idr_period,
979
0
        ps_rc_ctxt->ai4_init_qp,
980
0
        ps_rc_ctxt->u4_max_vbv_buff_size,
981
0
        ps_rc_ctxt->i4_max_inter_frm_int,
982
0
        ps_rc_ctxt->i4_is_gop_closed,
983
0
        ps_rc_ctxt->ai4_min_max_qp, /*min and max qp to be used for each of picture type*/
984
0
        ps_rc_ctxt->i4_use_est_intra_sad,
985
0
        ps_rc_ctxt->u4_src_ticks,
986
0
        ps_rc_ctxt->u4_tgt_ticks,
987
0
        ps_rc_ctxt->i4_frame_height, /*pels in frame considering 420 semi planar format*/
988
0
        ps_rc_ctxt->i4_frame_width,
989
0
        ps_rc_ctxt->i4_num_active_pic_type,
990
0
        ps_rc_ctxt->i4_field_pic,
991
0
        ps_rc_ctxt->i4_quality_preset,
992
0
        ps_rc_ctxt->i4_num_frame_in_lap_window,
993
0
        ps_rc_ctxt->i4_initial_decoder_delay_frames,
994
0
        ps_rc_ctxt->f_vbr_max_peak_sustain_dur,
995
0
        ps_rc_ctxt->i8_num_frms_to_encode,
996
0
        ps_rc_ctxt->i4_min_scd_hevc_qp,
997
0
        ps_rc_ctxt->u1_bit_depth,
998
0
        ps_rc_ctxt->pf_stat_file,
999
0
        ps_rc_ctxt->i4_rc_pass,
1000
0
        ps_rc_ctxt->pv_gop_stat,
1001
0
        ps_rc_ctxt->i8_num_gop_mem_alloc,
1002
0
        ps_rc_ctxt->i4_is_infinite_gop,
1003
0
        sizeof(ihevce_lap_output_params_t),
1004
0
        sizeof(rc_lap_out_params_t),
1005
0
        (void *)ps_sys_api,
1006
0
        ps_rc_ctxt->i4_fp_bit_alloc_in_sp,
1007
0
        i4_num_frame_parallel,
1008
0
        ps_rc_ctxt->i4_capped_vbr_flag);
1009
1010
    //ps_rc_ctxt->i4_init_vbv_fullness = 500000;
1011
0
    rc_init_set_ebf(ps_rc_ctxt->rc_hdl, ps_rc_ctxt->i4_init_vbv_fullness);
1012
1013
    /*get init qp based on ebf for rate control*/
1014
0
    if(ps_rc_ctxt->e_rate_control_type != CONST_QP)
1015
0
    {
1016
0
        WORD32 I_frame_qp, I_frame_mpeg2_qp;
1017
        /*assume moderate fsim*/
1018
0
        WORD32 i4_fsim_global = MODERATE_FSIM_VALUE;
1019
0
        I_frame_mpeg2_qp = rc_get_bpp_based_scene_cut_qp(
1020
0
            ps_rc_ctxt->rc_hdl,
1021
0
            I_PIC,
1022
0
            ((3 * ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 1),
1023
0
            i4_fsim_global,
1024
0
            ps_rc_ctxt->af_sum_weigh[0],
1025
0
            1);
1026
1027
0
        I_frame_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(
1028
0
            I_frame_mpeg2_qp << QSCALE_Q_FAC_3, ps_rc_ctxt->ps_rc_quant_ctxt);
1029
1030
0
        I_frame_qp = I_frame_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1031
1032
0
        if(I_frame_qp > 44)
1033
0
            I_frame_qp = 44;
1034
1035
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[I_PIC] = I_frame_qp;
1036
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[P_PIC] = I_frame_qp + 1;
1037
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[B_PIC] = I_frame_qp + 2;
1038
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[B1_PIC] = I_frame_qp + 3;
1039
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[B2_PIC] = I_frame_qp + 4;
1040
        /*Bottom fields*/
1041
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[P1_PIC] = I_frame_qp + 1;
1042
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[BB_PIC] = I_frame_qp + 2;
1043
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[B11_PIC] = I_frame_qp + 3;
1044
0
        ps_rc_ctxt->ai4_init_pre_enc_qp[B22_PIC] = I_frame_qp + 4;
1045
1046
0
        ps_rc_ctxt->i4_pre_enc_qp_read_index = 0;
1047
0
        ps_rc_ctxt->i4_pre_enc_qp_write_index = ps_rc_ctxt->i4_pre_enc_rc_delay - 1;
1048
0
        for(i = 0; i < ps_rc_ctxt->i4_pre_enc_rc_delay; i++)
1049
0
        {
1050
            /*initialize it to -1 to indicate it as not produced*/
1051
0
            ps_rc_ctxt->as_pre_enc_qp_queue[i].i4_is_qp_valid = -1;
1052
0
        }
1053
0
        for(i = 0; i < (ps_rc_ctxt->i4_pre_enc_qp_write_index); i++)
1054
0
        {
1055
0
            WORD32 j;
1056
0
            ps_rc_ctxt->as_pre_enc_qp_queue[i].i4_is_qp_valid = 1;
1057
0
            for(j = 0; j < MAX_PIC_TYPE; j++)
1058
0
            {
1059
0
                ps_rc_ctxt->as_pre_enc_qp_queue[i].ai4_quant[j] =
1060
0
                    ps_rc_ctxt->ai4_init_pre_enc_qp[j];
1061
0
                ps_rc_ctxt->as_pre_enc_qp_queue[i].i4_scd_qp =
1062
0
                    ps_rc_ctxt->ai4_init_pre_enc_qp[I_PIC];
1063
0
            }
1064
0
        }
1065
1066
0
        ps_rc_ctxt->i4_use_qp_offset_pre_enc = 1;
1067
0
        ps_rc_ctxt->i4_num_frms_from_reset = 0;
1068
        /* SGI & Enc Loop Parallelism related changes*/
1069
0
        ps_rc_ctxt->u4_prev_scene_num = 0;
1070
        //ps_rc_ctxt->i4_use_init_qp_for_pre_enc = 0;
1071
0
        for(j = 0; j < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; j++)
1072
0
        {
1073
0
            ps_rc_ctxt->au4_prev_scene_num_multi_scene[j] = 0x3FFFFFFF;
1074
0
            for(i = 0; i < MAX_PIC_TYPE; i++)
1075
0
            {
1076
0
                ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[j][i] =
1077
0
                    ps_rc_ctxt->ai4_init_pre_enc_qp[i];
1078
0
            }
1079
0
        }
1080
1081
        /* SGI & Enc Loop Parallelism related changes*/
1082
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
1083
0
        {
1084
0
            ps_rc_ctxt->ai4_qp_for_previous_scene[i] = ps_rc_ctxt->ai4_init_pre_enc_qp[i];
1085
0
        }
1086
0
    }
1087
0
    else
1088
0
    {
1089
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
1090
0
        {
1091
0
            ps_rc_ctxt->ai4_init_pre_enc_qp[i] = ps_rc_ctxt->i4_init_frame_qp_user;
1092
0
            ps_rc_ctxt->ai4_qp_for_previous_scene[i] = ps_rc_ctxt->i4_init_frame_qp_user;
1093
0
        }
1094
0
    }
1095
0
}
1096
1097
/**
1098
******************************************************************************
1099
*
1100
*  @brief Populate common params from lap_out structure to rc_lap_out structure
1101
*         Also the init of some rc_lap_out params done here
1102
*  @par   Description
1103
*
1104
*  @param[in]   ps_lap_out
1105
*  pointer to lap_out structure
1106
*
1107
*  @param[out]      ps_rc_lap_out
1108
*  pointer to rc_lap_out structure
1109
*
1110
*  @return      void
1111
*
1112
******************************************************************************
1113
*/
1114
1115
void ihevce_rc_populate_common_params(
1116
    ihevce_lap_output_params_t *ps_lap_out, rc_lap_out_params_t *ps_rc_lap_out)
1117
0
{
1118
    /* Update common params */
1119
1120
0
    ps_rc_lap_out->i4_rc_pic_type = ps_lap_out->i4_pic_type;
1121
0
    ps_rc_lap_out->i4_rc_poc = ps_lap_out->i4_poc;
1122
0
    ps_rc_lap_out->i4_rc_temporal_lyr_id = ps_lap_out->i4_temporal_lyr_id;
1123
0
    ps_rc_lap_out->i4_rc_is_ref_pic = ps_lap_out->i4_is_ref_pic;
1124
0
    ps_rc_lap_out->i4_rc_scene_type = ps_lap_out->i4_scene_type;
1125
0
    ps_rc_lap_out->u4_rc_scene_num = ps_lap_out->u4_scene_num;
1126
0
    ps_rc_lap_out->i4_rc_display_num = ps_lap_out->i4_display_num;
1127
0
    ps_rc_lap_out->i4_rc_quality_preset = ps_lap_out->i4_quality_preset;
1128
0
    ps_rc_lap_out->i4_rc_first_field = ps_lap_out->i4_first_field;
1129
1130
    /*params populated in LAP-2*/
1131
0
    ps_rc_lap_out->i8_frame_acc_coarse_me_cost = -1;
1132
0
    memset(ps_rc_lap_out->ai8_frame_acc_coarse_me_sad, -1, sizeof(WORD32) * 52);
1133
1134
0
    ps_rc_lap_out->i8_pre_intra_satd = -1;
1135
1136
0
    ps_rc_lap_out->i8_raw_pre_intra_sad = -1;
1137
1138
0
    ps_rc_lap_out->i8_raw_l1_coarse_me_sad = -1;
1139
1140
0
    ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated = 1;
1141
    /* SGI & Enc Loop Parallelism related changes*/
1142
0
    ps_rc_lap_out->i4_ignore_for_rc_update = 0;
1143
1144
    /*For 1 pass HQ I frames*/
1145
1146
0
    ps_rc_lap_out->i4_complexity_bin = 5;
1147
0
    {
1148
0
        WORD32 ai4_offsets[5] = { 0, 1, 2, 3, 4 };
1149
0
        memmove(ps_rc_lap_out->ai4_offsets, ai4_offsets, sizeof(WORD32) * 5);
1150
0
        ps_rc_lap_out->i4_offsets_set_flag = -1;
1151
0
    }
1152
1153
0
    ps_rc_lap_out->i4_L1_qp = -1;
1154
0
    ps_rc_lap_out->i4_L0_qp = -1;
1155
0
}
1156
1157
/*###############################################*/
1158
/******* END OF RC INIT FUNCTIONS **************/
1159
/*###############################################*/
1160
1161
/*#########################################################*/
1162
/******* START OF PRE-ENC QP QUERY FUNCTIONS **************/
1163
/*#######################################################*/
1164
1165
/**
1166
******************************************************************************
1167
*
1168
*  @name  ihevce_rc_get_bpp_based_frame_qp
1169
*
1170
*  @par   Description
1171
*
1172
*  @param[in]   ps_rc_ctxt  - pointer to rc context
1173
*               ps_rc_lap_out
1174
*  @return      frame qp
1175
*
1176
******************************************************************************
1177
*/
1178
WORD32 ihevce_rc_get_bpp_based_frame_qp(void *pv_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out)
1179
0
{
1180
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
1181
0
    WORD32 i4_frame_qs_q3, i4_hevc_frame_qp, i;
1182
0
    frame_info_t *ps_frame_info;
1183
0
    picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
1184
0
        (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
1185
0
        ps_rc_ctxt->i4_field_pic,
1186
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
1187
0
        ps_rc_lap_out->i4_is_bottom_field,
1188
0
        ps_rc_ctxt->i4_top_field_first);
1189
    /*initialise the coeffs to 1 in case lap is not used */
1190
0
    for(i = 0; i < MAX_PIC_TYPE; i++)
1191
0
    {
1192
0
        ps_rc_ctxt->af_sum_weigh[0][i][0] = 1.0;
1193
0
        ps_rc_ctxt->af_sum_weigh[0][i][1] = 0.0;
1194
0
        ps_rc_ctxt->af_sum_weigh[0][i][2] = 0.0;
1195
0
    }
1196
0
    {
1197
        /*scene cut handling during pre-enc stage*/
1198
        /*assume lap fsim as 117. not used since ratio is direclt sent*/
1199
0
        if(ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
1200
0
        {
1201
0
            for(i = 0; i < MAX_PIC_TYPE; i++)
1202
0
            {
1203
0
                ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i] = -1;
1204
0
                ps_rc_ctxt->ai8_prev_frame_hme_sad[i] = -1;
1205
0
                ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i] = -1;
1206
0
            }
1207
0
            ps_rc_ctxt->i4_is_est_L0_intra_sad_available = 0;
1208
0
        }
1209
1210
0
        if(ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT ||
1211
0
           !ps_rc_ctxt->i4_is_est_L0_intra_sad_available)
1212
0
        {
1213
            /*compute bpp based qp if current frame is scene cut or data is not sufficient*/
1214
0
            i4_frame_qs_q3 = rc_get_bpp_based_scene_cut_qp(
1215
0
                ps_rc_ctxt->rc_hdl,
1216
0
                I_PIC,
1217
0
                ((3 * ps_rc_lap_out->i4_num_pels_in_frame_considered) >> 1),
1218
0
                117,
1219
0
                ps_rc_ctxt->af_sum_weigh[0],
1220
0
                0);
1221
0
            i4_frame_qs_q3 = i4_frame_qs_q3 << QSCALE_Q_FAC_3;
1222
0
        }
1223
0
        else
1224
0
        {
1225
            /*using previous one sub-gop data calculate i to rest ratio and qp assuming it is I frame*/
1226
0
            WORD32 i4_num_b, i, ai4_pic_dist[MAX_PIC_TYPE], index, i4_total_bits;
1227
0
            LWORD64 i8_average_pre_intra_sad = 0, i8_average_est_l0_satd_by_act = 0;
1228
0
            double lambda_modifier[MAX_PIC_TYPE], complexity[MAX_PIC_TYPE], den = 0.0f,
1229
0
                                                                            i_to_rest_bit_ratio;
1230
0
            WORD32 i4_curr_bits_estimated = 0;
1231
1232
0
            for(i = 0; i < MAX_PIC_TYPE; i++)
1233
0
            {
1234
0
                complexity[i] = 0;
1235
0
                lambda_modifier[i] = 0;
1236
0
                ai4_pic_dist[i] = 0;
1237
0
            }
1238
1239
0
            index = ihevce_get_offline_index(
1240
0
                ps_rc_ctxt, ps_rc_lap_out->i4_num_pels_in_frame_considered);
1241
0
            if(ps_rc_ctxt->i4_max_temporal_lyr)
1242
0
            {
1243
0
                i4_num_b = ((WORD32)pow((float)2, ps_rc_ctxt->i4_max_temporal_lyr)) - 1;
1244
0
            }
1245
0
            else
1246
0
            {
1247
0
                i4_num_b = 0;
1248
0
            }
1249
1250
0
            lambda_modifier[I_PIC] =
1251
0
                ihevce_get_frame_lambda_modifier((WORD8)I_PIC, 0, 1, 1, i4_num_b);
1252
0
            lambda_modifier[P_PIC] =
1253
0
                ihevce_get_frame_lambda_modifier((WORD8)P_PIC, 0, 1, 1, i4_num_b) *
1254
0
                pow((float)1.125, 1);
1255
0
            lambda_modifier[B_PIC] =
1256
0
                ihevce_get_frame_lambda_modifier(
1257
0
                    (WORD8)B_PIC, 1, (ps_rc_ctxt->i4_max_temporal_lyr > 1), 1, i4_num_b) *
1258
0
                pow((float)1.125, 2);
1259
0
            lambda_modifier[B1_PIC] =
1260
0
                ihevce_get_frame_lambda_modifier(
1261
0
                    (WORD8)B1_PIC, 2, 1, (ps_rc_ctxt->i4_max_temporal_lyr > 2), i4_num_b) *
1262
0
                pow((float)1.125, 3);
1263
0
            lambda_modifier[B2_PIC] =
1264
0
                ihevce_get_frame_lambda_modifier((WORD8)B2_PIC, 3, 1, 0, i4_num_b) *
1265
0
                pow((float)1.125, 4);
1266
1267
            /*consider average of one sub-gop for intra sad*/
1268
1269
0
            if(ps_rc_ctxt->i4_quality_preset == IHEVCE_QUALITY_P6)
1270
0
            {
1271
0
                for(i = 0; i < 2; i++)
1272
0
                {
1273
0
                    i8_average_pre_intra_sad += ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i];
1274
0
                    i8_average_est_l0_satd_by_act += ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i];
1275
0
                    if(ps_rc_ctxt->i4_field_pic == 1 && i != 0)
1276
0
                    {
1277
0
                        i8_average_pre_intra_sad +=
1278
0
                            ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i + FIELD_OFFSET];
1279
0
                        i8_average_est_l0_satd_by_act +=
1280
0
                            ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i + FIELD_OFFSET];
1281
0
                    }
1282
0
                }
1283
0
                if(ps_rc_ctxt->i4_field_pic == 1)
1284
0
                {
1285
0
                    i8_average_pre_intra_sad /= 3;
1286
0
                    i8_average_est_l0_satd_by_act /= 3;
1287
0
                }
1288
0
                else
1289
0
                {
1290
0
                    i8_average_pre_intra_sad <<= 1;
1291
0
                    i8_average_est_l0_satd_by_act <<= 1;
1292
0
                }
1293
0
            }
1294
0
            else
1295
0
            {
1296
0
                for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
1297
0
                {
1298
0
                    i8_average_pre_intra_sad += ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i];
1299
0
                    i8_average_est_l0_satd_by_act += ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i];
1300
0
                    if(ps_rc_ctxt->i4_field_pic == 1 && i != 0)
1301
0
                    {
1302
0
                        i8_average_pre_intra_sad +=
1303
0
                            ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[i + FIELD_OFFSET];
1304
0
                        i8_average_est_l0_satd_by_act +=
1305
0
                            ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i + FIELD_OFFSET];
1306
0
                    }
1307
0
                }
1308
0
                if(ps_rc_ctxt->i4_field_pic == 1)
1309
0
                {
1310
0
                    i8_average_pre_intra_sad /= ((i << 1) - 1);
1311
0
                    i8_average_est_l0_satd_by_act /= ((i << 1) - 1);
1312
0
                }
1313
0
                else
1314
0
                {
1315
0
                    i8_average_pre_intra_sad /= i;
1316
0
                    i8_average_est_l0_satd_by_act /= i;
1317
0
                }
1318
0
            }
1319
1320
            /*no lambda modifier is considered for I pic as other lambda are scaled according to I frame lambda*/
1321
0
            complexity[I_PIC] = (double)i8_average_pre_intra_sad;
1322
1323
0
            for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
1324
0
            {
1325
0
#if !USE_SQRT
1326
0
                complexity[i] = ps_rc_ctxt->ai8_prev_frame_hme_sad[i] / pow(1.125, i);
1327
1328
0
                if(ps_rc_ctxt->i4_field_pic == 1)
1329
0
                {
1330
0
                    complexity[i + FIELD_OFFSET] =
1331
0
                        ps_rc_ctxt->ai8_prev_frame_hme_sad[i + FIELD_OFFSET] / pow(1.125, i);
1332
0
                }
1333
#else
1334
                complexity[i] = ps_rc_ctxt->ai8_prev_frame_hme_sad[i] /
1335
                                (sqrt(lambda_modifier[i] / lambda_modifier[I_PIC]) * pow(1.125, i));
1336
#endif
1337
0
            }
1338
            /*get picture type distribution in LAP*/
1339
0
            rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
1340
1341
0
            for(i = 0; i < MAX_PIC_TYPE; i++)
1342
0
            {
1343
0
                den += complexity[i] * ai4_pic_dist[i];
1344
0
            }
1345
            /*subtract I frame complexity to get I to rest ratio*/
1346
0
            {
1347
0
                WORD32 num_inter_pic = 0;
1348
0
                for(i = 1; i < MAX_PIC_TYPE; i++)
1349
0
                {
1350
0
                    num_inter_pic += ai4_pic_dist[i];
1351
0
                }
1352
0
                if(num_inter_pic > 0)
1353
0
                    den = (den - (complexity[I_PIC] * ai4_pic_dist[I_PIC])) / num_inter_pic;
1354
0
                else
1355
0
                    den = complexity[I_PIC];
1356
0
            }
1357
1358
0
            if(den > 0)
1359
0
                i_to_rest_bit_ratio = (float)((complexity[I_PIC]) / den);
1360
0
            else
1361
0
                i_to_rest_bit_ratio = 15;
1362
1363
            /*get qp for scene cut frame based on offline data*/
1364
0
            i4_frame_qs_q3 = rc_get_qp_for_scd_frame(
1365
0
                ps_rc_ctxt->rc_hdl,
1366
0
                I_PIC,
1367
0
                i8_average_est_l0_satd_by_act,
1368
0
                ps_rc_lap_out->i4_num_pels_in_frame_considered,
1369
0
                -1,
1370
0
                MODERATE_FSIM_VALUE,
1371
0
                (void *)&g_offline_i_model_coeff[index][0],
1372
0
                (float)i_to_rest_bit_ratio,
1373
0
                0,
1374
0
                ps_rc_ctxt->af_sum_weigh[0],
1375
0
                ps_rc_lap_out->ps_frame_info,
1376
0
                ps_rc_ctxt->i4_rc_pass,
1377
0
                0,
1378
0
                0,
1379
0
                0,
1380
0
                &i4_total_bits,
1381
0
                &i4_curr_bits_estimated,
1382
0
                ps_rc_lap_out->i4_use_offline_model_2pass,
1383
0
                0,
1384
0
                0,
1385
0
                -1,
1386
0
                NULL);
1387
0
        }
1388
1389
0
        i4_hevc_frame_qp =
1390
0
            ihevce_rc_get_scaled_hevc_qp_from_qs_q3(i4_frame_qs_q3, ps_rc_ctxt->ps_rc_quant_ctxt);
1391
1392
0
        i4_hevc_frame_qp = i4_hevc_frame_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1393
1394
0
        if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
1395
0
            i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
1396
1397
        /*offset depending on current picture type*/
1398
0
        if(rc_pic_type != I_PIC)
1399
0
            i4_hevc_frame_qp += ps_rc_lap_out->i4_rc_temporal_lyr_id + 1;
1400
        /*clip min and max qp to be within range*/
1401
0
        i4_hevc_frame_qp = ihevce_clip_min_max_qp(
1402
0
            ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
1403
1404
0
        ps_rc_ctxt->ai4_qp_for_previous_scene_pre_enc[rc_pic_type] = i4_hevc_frame_qp;
1405
0
        ps_rc_ctxt->au4_prev_scene_num_pre_enc[rc_pic_type] = ps_rc_lap_out->u4_rc_scene_num;
1406
0
    }
1407
1408
0
    return i4_hevc_frame_qp;
1409
0
}
1410
/**
1411
******************************************************************************
1412
*
1413
*  @name  ihevce_rc_get_pre_enc_pic_quant
1414
*
1415
*  @par   Description - Called from ihevce_rc_cal_pre_enc_qp. updates frame qp
1416
*                       which will be used by next frame of same pic type in
1417
*                       pre-enc stage
1418
*
1419
*  @param[in]   ps_rc_ctxt  - pointer to rc context
1420
*  @return      void
1421
*
1422
******************************************************************************
1423
*/
1424
WORD32
1425
    ihevce_rc_get_pre_enc_pic_quant(void *pv_ctxt, picture_type_e rc_pic_type, WORD32 *pi4_scd_qp)
1426
0
{
1427
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
1428
0
    WORD32 i4_frame_qp, i4_frame_qp_q6, i4_hevc_frame_qp = -1;
1429
0
    WORD32 i4_max_frame_bits = (1 << 30);
1430
0
    WORD32 i4_temporal_layer_id, i4_is_bottom_field, i4_cur_est_texture_bits;
1431
1432
0
    ihevce_rc_get_pic_param(rc_pic_type, &i4_temporal_layer_id, &i4_is_bottom_field);
1433
1434
0
    {
1435
0
        WORD32 is_scd_ref_frame = 0, i4_num_scd_in_lap_window = 0, num_frames_b4_scd = 0;
1436
1437
        /*treat even first frame as scd frame*/
1438
0
        if(!ps_rc_ctxt->i4_is_first_frame_encoded)
1439
0
        {
1440
0
            is_scd_ref_frame = 1;
1441
0
        }
1442
1443
0
        {
1444
            /*Only I frames are considered as scd pic during pre-enc*/
1445
0
            is_scd_ref_frame &= (rc_pic_type == I_PIC);
1446
0
        }
1447
1448
0
        rc_set_num_scd_in_lap_window(
1449
0
            ps_rc_ctxt->rc_hdl, i4_num_scd_in_lap_window, num_frames_b4_scd);
1450
1451
        /** Pre-enc thread as of now SCD handling is not present */
1452
        //if(!(is_scd_ref_frame || ps_rc_ctxt->i4_is_pause_to_resume) || call_type == PRE_ENC_GET_QP)
1453
0
        {
1454
0
            WORD32 i4_is_first_frame_coded;
1455
            /*Once first frame has been encoded use prev frame intra satd and cur frame satd to alter est intra sad for cur frame*/
1456
0
            i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
1457
0
            {
1458
0
                int i;
1459
0
                WORD32 i4_curr_bits_estimated, i4_is_model_valid;
1460
                /*initialise the coeffs to 1 and 0in case lap is not used */
1461
0
                for(i = 0; i < MAX_PIC_TYPE; i++)
1462
0
                {
1463
0
                    ps_rc_ctxt->af_sum_weigh[0][i][0] = 1.0;
1464
0
                    ps_rc_ctxt->af_sum_weigh[0][i][1] = 0.0;
1465
0
                }
1466
1467
0
                i4_frame_qp_q6 = get_frame_level_qp(
1468
0
                    ps_rc_ctxt->rc_hdl,
1469
0
                    rc_pic_type,
1470
0
                    i4_max_frame_bits,
1471
0
                    &i4_cur_est_texture_bits,  //this value is returned by rc
1472
0
                    ps_rc_ctxt->af_sum_weigh[0],
1473
0
                    0,
1474
0
                    8.0f,
1475
0
                    NULL,
1476
0
                    ps_rc_ctxt->i4_complexity_bin,
1477
0
                    ps_rc_ctxt->i4_scene_num_latest, /*no pause resume concept*/
1478
0
                    &i4_curr_bits_estimated,
1479
0
                    &i4_is_model_valid,
1480
0
                    NULL,
1481
0
                    NULL,
1482
0
                    NULL,
1483
0
                    NULL,
1484
0
                    NULL,
1485
0
                    NULL);
1486
1487
                /** The usage of global table will truncate the input given as qp format and hence will not return very low qp values desirable at very
1488
                low bitrate. Hence on the fly calculation is enabled*/
1489
0
                i4_hevc_frame_qp =
1490
0
                    ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
1491
1492
0
                if(rc_pic_type == I_PIC)
1493
0
                {
1494
                    /*scene cut handling during pre-enc stage*/
1495
0
                    i4_frame_qp = rc_get_bpp_based_scene_cut_qp(
1496
0
                        ps_rc_ctxt->rc_hdl,
1497
0
                        rc_pic_type,
1498
0
                        ((3 * ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 1),
1499
0
                        ps_rc_ctxt->ai4_lap_f_sim[0],
1500
0
                        ps_rc_ctxt->af_sum_weigh[0],
1501
0
                        0);
1502
1503
0
                    *pi4_scd_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(
1504
0
                        i4_frame_qp << QSCALE_Q_FAC_3, ps_rc_ctxt->ps_rc_quant_ctxt);
1505
0
                    *pi4_scd_qp = *pi4_scd_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1506
0
                    if(*pi4_scd_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
1507
0
                        *pi4_scd_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
1508
0
                }
1509
0
                else
1510
0
                {
1511
                    /*scene cut qp is only valid when queried for I_PIC*/
1512
0
                    *pi4_scd_qp = i4_hevc_frame_qp;
1513
0
                }
1514
0
            }
1515
0
        }
1516
1517
0
        ASSERT(i4_hevc_frame_qp >= (-ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset));
1518
1519
        /*constraint qp swing based on neighbour frames*/
1520
0
        if(is_first_frame_coded(ps_rc_ctxt->rc_hdl))
1521
0
        {
1522
0
            if(ps_rc_ctxt->i4_field_pic == 0)
1523
0
            {
1524
0
                if((rc_pic_type != I_PIC && rc_pic_type != P_PIC) &&
1525
0
                   i4_hevc_frame_qp >
1526
0
                       ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1527
0
                                                       [rc_pic_type - 1] +
1528
0
                           3)
1529
0
                {
1530
                    /*allow max of +3 compared to previous frame*/
1531
0
                    i4_hevc_frame_qp =
1532
0
                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1533
0
                                                        [rc_pic_type - 1] +
1534
0
                        3;
1535
0
                }
1536
0
                if((rc_pic_type != I_PIC && rc_pic_type != P_PIC) &&
1537
0
                   i4_hevc_frame_qp <
1538
0
                       (ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1539
0
                                                        [rc_pic_type - 1]))
1540
0
                {
1541
0
                    i4_hevc_frame_qp =
1542
0
                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1543
0
                                                        [rc_pic_type - 1];
1544
0
                }
1545
1546
                /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
1547
0
                if(i4_temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
1548
0
                   ps_rc_ctxt->i4_max_temporal_lyr > 1)
1549
0
                {
1550
0
                    i4_hevc_frame_qp =
1551
0
                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1552
0
                                                        [rc_pic_type - 1] +
1553
0
                        1;
1554
0
                }
1555
0
            }
1556
0
            else /*for field case*/
1557
0
            {
1558
0
                if(i4_temporal_layer_id >= 1)
1559
0
                {
1560
                    /*To make the comparison of qp with the top field's of previous layer tempor layer id matches with the pic type. */
1561
0
                    if(i4_hevc_frame_qp >
1562
0
                       ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1563
0
                                                       [i4_temporal_layer_id] +
1564
0
                           3)
1565
0
                    {
1566
                        /*allow max of +3 compared to previous frame*/
1567
0
                        i4_hevc_frame_qp =
1568
0
                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1569
0
                                                            [i4_temporal_layer_id] +
1570
0
                            3;
1571
0
                    }
1572
0
                    if(i4_hevc_frame_qp <
1573
0
                       ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1574
0
                                                       [i4_temporal_layer_id])
1575
0
                    {
1576
0
                        i4_hevc_frame_qp =
1577
0
                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1578
0
                                                            [i4_temporal_layer_id];
1579
0
                    }
1580
                    /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
1581
0
                    if(i4_temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
1582
0
                       ps_rc_ctxt->i4_max_temporal_lyr > 1)
1583
0
                    {
1584
0
                        i4_hevc_frame_qp =
1585
0
                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[ps_rc_ctxt->i4_scene_num_latest]
1586
0
                                                            [i4_temporal_layer_id] +
1587
0
                            1;
1588
0
                    }
1589
0
                }
1590
0
            }
1591
0
        }
1592
1593
#if USE_USER_FIRST_FRAME_QP
1594
        /*I_PIC check is necessary coz pre-enc can query for qp even before first frame update has happened*/
1595
        if(!ps_rc_ctxt->i4_is_first_frame_encoded && rc_pic_type == I_PIC)
1596
        {
1597
            i4_hevc_frame_qp = ps_rc_ctxt->i4_init_frame_qp_user;
1598
            DBG_PRINTF("FIXED START QP PATH *************************\n");
1599
        }
1600
#endif
1601
        /**clip to min qp which is user configurable*/
1602
0
        i4_hevc_frame_qp =
1603
0
            ihevce_clip_min_max_qp(ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, i4_temporal_layer_id);
1604
1605
0
        return i4_hevc_frame_qp;
1606
0
    }
1607
0
}
1608
/**
1609
******************************************************************************
1610
*
1611
*  @name  ihevce_rc_cal_pre_enc_qp
1612
*
1613
*  @par   Description - Called from enc_loop_init. updates frame qp which will
1614
                        be used by next frame of same pic type in pre-enc stage
1615
*
1616
*  @param[in]   ps_rc_ctxt  - pointer to rc context
1617
*  @return      void
1618
*
1619
******************************************************************************
1620
*/
1621
void ihevce_rc_cal_pre_enc_qp(void *pv_rc_ctxt)
1622
0
{
1623
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
1624
0
    WORD32 i, i4_frame_qp, i4_scd_qp;
1625
0
    WORD32 i4_delay_l0_enc = 0;
1626
1627
0
    i4_delay_l0_enc = ps_rc_ctxt->i4_pre_enc_rc_delay;
1628
1629
0
    if(ps_rc_ctxt->e_rate_control_type != CONST_QP)
1630
0
    {
1631
        //DBG_PRINTF("\ncheck query read = %d write = %d",ps_rc_ctxt->i4_pre_enc_qp_read_index,ps_rc_ctxt->i4_pre_enc_qp_write_index);
1632
0
#if DETERMINISTIC_RC
1633
0
        ASSERT(
1634
0
            ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].i4_is_qp_valid ==
1635
0
            -1);
1636
0
#endif
1637
0
        for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
1638
0
        {
1639
0
            i4_frame_qp =
1640
0
                ihevce_rc_get_pre_enc_pic_quant(ps_rc_ctxt, (picture_type_e)i, &i4_scd_qp);
1641
1642
0
            ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].ai4_quant[i] =
1643
0
                i4_frame_qp;
1644
            /*returns valid scene cut qp only when queried as I_PIC*/
1645
0
            if(i == 0)
1646
0
            {
1647
0
                ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].i4_scd_qp =
1648
0
                    i4_scd_qp;
1649
0
            }
1650
1651
0
            if(ps_rc_ctxt->i4_field_pic && i > 0)
1652
0
            {
1653
0
                i4_frame_qp = ihevce_rc_get_pre_enc_pic_quant(
1654
0
                    ps_rc_ctxt, (picture_type_e)(i + FIELD_OFFSET), &i4_scd_qp);
1655
1656
0
                ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index]
1657
0
                    .ai4_quant[i + FIELD_OFFSET] = i4_frame_qp;
1658
0
            }
1659
0
        }
1660
        /*mark index as populated*/
1661
0
        ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_write_index].i4_is_qp_valid = 1;
1662
1663
0
        ps_rc_ctxt->i4_pre_enc_qp_write_index =
1664
0
            (ps_rc_ctxt->i4_pre_enc_qp_write_index + 1) % i4_delay_l0_enc;
1665
0
    }
1666
0
}
1667
/**
1668
******************************************************************************
1669
*
1670
*  @brief function to get updated qp after L1 analysis for L0. '
1671
*           This uses estimated L0 satd based on L1 satd/act
1672
*
1673
*  @par   Description
1674
*
1675
*  @param[in]   pv_rc_ctxt
1676
*               void pointer to rc ctxt
1677
*  @param[in]   rc_lap_out_params_t *
1678
pointer to lap out structure
1679
*   @param[in]  i8_est_L0_satd_act
1680
*               estimated L0 satd/act based on L1 satd/act
1681
*  @return      void
1682
*
1683
******************************************************************************
1684
*/
1685
WORD32 ihevce_get_L0_est_satd_based_scd_qp(
1686
    void *pv_rc_ctxt,
1687
    rc_lap_out_params_t *ps_rc_lap_out,
1688
    LWORD64 i8_est_L0_satd_act,
1689
    float i_to_avg_rest_ratio)
1690
0
{
1691
0
    rc_context_t *ps_ctxt = (rc_context_t *)pv_rc_ctxt;
1692
0
    WORD32 i4_frame_qs_q3, i4_hevc_qp, i4_est_header_bits, index, i, i4_total_bits;
1693
0
    picture_type_e rc_pic_type;
1694
1695
0
    rc_pic_type = ihevce_rc_conv_pic_type(
1696
0
        (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
1697
0
        ps_ctxt->i4_field_pic,
1698
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
1699
0
        ps_rc_lap_out->i4_is_bottom_field,
1700
0
        ps_ctxt->i4_top_field_first);
1701
1702
    /*initialise the coeffs to 1 in case lap is not used */
1703
1704
0
    for(i = 0; i < MAX_PIC_TYPE; i++)
1705
0
    {
1706
0
        ps_ctxt->af_sum_weigh[0][i][0] = 1.0;
1707
0
        ps_ctxt->af_sum_weigh[0][i][1] = 0.0;
1708
0
    }
1709
1710
    /*get bits to find estimate of header bits*/
1711
0
    i4_est_header_bits = rc_get_scene_change_est_header_bits(
1712
0
        ps_ctxt->rc_hdl,
1713
0
        ps_rc_lap_out->i4_num_pels_in_frame_considered,
1714
0
        ps_ctxt->ai4_lap_f_sim[0],
1715
0
        ps_ctxt->af_sum_weigh[0],
1716
0
        i_to_avg_rest_ratio);
1717
1718
0
    index = ihevce_get_offline_index(ps_ctxt, ps_rc_lap_out->i4_num_pels_in_frame_considered);
1719
0
    {
1720
0
        WORD32 i4_true_scd = 0;
1721
0
        WORD32 i4_curr_bits_estimated;
1722
1723
0
        i4_frame_qs_q3 = rc_get_qp_for_scd_frame(
1724
0
            ps_ctxt->rc_hdl,
1725
0
            I_PIC,
1726
0
            i8_est_L0_satd_act,
1727
0
            ps_rc_lap_out->i4_num_pels_in_frame_considered,
1728
0
            i4_est_header_bits,
1729
0
            ps_ctxt->ai4_lap_f_sim[0],
1730
0
            (void *)&g_offline_i_model_coeff[index][0],
1731
0
            i_to_avg_rest_ratio,
1732
0
            i4_true_scd,
1733
0
            ps_ctxt->af_sum_weigh[0],
1734
0
            ps_rc_lap_out->ps_frame_info,
1735
0
            ps_ctxt->i4_rc_pass,
1736
0
            0,
1737
0
            0,
1738
0
            0,
1739
0
            &i4_total_bits,
1740
0
            &i4_curr_bits_estimated,
1741
0
            ps_rc_lap_out->i4_use_offline_model_2pass,
1742
0
            0,
1743
0
            0,
1744
0
            -1,
1745
0
            NULL);
1746
0
    }
1747
0
    i4_hevc_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(i4_frame_qs_q3, ps_ctxt->ps_rc_quant_ctxt);
1748
0
    i4_hevc_qp = i4_hevc_qp + ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
1749
1750
0
    if(i4_hevc_qp > ps_ctxt->ps_rc_quant_ctxt->i2_max_qp)
1751
0
        i4_hevc_qp = ps_ctxt->ps_rc_quant_ctxt->i2_max_qp;
1752
1753
0
    if(i4_hevc_qp < (SCD_MIN_HEVC_QP -
1754
0
                     ps_ctxt->ps_rc_quant_ctxt
1755
0
                         ->i1_qp_offset))  // since outside RC the QP range is -12 to 51 for 10 bit
1756
0
    {
1757
0
        i4_hevc_qp = (SCD_MIN_HEVC_QP - ps_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
1758
0
    }
1759
0
    else if(i4_hevc_qp > SCD_MAX_HEVC_QP)
1760
0
    {
1761
0
        i4_hevc_qp = SCD_MAX_HEVC_QP;
1762
0
    }
1763
    /*this is done outside loop*/
1764
1765
0
    return i4_hevc_qp;
1766
0
}
1767
/**
1768
******************************************************************************
1769
*
1770
*  @name  ihevce_rc_pre_enc_qp_query
1771
*
1772
*  @par   Description - Called from pre enc thrd for getting the qp of non scd
1773
                        frames. updates frame qp from reverse queue from enc loop
1774
                        when its available
1775
*
1776
*  @param[in]   ps_rc_ctxt  - pointer to rc context
1777
*  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
1778
*               All decision should consider this delay for updation!
1779
*
1780
*  @return      void
1781
*
1782
******************************************************************************
1783
*/
1784
1785
WORD32 ihevce_rc_pre_enc_qp_query(
1786
    void *pv_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out, WORD32 i4_update_delay)
1787
0
{
1788
0
    WORD32 scene_type, i4_is_scd = 0, i4_frame_qp, slice_type;
1789
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
1790
0
    rc_type_e e_rc_type = ps_rc_ctxt->e_rate_control_type;
1791
0
    IV_PICTURE_CODING_TYPE_T pic_type = (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type;
1792
0
    picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
1793
0
        (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
1794
0
        ps_rc_ctxt->i4_field_pic,
1795
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
1796
0
        ps_rc_lap_out->i4_is_bottom_field,
1797
0
        ps_rc_ctxt->i4_top_field_first);
1798
0
    WORD32 i4_use_offset_flag = 0, k = 0;
1799
0
    WORD32 i4_inter_frame_interval = rc_get_inter_frame_interval(ps_rc_ctxt->rc_hdl);
1800
0
    WORD32 ai4_offsets[5] = { 0, 1, 2, 3, 4 };
1801
0
    rc_lap_out_params_t *ps_rc_lap_out_temp = ps_rc_lap_out;
1802
1803
    /* The window for which your update is guaranteed */
1804
0
    WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
1805
1806
0
    k = 0;
1807
0
    if((updated_window >= i4_inter_frame_interval) && (ps_rc_ctxt->i4_rc_pass != 2) &&
1808
0
       ((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC)))
1809
0
    {
1810
0
        WORD32 i4_count = 0;
1811
1812
0
        for(i4_count = 0; i4_count < updated_window; i4_count++)
1813
0
        {
1814
0
            picture_type_e rc_pic_type_temp = ihevce_rc_conv_pic_type(
1815
0
                (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out_temp->i4_rc_pic_type,
1816
0
                ps_rc_ctxt->i4_field_pic,
1817
0
                ps_rc_lap_out_temp->i4_rc_temporal_lyr_id,
1818
0
                ps_rc_lap_out_temp->i4_is_bottom_field,
1819
0
                ps_rc_ctxt->i4_top_field_first);
1820
1821
0
            if((rc_pic_type_temp == I_PIC) || (rc_pic_type_temp == P_PIC))
1822
0
                ihevce_compute_temporal_complexity_reset_Kp_Kb(ps_rc_lap_out_temp, pv_rc_ctxt, 0);
1823
1824
0
            ps_rc_lap_out_temp =
1825
0
                (rc_lap_out_params_t *)ps_rc_lap_out_temp->ps_rc_lap_out_next_encode;
1826
1827
0
            if(ps_rc_lap_out_temp == NULL)
1828
0
                break;
1829
0
        }
1830
0
    }
1831
1832
0
    if(updated_window >= i4_inter_frame_interval)
1833
0
    {
1834
0
        i4_use_offset_flag = 1;
1835
0
        memmove(ai4_offsets, ps_rc_lap_out->ai4_offsets, sizeof(WORD32) * 5);
1836
0
    }
1837
1838
0
    if(CONST_QP == e_rc_type)
1839
0
    {
1840
0
        switch(pic_type)
1841
0
        {
1842
0
        case IV_I_FRAME:
1843
0
        case IV_IDR_FRAME:
1844
0
        {
1845
0
            slice_type = ISLICE;
1846
0
            break;
1847
0
        }
1848
0
        case IV_P_FRAME:
1849
0
        {
1850
0
            slice_type = PSLICE;
1851
0
            break;
1852
0
        }
1853
0
        case IV_B_FRAME:
1854
0
        {
1855
0
            slice_type = BSLICE;
1856
0
            break;
1857
0
        }
1858
0
        }
1859
1860
0
        i4_frame_qp = ihevce_get_cur_frame_qp(
1861
0
            ps_rc_ctxt->i4_init_frame_qp_user,
1862
0
            slice_type,
1863
0
            ps_rc_lap_out->i4_rc_temporal_lyr_id,
1864
0
            ps_rc_ctxt->i4_min_frame_qp,
1865
0
            ps_rc_ctxt->i4_max_frame_qp,
1866
0
            ps_rc_ctxt->ps_rc_quant_ctxt);
1867
1868
0
        return i4_frame_qp;
1869
0
    }
1870
0
    else
1871
0
    {
1872
        /*check scene type*/
1873
0
        scene_type = ihevce_rc_lap_get_scene_type(ps_rc_lap_out);
1874
1875
0
        if(scene_type == SCENE_TYPE_SCENE_CUT)
1876
0
        {
1877
0
            i4_is_scd = 1;
1878
0
            ps_rc_ctxt->i4_num_frms_from_reset = 0;
1879
0
#if USE_QP_OFFSET_POST_SCD
1880
0
            ps_rc_ctxt->i4_use_qp_offset_pre_enc = 1;
1881
#else
1882
            ps_rc_ctxt->i4_use_qp_offset_pre_enc = 0;
1883
#endif
1884
0
        }
1885
0
        ASSERT(
1886
0
            ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid ==
1887
0
                1 ||
1888
0
            ps_rc_lap_out->i4_rc_poc < 20);
1889
1890
0
        if(ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid ==
1891
0
           1)
1892
0
        {
1893
0
            if(i4_is_scd || ps_rc_ctxt->i4_use_qp_offset_pre_enc)
1894
0
            {
1895
0
#if 1  //The qp will be populated assuming the frame is I_PIC. Adjust according to current pic type
1896
0
                i4_frame_qp =
1897
0
                    ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_scd_qp;
1898
0
                if(rc_pic_type == P_PIC)
1899
0
                    i4_frame_qp++;
1900
0
                else
1901
0
                    i4_frame_qp = i4_frame_qp + ps_rc_lap_out->i4_rc_temporal_lyr_id;
1902
0
#endif
1903
0
                if(i4_use_offset_flag)
1904
0
                {
1905
0
                    if(rc_pic_type > B2_PIC)
1906
0
                        i4_frame_qp = ps_rc_ctxt->i4_L0_frame_qp + ai4_offsets[rc_pic_type - 4];
1907
0
                    else
1908
0
                        i4_frame_qp = ps_rc_ctxt->i4_L0_frame_qp + ai4_offsets[rc_pic_type];
1909
0
                }
1910
0
            }
1911
0
            else
1912
0
            {
1913
0
#if DETERMINISTIC_RC
1914
0
                i4_frame_qp = ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index]
1915
0
                                  .ai4_quant[rc_pic_type];
1916
#else
1917
                /*read the latest qp updated by enc*/
1918
                i4_frame_qp =
1919
                    ps_rc_ctxt
1920
                        ->as_pre_enc_qp_queue
1921
                            [(ps_rc_ctxt->i4_pre_enc_qp_write_index + MAX_PRE_ENC_RC_DELAY - 1) %
1922
                             MAX_PRE_ENC_RC_DELAY]
1923
                        .ai4_quant[rc_pic_type];
1924
#endif
1925
0
            }
1926
1927
0
            ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index].i4_is_qp_valid =
1928
0
                -1;
1929
            /*once encoder starts reading from qp queue it should always read from qp queue*/
1930
            //ps_rc_ctxt->i4_use_init_qp_for_pre_enc = 0;
1931
0
        }
1932
0
        else
1933
0
        {
1934
0
            i4_frame_qp = ps_rc_ctxt->ai4_init_pre_enc_qp[rc_pic_type];
1935
0
        }
1936
0
        {
1937
0
            WORD32 i4_delay_l0_enc = ps_rc_ctxt->i4_pre_enc_rc_delay;
1938
0
            ps_rc_ctxt->i4_pre_enc_qp_read_index =
1939
0
                (ps_rc_ctxt->i4_pre_enc_qp_read_index + 1) % i4_delay_l0_enc;
1940
1941
0
            if(ps_rc_ctxt->i4_num_frms_from_reset < i4_delay_l0_enc)
1942
0
            {
1943
0
                ps_rc_ctxt->i4_num_frms_from_reset++;
1944
0
                if(ps_rc_ctxt->i4_num_frms_from_reset >= i4_delay_l0_enc)
1945
0
                    ps_rc_ctxt->i4_use_qp_offset_pre_enc = 0;
1946
0
            }
1947
0
        }
1948
1949
0
        i4_frame_qp = CLIP3(i4_frame_qp, ps_rc_ctxt->i4_min_frame_qp, ps_rc_ctxt->i4_max_frame_qp);
1950
0
        return i4_frame_qp;
1951
0
    }
1952
0
}
1953
/**
1954
******************************************************************************
1955
*
1956
*  @brief function to estimate L0 satd based on L1 satd. '
1957
*
1958
*
1959
*  @par   Description
1960
*
1961
*  @param[in]   pv_rc_ctxt
1962
*               void pointer to rc ctxt
1963
*  @param[in]   rc_lap_out_params_t *
1964
pointer to lap out structure
1965
*   @param[in]  i8_est_L0_satd_act
1966
*               estimated L0 satd/act based on L1 satd/act
1967
*  @return      void
1968
*
1969
******************************************************************************
1970
*/
1971
LWORD64 ihevce_get_L0_satd_based_on_L1(
1972
    LWORD64 i8_satd_by_act_L1, WORD32 i4_num_pixel, WORD32 i4_cur_q_scale)
1973
0
{
1974
0
    LWORD64 est_L0_satd_by_act;
1975
0
    float m, c;
1976
    /** choose coeff based on resolution*/
1977
0
    if(i4_num_pixel > 5184000)
1978
0
    {
1979
0
        m = (float)2.3911;
1980
0
        c = (float)86329;
1981
0
    }
1982
0
    else if(i4_num_pixel > 1497600)
1983
0
    {
1984
0
        m = (float)2.7311;
1985
0
        c = (float)-1218.9;
1986
0
    }
1987
0
    else if(i4_num_pixel > 633600)
1988
0
    {
1989
0
        m = (float)3.1454;
1990
0
        c = (float)-5836.1;
1991
0
    }
1992
0
    else
1993
0
    {
1994
0
        m = (float)3.5311;
1995
0
        c = (float)-2377.2;
1996
0
    }
1997
    /*due to qp difference between I and  P, For P pic for same */
1998
0
    est_L0_satd_by_act = (LWORD64)(i8_satd_by_act_L1 / i4_cur_q_scale * m + c) * i4_cur_q_scale;
1999
2000
0
    {
2001
0
        if(est_L0_satd_by_act < (i4_num_pixel >> 3))
2002
0
            est_L0_satd_by_act = (i4_num_pixel >> 3);
2003
0
    }
2004
0
    return est_L0_satd_by_act;
2005
0
}
2006
/**
2007
******************************************************************************
2008
*
2009
*  @name  ihevce_rc_register_L1_analysis_data
2010
*
2011
*  @par   Description
2012
*
2013
*  @param[in]   ps_rc_ctxt  - pointer to rc context
2014
*               ps_rc_lap_out
2015
*               i8_est_L0_satd_by_act
2016
*               i8_pre_intra_sad
2017
*               i8_l1_hme_sad
2018
*  @return      void
2019
*
2020
******************************************************************************
2021
*/
2022
void ihevce_rc_register_L1_analysis_data(
2023
    void *pv_rc_ctxt,
2024
    rc_lap_out_params_t *ps_rc_lap_out,
2025
    LWORD64 i8_est_L0_satd_by_act,
2026
    LWORD64 i8_pre_intra_sad,
2027
    LWORD64 i8_l1_hme_sad)
2028
0
{
2029
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
2030
0
    WORD32 i, data_available = 1;
2031
0
    picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
2032
0
        (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
2033
0
        ps_rc_ctxt->i4_field_pic,
2034
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
2035
0
        ps_rc_lap_out->i4_is_bottom_field,
2036
0
        ps_rc_ctxt->i4_top_field_first);
2037
2038
    //if( ps_rc_ctxt->u4_rc_scene_num_est_L0_intra_sad_available == ps_rc_lap_out->u4_rc_scene_num)
2039
0
    {
2040
        /*update current frame's data*/
2041
0
        ps_rc_ctxt->ai8_prev_frame_est_L0_satd[rc_pic_type] = i8_est_L0_satd_by_act;
2042
0
        ps_rc_ctxt->ai8_prev_frame_hme_sad[rc_pic_type] = i8_l1_hme_sad;
2043
0
        ps_rc_ctxt->ai8_prev_frame_pre_intra_sad[rc_pic_type] = i8_pre_intra_sad;
2044
0
    }
2045
    /*check if data is available for all picture type*/
2046
0
    if(!ps_rc_ctxt->i4_is_est_L0_intra_sad_available)
2047
0
    {
2048
0
        for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2049
0
        {
2050
0
            data_available &= (ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i] >= 0);
2051
0
            if(ps_rc_ctxt->i4_field_pic == 1 && i != 0)
2052
0
                data_available &= (ps_rc_ctxt->ai8_prev_frame_est_L0_satd[i + FIELD_OFFSET] >= 0);
2053
0
        }
2054
0
        ps_rc_ctxt->i4_is_est_L0_intra_sad_available = data_available;
2055
0
    }
2056
0
}
2057
2058
/*#######################################################*/
2059
/******* END OF PRE-ENC QP QUERY FUNCTIONS **************/
2060
/*#####################################################*/
2061
2062
/*##########################################################*/
2063
/******* START OF ENC THRD QP QUERY FUNCTIONS **************/
2064
/*########################################################*/
2065
2066
/**
2067
******************************************************************************
2068
*
2069
*  @brief function to get ihevce_rc_get_pic_quant
2070
*
2071
*  @par   Description
2072
*  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
2073
*               All decision should consider this delay for updation!
2074
******************************************************************************
2075
*/
2076
2077
WORD32 ihevce_rc_get_pic_quant(
2078
    void *pv_ctxt,
2079
    rc_lap_out_params_t *ps_rc_lap_out,
2080
    IHEVCE_RC_CALL_TYPE call_type,
2081
    WORD32 i4_enc_frm_id,
2082
    WORD32 i4_update_delay,
2083
    WORD32 *pi4_tot_bits_estimated)
2084
0
{
2085
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
2086
0
    WORD32 i4_frame_qp, i4_frame_qp_q6, i4_hevc_frame_qp = -1, i4_deltaQP = 0;
2087
0
    WORD32 i4_max_frame_bits = (1 << 30);
2088
0
    rc_type_e e_rc_type = ps_rc_ctxt->e_rate_control_type;
2089
0
    WORD32 slice_type, index, i4_num_frames_in_cur_gop, i4_cur_est_texture_bits;
2090
0
    WORD32 temporal_layer_id = ps_rc_lap_out->i4_rc_temporal_lyr_id;
2091
0
    IV_PICTURE_CODING_TYPE_T pic_type = (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type;
2092
0
    picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
2093
0
        pic_type,
2094
0
        ps_rc_ctxt->i4_field_pic,
2095
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
2096
0
        ps_rc_lap_out->i4_is_bottom_field,
2097
0
        ps_rc_ctxt->i4_top_field_first);
2098
0
    float i_to_avg_bit_ratio;
2099
0
    frame_info_t s_frame_info_temp;
2100
0
    WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
2101
0
    WORD32 i4_vbv_buf_max_bits;
2102
0
    WORD32 i4_est_tex_bits;
2103
0
    WORD32 i4_cur_est_header_bits, i4_fade_scene;
2104
0
    WORD32 i4_model_available, i4_is_no_model_scd;
2105
0
    WORD32 i4_estimate_to_calc_frm_error;
2106
2107
    /* The window for which your update is guaranteed */
2108
0
    WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
2109
2110
0
    ps_rc_ctxt->i4_scene_num_latest = i4_scene_num;
2111
2112
0
    ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP = INVALID_QP;
2113
0
    ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = INVALID_QP;
2114
0
    ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP = INVALID_QP;
2115
2116
0
    ps_rc_ctxt->i4_quality_preset = ps_rc_lap_out->i4_rc_quality_preset;
2117
0
    ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = INVALID_QP;
2118
2119
0
    if(1 == ps_rc_ctxt->i4_bitrate_changed)
2120
0
    {
2121
0
        ps_rc_ctxt->i4_bitrate_changed = 0;
2122
0
    }
2123
0
    if(CONST_QP == e_rc_type)
2124
0
    {
2125
0
        switch(pic_type)
2126
0
        {
2127
0
        case IV_I_FRAME:
2128
0
        case IV_IDR_FRAME:
2129
0
        {
2130
0
            slice_type = ISLICE;
2131
0
            break;
2132
0
        }
2133
0
        case IV_P_FRAME:
2134
0
        {
2135
0
            slice_type = PSLICE;
2136
0
            break;
2137
0
        }
2138
0
        case IV_B_FRAME:
2139
0
        {
2140
0
            slice_type = BSLICE;
2141
0
            break;
2142
0
        }
2143
0
        }
2144
2145
0
        i4_frame_qp = ihevce_get_cur_frame_qp(
2146
0
            ps_rc_ctxt->i4_init_frame_qp_user,
2147
0
            slice_type,
2148
0
            temporal_layer_id,
2149
0
            ps_rc_ctxt->i4_min_frame_qp,
2150
0
            ps_rc_ctxt->i4_max_frame_qp,
2151
0
            ps_rc_ctxt->ps_rc_quant_ctxt);
2152
0
        return i4_frame_qp;
2153
0
    }
2154
0
    else
2155
0
    {
2156
0
        WORD32 is_scd_ref_frame = 0, i4_num_scd_in_lap_window = 0, num_frames_b4_scd = 0,
2157
0
               scene_type = 0, i;
2158
        //ihevce_lap_output_params_t *ps_cur_rc_lap_out;
2159
2160
0
        if(ps_rc_ctxt->ai4_scene_num_last_pic[rc_pic_type] !=
2161
0
           (WORD32)ps_rc_lap_out->u4_rc_scene_num)
2162
0
        {
2163
0
            rc_reset_pic_model(ps_rc_ctxt->rc_hdl, rc_pic_type);
2164
0
            rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, rc_pic_type);
2165
0
        }
2166
0
        ps_rc_ctxt->ai4_scene_num_last_pic[rc_pic_type] = ps_rc_lap_out->u4_rc_scene_num;
2167
2168
0
        if(call_type == ENC_GET_QP)
2169
0
        {
2170
0
            i4_model_available = model_availability(ps_rc_ctxt->rc_hdl, rc_pic_type);
2171
2172
0
            ps_rc_lap_out->i8_est_text_bits = -1;
2173
0
        }
2174
2175
0
        if((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC) || (rc_pic_type == P1_PIC))
2176
0
        {
2177
0
            ps_rc_ctxt->i4_cur_scene_num = ps_rc_lap_out->u4_rc_scene_num;
2178
0
        }
2179
2180
0
        {
2181
0
            if(!(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME))
2182
0
            {
2183
0
                ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id] =
2184
0
                    ps_rc_lap_out->i8_frame_acc_coarse_me_cost;
2185
0
            }
2186
            /*check if frame is scene cut*/
2187
            /* If scd do not query the model. obtain qp from offline data model*/
2188
0
            scene_type = ihevce_rc_lap_get_scene_type(ps_rc_lap_out);
2189
2190
0
            if(ps_rc_ctxt->ai4_scene_numbers[ps_rc_lap_out->u4_rc_scene_num] == 0 &&
2191
0
               (scene_type != SCENE_TYPE_SCENE_CUT))
2192
0
            {
2193
0
                scene_type = SCENE_TYPE_SCENE_CUT;
2194
0
            }
2195
2196
0
            if(ps_rc_ctxt->ai4_scene_numbers[ps_rc_lap_out->u4_rc_scene_num] > 0 &&
2197
0
               (scene_type == SCENE_TYPE_SCENE_CUT))
2198
0
            {
2199
0
                scene_type = SCENE_TYPE_NORMAL;
2200
0
            }
2201
0
            if(scene_type == SCENE_TYPE_SCENE_CUT)
2202
0
            {
2203
0
                if((ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6) &&
2204
0
                   (rc_pic_type > P_PIC))
2205
0
                {
2206
0
                    is_scd_ref_frame = 0;
2207
0
                }
2208
0
                else
2209
0
                {
2210
0
                    is_scd_ref_frame = 1;
2211
0
                }
2212
0
            }
2213
0
            else if(scene_type == SCENE_TYPE_PAUSE_TO_RESUME)
2214
0
            {
2215
                /*pause to resume flag will only be set in layer 0 frames( I and P pic)*/
2216
                /*I PIC can handle this by detecting I_only SCD which is based on open loop SATD hence explicit handling for pause to resume is required only for P_PIC*/
2217
2218
0
                if(ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)
2219
0
                {
2220
0
                    if(call_type == ENC_GET_QP && rc_pic_type == P_PIC)
2221
0
                    {
2222
0
                        ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 1;
2223
0
                    }
2224
0
                }
2225
0
                else
2226
0
                {
2227
0
                    if(call_type == ENC_GET_QP && rc_pic_type != I_PIC)
2228
0
                    {
2229
0
                        ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 1;
2230
0
                    }
2231
0
                }
2232
0
            }
2233
2234
0
            ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] =
2235
0
                ps_rc_lap_out->i4_is_cmplx_change_reset_model;
2236
0
            ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id] =
2237
0
                ps_rc_lap_out->i4_is_cmplx_change_reset_bits;
2238
2239
            /*initialise the coeffs to 1 in case lap is not used */
2240
0
            for(i = 0; i < MAX_PIC_TYPE; i++)
2241
0
            {
2242
0
                ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][0] = 1.0;
2243
0
                ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][1] = 0.0;
2244
0
                ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][2] = 0.0;
2245
0
            }
2246
2247
            /*treat even first frame as scd frame*/
2248
0
            if(!ps_rc_ctxt->i4_is_first_frame_encoded)
2249
0
            {
2250
0
                is_scd_ref_frame = 1;
2251
0
            }
2252
2253
            /*special case SCD handling for Non-I pic*/
2254
0
            if(!(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) && call_type == ENC_GET_QP)
2255
0
            {
2256
0
                if(is_scd_ref_frame)
2257
0
                {
2258
                    /*A non-I pic will only be marked as scene cut only if there is another SCD follows within another subgop*/
2259
0
                    ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 1;
2260
0
                }
2261
                /*check if current sad is very different from previous SAD and */
2262
0
                else if(
2263
0
                    !ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] &&
2264
0
                    ps_rc_lap_out->i4_is_non_I_scd)
2265
0
                {
2266
0
                    ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 1;
2267
0
                    is_scd_ref_frame = 1;
2268
0
                }
2269
0
            }
2270
2271
0
            if(call_type == PRE_ENC_GET_QP)
2272
0
            {
2273
                /*Only I frames are considered as scd pic during pre-enc*/
2274
0
                is_scd_ref_frame &= (pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME);
2275
0
            }
2276
2277
            /*special case SCD handling for I pic*/
2278
0
            if((pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) && !is_scd_ref_frame)
2279
0
            {
2280
                /*If open loop SATD's of two I picture are very different then treat the I pic as SCD and reset only model as this can
2281
                happen during fade-in and fade-out where other picture types would have learnt. Reset is required only for I.*/
2282
2283
0
                if(ps_rc_lap_out->i4_is_I_only_scd)
2284
0
                {
2285
0
                    is_scd_ref_frame = 1;
2286
0
                    ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 1;
2287
0
                }
2288
0
            }
2289
            /*should be recalculated for every picture*/
2290
0
            if((updated_window) > 0 && (call_type == ENC_GET_QP) && (ps_rc_ctxt->i4_rc_pass != 2))
2291
0
            {
2292
0
                rc_lap_out_params_t *ps_cur_rc_lap_out;
2293
2294
0
                UWORD32 u4_L1_based_lap_complexity_q7;
2295
0
                WORD32 i = 0, k = 0, i4_f_sim = 0, i4_h_sim = 0, i4_var_sum = 0,
2296
0
                       i4_num_pic_metric_count = 0, i4_is_first_frm = 1,
2297
0
                       i4_intra_frame_interval = 0;
2298
0
                LWORD64 i8_l1_analysis_lap_comp = 0;
2299
0
                LWORD64 nor_frm_hme_sad_q10;
2300
0
                picture_type_e curr_rc_pic_type;
2301
0
                WORD32 ai4_pic_dist[MAX_PIC_TYPE] = { 0 };
2302
0
                LWORD64 i8_sad_first_frame_pic_type[MAX_PIC_TYPE] = { 0 },
2303
0
                        i8_total_sad_pic_type[MAX_PIC_TYPE] = { 0 };
2304
0
                LWORD64 i8_last_frame_pic_type[MAX_PIC_TYPE] = { 0 }, i8_esti_consum_bits = 0;
2305
0
                WORD32 i4_num_pic_type[MAX_PIC_TYPE] = { 0 }, i4_frames_in_lap_end = 0,
2306
0
                       i4_first_frame_coded_flag, i4_gop_end_flag = 1, i4_num_frame_for_ebf = 0;
2307
0
                i4_first_frame_coded_flag = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2308
2309
                /*Setting the next scene cut as well as pic distribution for the gop*/
2310
2311
0
                ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_rc_lap_out;
2312
0
                i4_intra_frame_interval = rc_get_intra_frame_interval(ps_rc_ctxt->rc_hdl);
2313
2314
                /*Set the rc sc i next*/
2315
0
                if(ps_cur_rc_lap_out != NULL)
2316
0
                {
2317
0
                    WORD32 i4_count = 0;
2318
0
                    do
2319
0
                    {
2320
0
                        if(((rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode ==
2321
0
                            NULL))  //||((( (ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_pre_intra_sad == -1) || (  ((ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_raw_pre_intra_sad == -1) ||(  ((ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_raw_l1_coarse_me_sad == -1) ||(((ihevce_lap_output_params_t*)ps_cur_rc_lap_out->ps_lap_out_next)->i8_frame_acc_coarse_me_sad == -1)))
2322
0
                            break;
2323
2324
0
                        ps_cur_rc_lap_out =
2325
0
                            (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2326
0
                        i4_count++;
2327
2328
0
                    } while((i4_count + 1) < updated_window);
2329
2330
0
                    rc_set_next_sc_i_in_rc_look_ahead(
2331
0
                        ps_rc_ctxt->rc_hdl, ps_cur_rc_lap_out->i4_next_sc_i_in_rc_look_ahead);
2332
0
                    rc_update_pic_distn_lap_to_rc(
2333
0
                        ps_rc_ctxt->rc_hdl, ps_cur_rc_lap_out->ai4_num_pic_type);
2334
2335
0
                    ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead =
2336
0
                        ps_cur_rc_lap_out->i4_next_sc_i_in_rc_look_ahead;
2337
0
                }
2338
2339
0
                ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_rc_lap_out;
2340
0
                if(ps_cur_rc_lap_out != NULL)
2341
0
                {
2342
                    /*initialise the coeffs to 1 in case lap is not used */
2343
0
                    for(i = 0; i < MAX_PIC_TYPE; i++)
2344
0
                    {
2345
0
                        ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][0] = 0.0;
2346
0
                        ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][1] = 0.0;
2347
0
                        ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][i][2] = 0.0;
2348
0
                    }
2349
0
                    i = 0;
2350
0
                    k = 0;
2351
2352
                    //ASSERT(ps_cur_rc_lap_out != NULL);
2353
0
                    do
2354
0
                    {
2355
0
                        curr_rc_pic_type = ihevce_rc_conv_pic_type(
2356
0
                            (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out->i4_rc_pic_type,
2357
0
                            ps_rc_ctxt->i4_field_pic,
2358
0
                            ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
2359
0
                            ps_cur_rc_lap_out->i4_is_bottom_field,
2360
0
                            ps_rc_ctxt->i4_top_field_first);
2361
0
                        if(ps_rc_ctxt->i4_is_first_frame_encoded || !i4_is_first_frm)
2362
0
                        {
2363
                            /*Ignore first frame Fsim as it is not valid for first frame*/
2364
0
                            i4_f_sim += ps_cur_rc_lap_out->s_pic_metrics.i4_fsim;
2365
0
                            i4_h_sim += ps_cur_rc_lap_out->s_pic_metrics.ai4_hsim[0];
2366
0
                            i4_var_sum += (WORD32)ps_cur_rc_lap_out->s_pic_metrics.i8_8x8_var_lum;
2367
0
                            i4_num_pic_metric_count++;
2368
                            //DBG_PRINTF("\n fsim = %d i = %d",ps_cur_rc_lap_out->s_pic_metrics.i4_fsim,i);
2369
                            //ASSERT(ps_cur_rc_lap_out->s_pic_metrics.i4_fsim <= 128);
2370
0
                        }
2371
2372
                        /*accumulate complexity from LAP2*/
2373
0
                        if(curr_rc_pic_type == I_PIC)
2374
0
                        {
2375
0
                            i8_l1_analysis_lap_comp +=
2376
0
                                (LWORD64)(1.17 * ps_cur_rc_lap_out->i8_raw_pre_intra_sad);
2377
0
                        }
2378
0
                        else
2379
0
                        {
2380
0
                            if(curr_rc_pic_type <= B2_PIC)
2381
0
                                i8_l1_analysis_lap_comp += (LWORD64)(
2382
0
                                    (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
2383
0
                                    pow(1.125f, curr_rc_pic_type));
2384
0
                            else
2385
0
                                i8_l1_analysis_lap_comp += (LWORD64)(
2386
0
                                    (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
2387
0
                                    pow(1.125f, curr_rc_pic_type - B2_PIC));
2388
0
                        }
2389
0
                        i++;
2390
0
                        i4_is_first_frm = 0;
2391
2392
                        /*CAll the function for predictting the ebf and stuffing condition check*/
2393
                        /*rd model pass lapout l1 pass ebf return estimated ebf and signal*/
2394
2395
0
                        {
2396
0
                            if(i4_first_frame_coded_flag && (i4_gop_end_flag != 0))
2397
0
                            {
2398
0
                                if(curr_rc_pic_type == 0)
2399
0
                                    i4_gop_end_flag = 0;
2400
2401
0
                                if(i4_gop_end_flag)
2402
0
                                {
2403
0
                                    WORD32 prev_frm_cl_sad =
2404
0
                                        rc_get_prev_frame_sad(ps_rc_ctxt->rc_hdl, curr_rc_pic_type);
2405
0
                                    WORD32 cur_frm_est_cl_sad = (WORD32)(
2406
0
                                        (ps_cur_rc_lap_out->i8_frame_acc_coarse_me_cost *
2407
0
                                         prev_frm_cl_sad) /
2408
0
                                        ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[curr_rc_pic_type]);
2409
0
                                    i8_esti_consum_bits += bit_alloc_get_estimated_bits_for_pic(
2410
0
                                        ps_rc_ctxt->rc_hdl,
2411
0
                                        cur_frm_est_cl_sad,
2412
0
                                        prev_frm_cl_sad,
2413
0
                                        curr_rc_pic_type);
2414
0
                                    i4_num_frame_for_ebf++;
2415
0
                                }
2416
0
                            }
2417
0
                        }
2418
0
                        ps_cur_rc_lap_out =
2419
0
                            (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2420
                        /*The scene cut is lap window other than current frame is used to reduce bit alloc window for I pic*/
2421
0
                        if(ps_cur_rc_lap_out != NULL &&
2422
0
                           ps_cur_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
2423
0
                        {
2424
0
                            i4_num_scd_in_lap_window++;
2425
0
                            if(i4_num_scd_in_lap_window == 1)
2426
0
                            {
2427
                                /*Note how many frames are parsed before first scd is hit*/
2428
0
                                num_frames_b4_scd = i + 1;
2429
0
                            }
2430
0
                        }
2431
2432
0
                        if((ps_cur_rc_lap_out == NULL ||
2433
0
                            (i >=
2434
0
                             (updated_window -
2435
0
                              k))))  //||((( -1 == ps_cur_rc_lap_out->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out->i8_frame_acc_coarse_me_sad))))
2436
0
                            break;
2437
0
                        if(0)  //(( -1 == ps_cur_rc_lap_out->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out->i8_frame_acc_coarse_me_sad)))
2438
0
                        {
2439
0
                            k++;
2440
0
                            ps_cur_rc_lap_out =
2441
0
                                (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
2442
0
                            if(ps_cur_rc_lap_out == NULL)
2443
0
                                break;
2444
0
                            continue;
2445
0
                        }
2446
2447
0
                    } while(1);
2448
0
                    ;
2449
0
                }
2450
                /*For the first subgop we cant have underflow prevention logic
2451
                since once picture of each type is not encoded also happens for static contents thants high i_to avg_ratio */
2452
0
                if(i4_first_frame_coded_flag &&
2453
0
                   (ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] > I_TO_REST_SLOW))
2454
0
                {
2455
0
                    if(!(i4_num_frame_for_ebf < ps_rc_ctxt->i4_max_inter_frm_int))
2456
0
                        rc_bit_alloc_detect_ebf_stuff_scenario(
2457
0
                            ps_rc_ctxt->rc_hdl,
2458
0
                            i4_num_frame_for_ebf,
2459
0
                            i8_esti_consum_bits,
2460
0
                            ps_rc_ctxt->i4_max_inter_frm_int);
2461
0
                }
2462
2463
0
                k = 0;
2464
2465
0
                i4_frames_in_lap_end = 0;
2466
0
                {
2467
0
                    rc_lap_out_params_t *ps_cur_rc_lap_out1;
2468
2469
0
                    ps_cur_rc_lap_out1 = (rc_lap_out_params_t *)ps_rc_lap_out;
2470
0
                    do
2471
0
                    {
2472
0
                        curr_rc_pic_type = ihevce_rc_conv_pic_type(
2473
0
                            (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out1->i4_rc_pic_type,
2474
0
                            ps_rc_ctxt->i4_field_pic,
2475
0
                            ps_cur_rc_lap_out1->i4_rc_temporal_lyr_id,
2476
0
                            ps_cur_rc_lap_out1->i4_is_bottom_field,
2477
0
                            ps_rc_ctxt->i4_top_field_first);
2478
                        /*accumulate complexity from LAP2*/
2479
2480
0
                        if(curr_rc_pic_type == I_PIC)
2481
0
                        {
2482
0
                            i8_total_sad_pic_type[I_PIC] +=
2483
0
                                ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2484
0
                            i8_last_frame_pic_type[I_PIC] =
2485
0
                                ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2486
0
                        }
2487
0
                        else
2488
0
                        {
2489
0
                            i8_total_sad_pic_type[curr_rc_pic_type] +=
2490
0
                                ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2491
0
                            i8_last_frame_pic_type[curr_rc_pic_type] =
2492
0
                                ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2493
0
                        }
2494
0
                        if(i4_num_pic_type[curr_rc_pic_type] == 0)
2495
0
                        {
2496
0
                            if(curr_rc_pic_type == I_PIC)
2497
0
                            {
2498
0
                                i8_sad_first_frame_pic_type[I_PIC] =
2499
0
                                    ps_cur_rc_lap_out1->i8_raw_pre_intra_sad;
2500
0
                            }
2501
0
                            else
2502
0
                            {
2503
0
                                i8_sad_first_frame_pic_type[curr_rc_pic_type] =
2504
0
                                    ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad;
2505
0
                            }
2506
0
                        }
2507
0
                        i4_num_pic_type[curr_rc_pic_type]++;
2508
2509
0
                        i4_frames_in_lap_end++;
2510
2511
0
                        ps_cur_rc_lap_out1 =
2512
0
                            (rc_lap_out_params_t *)ps_cur_rc_lap_out1->ps_rc_lap_out_next_encode;
2513
0
                        if((ps_cur_rc_lap_out1 == NULL ||
2514
0
                            (i4_frames_in_lap_end >=
2515
0
                             (updated_window -
2516
0
                              k))))  //||((( -1 == ps_cur_rc_lap_out1->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out1->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out1->i8_frame_acc_coarse_me_sad))))
2517
0
                        {
2518
0
                            break;
2519
0
                        }
2520
0
                        if(0)  //((( -1 == ps_cur_rc_lap_out1->i8_pre_intra_sad ) || ( -1 == ps_cur_rc_lap_out1->i8_raw_pre_intra_sad ) ||( -1 == ps_cur_rc_lap_out1->i8_raw_l1_coarse_me_sad) ||(-1 == ps_cur_rc_lap_out1->i8_frame_acc_coarse_me_sad))))
2521
0
                        {
2522
0
                            k++;
2523
0
                            ps_cur_rc_lap_out1 = (rc_lap_out_params_t *)
2524
0
                                                     ps_cur_rc_lap_out1->ps_rc_lap_out_next_encode;
2525
0
                            if(ps_cur_rc_lap_out1 == NULL)
2526
0
                                break;
2527
0
                            continue;
2528
0
                        }
2529
2530
0
                    } while(i4_frames_in_lap_end < (ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead - k));
2531
0
                }
2532
2533
                /*get picture type distribution in LAP*/
2534
0
                rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
2535
2536
0
                {
2537
0
                    float f_prev_comp;
2538
0
                    WORD32 j;
2539
0
                    float af_sum_weigh[MAX_PIC_TYPE], af_nume_weight[MAX_PIC_TYPE];
2540
0
                    float af_average_sad_pic_type[MAX_PIC_TYPE] = { 0 };
2541
0
                    for(j = 0; j < MAX_PIC_TYPE; j++)
2542
0
                    {
2543
0
                        if(i4_num_pic_type[j] > 0)
2544
0
                        {
2545
0
                            af_average_sad_pic_type[j] =
2546
0
                                (float)i8_total_sad_pic_type[j] / i4_num_pic_type[j];
2547
0
                        }
2548
2549
0
                        f_prev_comp = 1.;
2550
2551
0
                        i4_num_pic_type[j] = (i4_num_pic_type[j] > ai4_pic_dist[j])
2552
0
                                                 ? ai4_pic_dist[j]
2553
0
                                                 : i4_num_pic_type[j];
2554
2555
0
                        af_sum_weigh[j] = (float)i4_num_pic_type[j];
2556
0
                        af_nume_weight[j] = 1.0;
2557
2558
0
                        if(i4_num_pic_type[j] > 1 && (af_average_sad_pic_type[j] > 0))
2559
0
                        {
2560
0
                            af_nume_weight[j] =
2561
0
                                (float)i8_sad_first_frame_pic_type[j] / af_average_sad_pic_type[j];
2562
2563
0
                            f_prev_comp =
2564
0
                                (float)i8_last_frame_pic_type[j] / af_average_sad_pic_type[j];
2565
0
                        }
2566
                        //if(rc_pic_type != I_PIC)
2567
0
                        {
2568
0
                            af_sum_weigh[j] += f_prev_comp * (ai4_pic_dist[j] - i4_num_pic_type[j]);
2569
0
                        }
2570
0
                        ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][0] = af_nume_weight[j];
2571
0
                        ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][1] = af_sum_weigh[j];
2572
0
                        ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][2] = af_average_sad_pic_type[j];
2573
2574
                        /*Disabling steady state complexity based bit movement*/
2575
                        /*Enable it in CBR and not in VBR since VBR already has complexity based bit movement*/
2576
2577
0
                        if(0) /*i4_frames_in_lap_end < (updated_window) || ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)*/
2578
0
                        {
2579
0
                            ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][0] = 1.0;
2580
0
                            ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id][j][1] =
2581
0
                                0;  //(float)ai4_pic_dist[j];
2582
0
                        }
2583
0
                    }
2584
0
                    memmove(
2585
0
                        ps_rc_lap_out->ps_frame_info->af_sum_weigh,
2586
0
                        ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2587
0
                        sizeof(float) * MAX_PIC_TYPE * 3);
2588
0
                }
2589
2590
0
                if(i4_num_pic_metric_count > 0)
2591
0
                {
2592
0
                    i4_f_sim = i4_f_sim / i4_num_pic_metric_count;
2593
0
                    i4_h_sim = i4_h_sim / i4_num_pic_metric_count;
2594
0
                    i4_var_sum = i4_var_sum / i4_num_pic_metric_count;
2595
0
                }
2596
0
                else
2597
0
                {
2598
0
                    i4_f_sim = MODERATE_FSIM_VALUE;
2599
0
                    i4_h_sim = MODERATE_FSIM_VALUE;
2600
0
                }
2601
2602
0
                if(i > 0)
2603
0
                {
2604
0
                    float lap_L1_comp =
2605
0
                        (float)i8_l1_analysis_lap_comp /
2606
0
                        (i * ps_rc_ctxt->i4_frame_height *
2607
0
                         ps_rc_ctxt->i4_frame_width);  //per frame per pixel complexity
2608
2609
0
                    lap_L1_comp = rc_get_offline_normalized_complexity(
2610
0
                        ps_rc_ctxt->u4_intra_frame_interval,
2611
0
                        ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width,
2612
0
                        lap_L1_comp,
2613
0
                        ps_rc_ctxt->i4_rc_pass);
2614
2615
0
                    u4_L1_based_lap_complexity_q7 = (WORD32)((lap_L1_comp * (1 << 7)) + .05f);
2616
0
                }
2617
0
                else
2618
0
                {
2619
0
                    u4_L1_based_lap_complexity_q7 = 25;
2620
0
                }
2621
0
                ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id] =
2622
0
                    (WORD32)u4_L1_based_lap_complexity_q7;
2623
                /*clip f_sim to 0.3 for better stability*/
2624
0
                if(i4_f_sim < 38)
2625
0
                    i4_f_sim = 128 - MAX_LAP_COMPLEXITY_Q7;
2626
0
                ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id] = i4_f_sim;
2627
2628
                /*calculate normalized per pixel sad*/
2629
0
                nor_frm_hme_sad_q10 = (ps_rc_lap_out->i8_frame_acc_coarse_me_cost << 10) /
2630
0
                                      (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
2631
                /*if(rc_pic_type == P_PIC)
2632
                DBG_PRINTF("\n P frm hme sad = %f  ",((float)nor_frm_hme_sad_q10/ (1 << 10)));  */
2633
0
                rc_put_temp_comp_lap(
2634
0
                    ps_rc_ctxt->rc_hdl, i4_f_sim, nor_frm_hme_sad_q10, rc_pic_type);
2635
2636
0
                rc_set_num_scd_in_lap_window(
2637
0
                    ps_rc_ctxt->rc_hdl, i4_num_scd_in_lap_window, num_frames_b4_scd);
2638
2639
0
                if(rc_pic_type == I_PIC && updated_window > (ps_rc_ctxt->i4_max_inter_frm_int << 1))
2640
0
                {
2641
0
                    float i_to_avg_bit_ratio = ihevce_get_i_to_avg_ratio(
2642
0
                        (void *)ps_rc_ctxt,
2643
0
                        ps_rc_lap_out,
2644
0
                        1,
2645
0
                        1,
2646
0
                        1,
2647
0
                        ps_rc_lap_out->ai4_offsets,
2648
0
                        i4_update_delay);
2649
0
                    i_to_avg_bit_ratio = i_to_avg_bit_ratio * 1;
2650
0
                }
2651
2652
                /* accumulation of the hme sad over next sub gop to find the temporal comlexity of the sub GOP*/
2653
0
                if((rc_pic_type == I_PIC) || (rc_pic_type == P_PIC))
2654
0
                {
2655
0
                    ihevce_compute_temporal_complexity_reset_Kp_Kb(
2656
0
                        ps_rc_lap_out, (void *)ps_rc_ctxt, 1);
2657
0
                }
2658
2659
0
                if(i4_var_sum > MAX_LAP_VAR)
2660
0
                {
2661
0
                    i4_var_sum = MAX_LAP_VAR;
2662
0
                }
2663
2664
0
                {
2665
                    /*Filling for dumping data */
2666
2667
0
                    ps_rc_ctxt->ai4_num_scd_in_lap_window[i4_enc_frm_id] = i4_num_scd_in_lap_window;
2668
0
                    ps_rc_ctxt->ai4_num_frames_b4_scd[i4_enc_frm_id] = num_frames_b4_scd;
2669
0
                }
2670
0
            }
2671
0
        }
2672
2673
0
        if((ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6) && (rc_pic_type > P_PIC))
2674
0
        {
2675
0
            ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 0;
2676
0
            is_scd_ref_frame = 0;
2677
0
        }
2678
0
        i4_fade_scene = 0;
2679
        /*Scene type fade is marked only for P pics which are in fade regions*/
2680
0
        if((ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_IN ||
2681
0
            ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_OUT) &&
2682
0
           (ps_rc_lap_out->i4_rc_temporal_lyr_id == 0))
2683
0
        {
2684
0
            is_scd_ref_frame = 1;
2685
0
            i4_fade_scene = 1;
2686
0
        }
2687
2688
0
        if((!(is_scd_ref_frame || ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id])) &&
2689
0
           (((is_first_frame_coded(ps_rc_ctxt->rc_hdl)) && (pic_type == IV_I_FRAME)) ||
2690
0
            (pic_type != IV_I_FRAME)))
2691
0
        {
2692
0
            WORD32 i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2693
0
            i4_is_no_model_scd = 0;
2694
0
            if(call_type == ENC_GET_QP)
2695
0
            {
2696
0
                if(((0 == i4_model_available) || (!i4_is_first_frame_coded)))
2697
0
                {
2698
                    /*No scene change but model not available*/
2699
0
                    i4_is_no_model_scd = 1;
2700
0
                }
2701
0
            }
2702
0
        }
2703
0
        else
2704
0
        {
2705
            /*actual scene changes*/
2706
0
            i4_is_no_model_scd = 2;
2707
0
        }
2708
        /** Pre-enc thread as of now SCD handling is not present */
2709
0
        if(!i4_is_no_model_scd)
2710
0
        {
2711
0
            WORD32 i4_is_first_frame_coded, i4_prev_I_frm_sad, i4_cur_I_frm_sad;
2712
            /*Once first frame has been encoded use prev frame intra satd and cur frame satd to alter est intra sad for cur frame*/
2713
0
            i4_is_first_frame_coded = is_first_frame_coded(ps_rc_ctxt->rc_hdl);
2714
2715
            /*prev I frame sad i changes only in enc stage. For pre enc cur and prev will be same*/
2716
0
            if(ps_rc_ctxt->i8_prev_i_frm_cost > 0)
2717
0
            {
2718
0
                if(i4_is_first_frame_coded && (pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME))
2719
0
                {
2720
0
                    i4_prev_I_frm_sad = rc_get_prev_frame_intra_sad(ps_rc_ctxt->rc_hdl);
2721
0
                    i4_cur_I_frm_sad = (WORD32)(
2722
0
                        (ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id] * i4_prev_I_frm_sad) /
2723
0
                        ps_rc_ctxt->i8_prev_i_frm_cost);
2724
0
                    rc_update_prev_frame_intra_sad(ps_rc_ctxt->rc_hdl, i4_cur_I_frm_sad);
2725
0
                }
2726
0
            }
2727
            /*scale previous frame closed loop SAD with current frame HME SAD to be considered as current frame SAD*/
2728
0
            if(i4_is_first_frame_coded && !(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME) &&
2729
0
               call_type == ENC_GET_QP)
2730
0
            {
2731
0
                if(ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] > 0)
2732
0
                {
2733
0
                    WORD32 prev_frm_cl_sad = rc_get_prev_frame_sad(ps_rc_ctxt->rc_hdl, rc_pic_type);
2734
0
                    WORD32 cur_frm_est_cl_sad = (WORD32)(
2735
0
                        (ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id] *
2736
0
                         prev_frm_cl_sad) /
2737
0
                        ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type]);
2738
0
                    rc_update_prev_frame_sad(ps_rc_ctxt->rc_hdl, cur_frm_est_cl_sad, rc_pic_type);
2739
0
                }
2740
0
            }
2741
2742
0
            if(rc_pic_type == I_PIC && updated_window > (ps_rc_ctxt->i4_max_inter_frm_int << 1))
2743
0
            {
2744
0
                ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] = ihevce_get_i_to_avg_ratio(
2745
0
                    (void *)ps_rc_ctxt,
2746
0
                    ps_rc_lap_out,
2747
0
                    1,
2748
0
                    0,
2749
0
                    1,
2750
0
                    ps_rc_lap_out->ai4_offsets,
2751
0
                    i4_update_delay);
2752
0
            }
2753
2754
0
            ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP = -1;
2755
0
            i4_frame_qp_q6 = get_frame_level_qp(
2756
0
                ps_rc_ctxt->rc_hdl,
2757
0
                rc_pic_type,
2758
0
                i4_max_frame_bits,
2759
0
                &i4_cur_est_texture_bits,  //this value is returned by rc
2760
0
                ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2761
0
                1,
2762
0
                ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id],
2763
0
                ps_rc_lap_out->ps_frame_info,
2764
0
                ps_rc_lap_out->i4_complexity_bin,
2765
0
                i4_scene_num, /*no pause resume concept*/
2766
0
                pi4_tot_bits_estimated,
2767
0
                &ps_rc_lap_out->i4_is_model_valid,
2768
0
                &i4_vbv_buf_max_bits,
2769
0
                &i4_est_tex_bits,
2770
0
                &i4_cur_est_header_bits,
2771
0
                &ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP,
2772
0
                &ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP,
2773
0
                &i4_estimate_to_calc_frm_error);
2774
0
            ASSERT(*pi4_tot_bits_estimated != 0);
2775
            /** The usage of global table will truncate the input given as qp format and hence will not return very low qp values desirable at very
2776
            low bitrate. Hence on the fly calculation is enabled*/
2777
2778
0
            i4_hevc_frame_qp =
2779
0
                ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
2780
2781
0
            if(1 == ps_rc_lap_out->i4_is_model_valid)
2782
0
                ps_rc_lap_out->i4_is_steady_state = 1;
2783
0
            else
2784
0
                ps_rc_lap_out->i4_is_steady_state = 0;
2785
2786
0
            ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used = 0;
2787
0
            ps_rc_ctxt->i8_est_I_pic_header_bits = i4_cur_est_header_bits;
2788
0
        }
2789
0
        else
2790
0
        {
2791
0
            WORD32 i4_count = 0, i4_total_bits, i4_min_error_hevc_qp = 0;
2792
0
            float f_percent_error = 0.0f, f_min_error = 10000.0f;
2793
0
            WORD32 i4_current_bits_estimated = 0;
2794
0
            float i4_i_to_rest_ratio_final;
2795
0
            WORD32 i4_best_br_id = 0;
2796
0
            float af_i_qs[2];
2797
0
            LWORD64 ai8_i_tex_bits[2];
2798
0
            WORD32 i4_ref_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2799
0
                ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2800
0
            WORD32 ai4_header_bits[2];
2801
2802
0
            ps_rc_lap_out->i4_is_steady_state = 0;
2803
2804
0
            if(ps_rc_lap_out->i4_L0_qp > 44)
2805
0
                ps_rc_lap_out->i4_L0_qp = 44;
2806
0
            if(ps_rc_lap_out->i4_L0_qp < 7 - ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset)
2807
0
                ps_rc_lap_out->i4_L0_qp = 7 - ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
2808
2809
0
            ps_rc_lap_out->i4_L0_qp = ps_rc_lap_out->i4_L0_qp - 9;
2810
0
            ps_rc_lap_out->i4_is_model_valid = 0;
2811
0
            ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used = 1;
2812
0
            ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP = -1;
2813
2814
0
            ps_rc_ctxt->i4_normal_inter_pic = (i4_is_no_model_scd == 1);
2815
0
            while(1)
2816
0
            {
2817
0
                WORD32 i4_frame_qs_q3;
2818
0
                WORD32 i4_estimate_to_calc_frm_error_temp;
2819
2820
0
                i_to_avg_bit_ratio = ihevce_get_i_to_avg_ratio(
2821
0
                    (void *)ps_rc_ctxt,
2822
0
                    ps_rc_lap_out,
2823
0
                    1,
2824
0
                    0,
2825
0
                    1,
2826
0
                    ps_rc_lap_out->ai4_offsets,
2827
0
                    i4_update_delay);
2828
2829
0
                ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id] = i_to_avg_bit_ratio;
2830
2831
                /** Use estimate of header bits from pre-enc*/
2832
0
                if(1 == i4_is_no_model_scd)
2833
0
                {
2834
0
                    ps_rc_ctxt->i8_est_I_pic_header_bits =
2835
0
                        get_est_hdr_bits(ps_rc_ctxt->rc_hdl, rc_pic_type);
2836
0
                }
2837
0
                else
2838
0
                {
2839
0
                    WORD32 i4_curr_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2840
0
                        ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2841
                    /*Assume that 30% of header bits are constant and remaining are dependent on Qp
2842
                    and map them accordingly*/
2843
0
                    ps_rc_ctxt->i8_est_I_pic_header_bits = (LWORD64)(
2844
0
                        (.3 * ps_rc_lap_out->i8_est_I_pic_header_bits +
2845
0
                         (1. - .3) * ps_rc_lap_out->i8_est_I_pic_header_bits * i4_ref_qscale) /
2846
0
                        i4_curr_qscale);
2847
0
                }
2848
2849
                /*get qp for scene cut frame based on offline data*/
2850
0
                index = ihevce_get_offline_index(
2851
0
                    ps_rc_ctxt, ps_rc_lap_out->i4_num_pels_in_frame_considered);
2852
2853
                /*Sub pic rC bits extraction */
2854
0
                i4_frame_qs_q3 = rc_get_qp_for_scd_frame(
2855
0
                    ps_rc_ctxt->rc_hdl,
2856
0
                    I_PIC,
2857
0
                    ps_rc_lap_out->i8_frame_satd_act_accum,
2858
0
                    ps_rc_lap_out->i4_num_pels_in_frame_considered,
2859
0
                    (WORD32)ps_rc_ctxt->i8_est_I_pic_header_bits,
2860
0
                    ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id],
2861
0
                    (void *)&g_offline_i_model_coeff[index][0],
2862
0
                    i_to_avg_bit_ratio,
2863
0
                    1,
2864
0
                    ps_rc_ctxt->af_sum_weigh[i4_enc_frm_id],
2865
0
                    ps_rc_lap_out->ps_frame_info,
2866
0
                    ps_rc_ctxt->i4_rc_pass,
2867
0
                    (rc_pic_type != I_PIC),
2868
0
                    ((ps_rc_lap_out->i4_rc_temporal_lyr_id != ps_rc_ctxt->i4_max_temporal_lyr) ||
2869
0
                     (!ps_rc_ctxt->i4_max_temporal_lyr)),
2870
0
                    1,
2871
0
                    &i4_total_bits,
2872
0
                    &i4_current_bits_estimated,
2873
0
                    ps_rc_lap_out->i4_use_offline_model_2pass,
2874
0
                    ai8_i_tex_bits,
2875
0
                    af_i_qs,
2876
0
                    i4_best_br_id,
2877
0
                    &i4_estimate_to_calc_frm_error_temp);
2878
2879
0
                i4_hevc_frame_qp = ihevce_rc_get_scaled_hevc_qp_from_qs_q3(
2880
0
                    i4_frame_qs_q3, ps_rc_ctxt->ps_rc_quant_ctxt);
2881
2882
                /*Get corresponding q scale*/
2883
0
                i4_frame_qp =
2884
0
                    ihevce_rc_get_scaled_mpeg2_qp(i4_hevc_frame_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2885
2886
0
                if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
2887
0
                    i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
2888
2889
0
                {
2890
0
                    WORD32 i4_init_qscale = ihevce_rc_get_scaled_mpeg2_qp(
2891
0
                        ps_rc_lap_out->i4_L0_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
2892
0
                    f_percent_error = (float)(abs(i4_init_qscale - i4_frame_qp)) / i4_init_qscale;
2893
0
                    if(f_percent_error < f_min_error)
2894
0
                    {
2895
0
                        f_min_error = f_percent_error;
2896
0
                        i4_min_error_hevc_qp = i4_hevc_frame_qp;
2897
0
                        i4_i_to_rest_ratio_final = i_to_avg_bit_ratio;
2898
                        /*Get the bits estimated for least error*/
2899
0
                        *pi4_tot_bits_estimated = i4_current_bits_estimated;
2900
0
                        i4_estimate_to_calc_frm_error = i4_estimate_to_calc_frm_error_temp;
2901
0
                    }
2902
0
                    else
2903
0
                    {}
2904
0
                    ASSERT(*pi4_tot_bits_estimated != 0);
2905
0
                }
2906
0
                i4_count++;
2907
0
                if(/*(ps_rc_lap_out->i4_L0_qp == i4_hevc_frame_qp) ||*/ (i4_count > 17))
2908
0
                    break;
2909
0
                ps_rc_lap_out->i4_L0_qp++;
2910
0
            }
2911
0
            ps_rc_lap_out->i4_L0_qp = i4_min_error_hevc_qp;
2912
2913
0
            i4_hevc_frame_qp = i4_min_error_hevc_qp;
2914
0
            if(2 == i4_is_no_model_scd)
2915
0
            {
2916
                /* SGI & Enc Loop Parallelism related changes*/
2917
2918
                /*model reset not required if it is first frame*/
2919
0
                if(ps_rc_ctxt->i4_is_first_frame_encoded && !i4_fade_scene &&
2920
0
                   !ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] &&
2921
0
                   !ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] &&
2922
0
                   !ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] &&
2923
0
                   !ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id])
2924
0
                {
2925
0
                    ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id] = 1;
2926
                    /*reset all pic type is first frame encoded flag*/
2927
2928
0
                    ASSERT(pic_type == IV_IDR_FRAME || pic_type == IV_I_FRAME);
2929
0
                }
2930
0
                else if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
2931
0
                {
2932
0
                    rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, I_PIC);
2933
0
                    ASSERT(rc_pic_type == I_PIC);
2934
0
                    ASSERT(ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] == 0);
2935
0
                }
2936
0
                else if(
2937
0
                    ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
2938
0
                    ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
2939
0
                    ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] || i4_fade_scene)
2940
0
                {
2941
                    /*Only when there are back to back scene cuts we need a non- Ipic will be marked as scene cut*/
2942
                    /* Same path can also be followed during pause to resume detection to determine cur frame qp however handling during update is different*/
2943
0
                    WORD32 i4_prev_qp, i, i4_new_qp_hevc_qp, I_hevc_qp, cur_hevc_qp;
2944
2945
                    /*both cannot be set at same time since lap cannot mark same frame as both scene cut and pause to resume flag*/
2946
0
                    ASSERT(
2947
0
                        (ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] &&
2948
0
                         ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id]) == 0);
2949
2950
0
                    I_hevc_qp = i4_hevc_frame_qp;
2951
2952
                    /*alter ai4_prev_pic_hevc_qp so that qp restriction ll not let even other pictures temporary scd are thrashed*/
2953
                    //if(ps_rc_lap_out->i4_rc_temporal_lyr_id != ps_rc_ctxt->i4_max_temporal_lyr)
2954
0
                    {
2955
0
                        if(ps_rc_ctxt->i4_field_pic == 0)
2956
0
                        {
2957
0
                            for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2958
0
                            {
2959
0
                                i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
2960
0
                                i4_new_qp_hevc_qp = I_hevc_qp + i;
2961
0
                                i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2962
0
                                    ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2963
0
                                if(i4_prev_qp < i4_new_qp_hevc_qp)
2964
0
                                {
2965
0
                                    ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i] =
2966
0
                                        i4_new_qp_hevc_qp;
2967
0
                                }
2968
0
                            }
2969
0
                        }
2970
0
                        else
2971
0
                        { /*field case*/
2972
2973
0
                            for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
2974
0
                            {
2975
0
                                i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
2976
0
                                i4_new_qp_hevc_qp = I_hevc_qp + i;
2977
0
                                i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2978
0
                                    ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2979
0
                                if(i4_prev_qp < i4_new_qp_hevc_qp)
2980
0
                                {
2981
0
                                    ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i] =
2982
0
                                        i4_new_qp_hevc_qp;
2983
0
                                }
2984
2985
0
                                i4_prev_qp =
2986
0
                                    ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i + FIELD_OFFSET];
2987
0
                                i4_new_qp_hevc_qp = I_hevc_qp + i;
2988
0
                                i4_new_qp_hevc_qp = ihevce_clip_min_max_qp(
2989
0
                                    ps_rc_ctxt, i4_new_qp_hevc_qp, (picture_type_e)i, i - 1);
2990
0
                                if(i4_prev_qp < i4_new_qp_hevc_qp)
2991
0
                                {
2992
0
                                    ps_rc_ctxt
2993
0
                                        ->ai4_prev_pic_hevc_qp[i4_scene_num][i + FIELD_OFFSET] =
2994
0
                                        i4_new_qp_hevc_qp;
2995
0
                                }
2996
0
                            }
2997
0
                        }
2998
0
                    }
2999
0
                    {
3000
0
                        WORD32 i4_updated_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i];
3001
0
                        WORD32 i4_scale;
3002
3003
0
                        if(I_hevc_qp == i4_updated_qp)
3004
0
                            i4_scale = 16;
3005
0
                        else if(I_hevc_qp == (i4_updated_qp - 1))
3006
0
                            i4_scale = 14;
3007
0
                        else if(I_hevc_qp == (i4_updated_qp - 2))
3008
0
                            i4_scale = 12;
3009
0
                        else
3010
0
                            i4_scale = 10;
3011
3012
0
                        *pi4_tot_bits_estimated = (i4_scale * (*pi4_tot_bits_estimated)) >> 4;
3013
0
                        i4_estimate_to_calc_frm_error =
3014
0
                            (i4_scale * i4_estimate_to_calc_frm_error) >> 4;
3015
0
                    }
3016
0
                    if(call_type == ENC_GET_QP)
3017
0
                    {
3018
0
                        ps_rc_lap_out->i8_est_text_bits = *pi4_tot_bits_estimated;
3019
0
                    }
3020
0
                    ASSERT(*pi4_tot_bits_estimated != 0);
3021
3022
                    /*use previous frame qp of same pic type or SCD i frame qp with offset whichever is maximum*/
3023
                    /*For field case adding of  grater than 4 results in the qp increasing greatly when compared to previous pics/fields*/
3024
0
                    if(rc_pic_type <= FIELD_OFFSET)
3025
0
                        cur_hevc_qp = I_hevc_qp + rc_pic_type;
3026
0
                    else
3027
0
                        cur_hevc_qp = I_hevc_qp + (rc_pic_type - FIELD_OFFSET);
3028
3029
0
                    i4_prev_qp = ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type];
3030
3031
0
                    if((cur_hevc_qp < i4_prev_qp) && (ps_rc_ctxt->i4_num_active_pic_type > 2) &&
3032
0
                       (is_first_frame_coded(ps_rc_ctxt->rc_hdl)) && (!i4_fade_scene))
3033
0
                    {
3034
0
                        cur_hevc_qp = i4_prev_qp;
3035
0
                    }
3036
0
                    i4_frame_qp =
3037
0
                        ihevce_rc_get_scaled_mpeg2_qp(cur_hevc_qp, ps_rc_ctxt->ps_rc_quant_ctxt);
3038
0
                    i4_hevc_frame_qp = cur_hevc_qp;
3039
                    //ps_rc_ctxt->i4_is_non_I_scd_pic = 0;
3040
3041
0
                    rc_reset_first_frame_coded_flag(ps_rc_ctxt->rc_hdl, rc_pic_type);
3042
0
                }
3043
0
                else
3044
0
                {}
3045
0
            }
3046
0
            if((1 == i4_is_no_model_scd) && (call_type == ENC_GET_QP))
3047
0
            {
3048
0
                WORD32 i4_clip_QP;
3049
0
                i4_frame_qp_q6 =
3050
0
                    clip_qp_based_on_prev_ref(ps_rc_ctxt->rc_hdl, rc_pic_type, 1, i4_scene_num);
3051
0
                i4_clip_QP =
3052
0
                    ihevce_rc_get_scaled_hevce_qp_q6(i4_frame_qp_q6, ps_rc_ctxt->u1_bit_depth);
3053
0
                if(ps_rc_ctxt->i4_rc_pass != 2)
3054
0
                {
3055
0
                    i4_hevc_frame_qp = i4_clip_QP;
3056
0
                }
3057
0
                if((rc_pic_type == P_PIC) || (rc_pic_type == P1_PIC))
3058
0
                {
3059
0
                    *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 11) >> 4; /* P picture*/
3060
0
                    i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 11) >> 4;
3061
0
                }
3062
0
                else if((rc_pic_type == B_PIC) || (rc_pic_type == BB_PIC))
3063
0
                {
3064
0
                    *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 9) >> 4; /* B layer 1*/
3065
0
                    i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 9) >> 4;
3066
0
                }
3067
0
                else if((rc_pic_type == B1_PIC) || (rc_pic_type == B11_PIC))
3068
0
                {
3069
0
                    *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 7) >> 4; /* B layer 2*/
3070
0
                    i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 7) >> 4;
3071
0
                }
3072
0
                else if((rc_pic_type == B2_PIC) || (rc_pic_type == B22_PIC))
3073
0
                {
3074
0
                    *pi4_tot_bits_estimated = (*pi4_tot_bits_estimated * 5) >> 4; /* B layer 3*/
3075
0
                    i4_estimate_to_calc_frm_error = (i4_estimate_to_calc_frm_error * 5) >> 4;
3076
0
                }
3077
0
            }
3078
0
            rc_add_est_tot(ps_rc_ctxt->rc_hdl, *pi4_tot_bits_estimated);
3079
0
        }
3080
3081
0
        ASSERT(i4_hevc_frame_qp >= -ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
3082
3083
        /*constraint qp swing based on neighbour frames*/
3084
0
        if(is_first_frame_coded(ps_rc_ctxt->rc_hdl))
3085
0
        {
3086
0
            if(ps_rc_ctxt->i4_field_pic == 0)
3087
0
            {
3088
                /*In dissolve case the p frame comes before an I pic and ref b comes after then what
3089
                happens is b frame qp is restricted by the p frame qp so changed it to prev ref pic type*/
3090
0
                if(rc_pic_type != I_PIC && rc_pic_type != P_PIC)
3091
0
                {
3092
0
                    if(ps_rc_lap_out->i4_rc_temporal_lyr_id == 1)
3093
0
                    {
3094
0
                        picture_type_e prev_ref_pic_type =
3095
0
                            rc_getprev_ref_pic_type(ps_rc_ctxt->rc_hdl);
3096
3097
0
                        if(i4_hevc_frame_qp >
3098
0
                           ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] + 3)
3099
0
                        {
3100
0
                            if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] >
3101
0
                               0)
3102
0
                                i4_hevc_frame_qp =
3103
0
                                    ps_rc_ctxt
3104
0
                                        ->ai4_prev_pic_hevc_qp[i4_scene_num][prev_ref_pic_type] +
3105
0
                                    3;
3106
0
                        }
3107
0
                    }
3108
0
                    else if(
3109
0
                        i4_hevc_frame_qp >
3110
0
                        (ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 3))
3111
0
                    {
3112
                        /*allow max of +3 compared to previous frame*/
3113
0
                        if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] > 0)
3114
0
                            i4_hevc_frame_qp =
3115
0
                                ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 3;
3116
0
                    }
3117
0
                }
3118
3119
0
                if((rc_pic_type != I_PIC && rc_pic_type != P_PIC) &&
3120
0
                   (i4_hevc_frame_qp <
3121
0
                    ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1]))
3122
0
                {
3123
0
                    i4_hevc_frame_qp =
3124
0
                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1];
3125
0
                }
3126
3127
                /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
3128
0
                if(temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
3129
0
                   ps_rc_ctxt->i4_max_temporal_lyr > 1)
3130
0
                {
3131
0
                    i4_hevc_frame_qp =
3132
0
                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type - 1] + 1;
3133
0
                }
3134
0
            }
3135
0
            else /*for field case*/
3136
0
            {
3137
0
                if(ps_rc_lap_out->i4_rc_temporal_lyr_id >= 1)
3138
0
                {
3139
                    /*To make the comparison of qp with the top field's of previous layer tempor layer id matches with the pic type. */
3140
0
                    if(i4_hevc_frame_qp >
3141
0
                       ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3142
0
                                                       [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3143
0
                           3)
3144
0
                    {
3145
                        /*allow max of +3 compared to previous frame*/
3146
0
                        if(0 <
3147
0
                           ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3148
0
                                                           [ps_rc_lap_out->i4_rc_temporal_lyr_id])
3149
0
                            i4_hevc_frame_qp =
3150
0
                                ps_rc_ctxt
3151
0
                                    ->ai4_prev_pic_hevc_qp[i4_scene_num]
3152
0
                                                          [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3153
0
                                3;
3154
0
                    }
3155
0
                    if(i4_hevc_frame_qp <
3156
0
                       ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3157
0
                                                       [ps_rc_lap_out->i4_rc_temporal_lyr_id])
3158
0
                    {
3159
0
                        i4_hevc_frame_qp =
3160
0
                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3161
0
                                                            [ps_rc_lap_out->i4_rc_temporal_lyr_id];
3162
0
                    }
3163
3164
                    /** Force non-ref B pic qp to be ref_B_PIC_qp - 1. This is not valid for when max teporla later is less than 2*/
3165
0
                    if(temporal_layer_id == ps_rc_ctxt->i4_max_temporal_lyr &&
3166
0
                       ps_rc_ctxt->i4_max_temporal_lyr > 1)
3167
0
                    {
3168
0
                        i4_hevc_frame_qp =
3169
0
                            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num]
3170
0
                                                            [ps_rc_lap_out->i4_rc_temporal_lyr_id] +
3171
0
                            1;
3172
0
                    }
3173
0
                }
3174
                /** At lower range qp swing for same pic type is also imposed to make sure
3175
                    qp does not fall from 10 to 4 since they differ by only one q scale*/
3176
0
            }
3177
0
        }
3178
3179
        /**clip to min qp which is user configurable*/
3180
0
        i4_hevc_frame_qp = ihevce_clip_min_max_qp(
3181
0
            ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
3182
3183
0
#if 1  //FRAME_PARALLEL_LVL
3184
0
        ps_rc_ctxt->i4_est_text_bits_ctr_get_qp++;  //ELP_RC
3185
0
        ps_rc_ctxt->i4_est_text_bits_ctr_get_qp =
3186
0
            (ps_rc_ctxt->i4_est_text_bits_ctr_get_qp % (ps_rc_ctxt->i4_num_frame_parallel));
3187
0
#endif
3188
        /** the estimates are reset only duing enc call*/
3189
3190
#if USE_USER_FIRST_FRAME_QP
3191
        /*I_PIC check is necessary coz pre-enc can query for qp even before first frame update has happened*/
3192
        if(!ps_rc_ctxt->i4_is_first_frame_encoded && rc_pic_type == I_PIC)
3193
        {
3194
            i4_hevc_frame_qp = ps_rc_ctxt->i4_init_frame_qp_user;
3195
            DBG_PRINTF("FIXED START QP PATH *************************\n");
3196
        }
3197
#endif
3198
0
    }
3199
3200
0
    if(CONST_QP != e_rc_type)
3201
0
    {
3202
0
        ASSERT(*pi4_tot_bits_estimated != 0);
3203
0
    }
3204
3205
0
    ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP = i4_hevc_frame_qp;
3206
0
    if(ps_rc_lap_out->i4_is_model_valid)
3207
0
    {
3208
0
        get_bits_for_final_qp(
3209
0
            ps_rc_ctxt->rc_hdl,
3210
0
            &ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP,
3211
0
            &ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP,
3212
0
            &ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP,
3213
0
            i4_hevc_frame_qp,
3214
0
            ihevce_rc_get_scaled_mpeg2_qp_q6(
3215
0
                i4_hevc_frame_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset,
3216
0
                ps_rc_ctxt->u1_bit_depth),
3217
0
            i4_cur_est_header_bits,
3218
0
            i4_est_tex_bits,
3219
0
            i4_vbv_buf_max_bits,
3220
0
            rc_pic_type,
3221
0
            ps_rc_lap_out->i4_rc_display_num);
3222
0
    }
3223
0
    i4_deltaQP = ihevce_ebf_based_rc_correction_to_avoid_overflow(
3224
0
        ps_rc_ctxt, ps_rc_lap_out, pi4_tot_bits_estimated);
3225
0
    i4_hevc_frame_qp += i4_deltaQP;
3226
3227
    /**clip to min qp which is user configurable*/
3228
0
    i4_hevc_frame_qp = ihevce_clip_min_max_qp(
3229
0
        ps_rc_ctxt, i4_hevc_frame_qp, rc_pic_type, ps_rc_lap_out->i4_rc_temporal_lyr_id);
3230
3231
    /*set estimate status for frame level error calculation*/
3232
0
    if(i4_estimate_to_calc_frm_error > 0)
3233
0
    {
3234
0
        rc_set_estimate_status(
3235
0
            ps_rc_ctxt->rc_hdl,
3236
0
            i4_estimate_to_calc_frm_error - ps_rc_ctxt->i8_est_I_pic_header_bits,
3237
0
            ps_rc_ctxt->i8_est_I_pic_header_bits,
3238
0
            ps_rc_ctxt->i4_est_text_bits_ctr_get_qp);
3239
0
    }
3240
0
    else
3241
0
    {
3242
0
        rc_set_estimate_status(
3243
0
            ps_rc_ctxt->rc_hdl,
3244
0
            -1,
3245
0
            ps_rc_ctxt->i8_est_I_pic_header_bits,
3246
0
            ps_rc_ctxt->i4_est_text_bits_ctr_get_qp);
3247
0
    }
3248
3249
0
    ps_rc_lap_out->i8_est_text_bits = *pi4_tot_bits_estimated;
3250
3251
    /*B pictures which are in fades will take the highest QP of either side of P pics*/
3252
0
    if(ps_rc_lap_out->i4_rc_pic_type == IV_B_FRAME &&
3253
0
       (ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_IN ||
3254
0
        ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_FADE_OUT))
3255
0
    {
3256
0
        i4_hevc_frame_qp =
3257
0
            MAX(ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0], ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1]);
3258
0
    }
3259
3260
    /*saving the last two pics of layer 0*/
3261
0
    if(0 == ps_rc_lap_out->i4_rc_temporal_lyr_id)
3262
0
    {
3263
0
        ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[1] = ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0];
3264
0
        ps_rc_ctxt->ai4_last_tw0_lyr0_pic_qp[0] = i4_hevc_frame_qp;
3265
0
    }
3266
3267
0
    return i4_hevc_frame_qp;
3268
0
}
3269
3270
/*##########################################################*/
3271
/******* END OF ENC THRD QP QUERY FUNCTIONS ****************/
3272
/*########################################################*/
3273
3274
/*####################################################*/
3275
/******* START OF I2AVG RATIO FUNCTIONS **************/
3276
/*##################################################*/
3277
3278
/**
3279
******************************************************************************
3280
*
3281
*  @brief function to get i_to_avg_rest at scene cut frame based on data available from LAP
3282
*
3283
*  @par   Description
3284
*
3285
*  @param[in]   pv_rc_ctxt
3286
*               void pointer to rc ctxt
3287
*  @param[in]   ps_rc_lap_out : pointer to lap out structure
3288
*  @param[in]   i4_update_delay : The Delay in the update. This can happen for dist. case!
3289
*               All decision should consider this delay for updation!
3290
*  @return      WORD32 i_to_rest bit ratio
3291
*
3292
******************************************************************************
3293
*/
3294
float ihevce_get_i_to_avg_ratio(
3295
    void *pv_rc_ctxt,
3296
    rc_lap_out_params_t *ps_rc_lap_out,
3297
    WORD32 i_to_p_qp_offset,
3298
    WORD32 i4_offset_flag,
3299
    WORD32 i4_call_type,
3300
    WORD32 ai4_qp_offsets[4],
3301
    WORD32 i4_update_delay)
3302
0
{
3303
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
3304
0
    WORD32 i = 0, k = 0, num_frames_in_lap[MAX_PIC_TYPE] = { 0 }, ai4_pic_dist[MAX_PIC_TYPE],
3305
0
           ai4_pic_dist_in_cur_gop[MAX_PIC_TYPE] = { 0 };
3306
0
    WORD32 i4_num_b, i4_num_frms_traversed_in_lap = 0, total_frms_considered = 0,
3307
0
                     i4_flag_i_frame_exit = 0, u4_rc_scene_number;
3308
0
    rc_lap_out_params_t *ps_cur_rc_lap_out = ps_rc_lap_out;
3309
3310
0
    rc_lap_out_params_t *ps_cur_rc_lap_out_I = ps_rc_lap_out;
3311
0
    double complexity[MAX_PIC_TYPE] = { 0 }, d_first_i_complexity = 0, d_first_p_complexity = 0.0f,
3312
0
           cur_lambda_modifer, den = 0, average_intra_complexity = 0;
3313
0
    double i_frm_lambda_modifier;
3314
0
    float i_to_rest_bit_ratio = 8.00;
3315
0
    picture_type_e curr_rc_pic_type;
3316
0
    LWORD64 i8_l1_analysis_lap_comp = 0;
3317
0
    WORD32 i4_intra_frame_interval = rc_get_intra_frame_interval(ps_rc_ctxt->rc_hdl);
3318
0
    UWORD32 u4_L1_based_lap_complexity_q7 = 0;
3319
0
    WORD32 i4_frame_qp = 0, i4_I_frame_qp = 0;
3320
3321
0
    WORD32 ai4_lambda_offsets[5] = { -3, -2, 2, 6, 7 };
3322
    /* The window for which your update is guaranteed */
3323
0
    WORD32 updated_window = ps_rc_ctxt->i4_num_frame_in_lap_window - i4_update_delay;
3324
3325
0
    ASSERT(ps_rc_ctxt->i4_rc_pass != 2);
3326
0
    rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3327
3328
0
    if(ps_rc_ctxt->i4_max_temporal_lyr)
3329
0
    {
3330
0
        i4_num_b = ((WORD32)pow((float)2, ps_rc_ctxt->i4_max_temporal_lyr)) - 1;
3331
0
    }
3332
0
    else
3333
0
    {
3334
0
        i4_num_b = 0;
3335
0
    }
3336
0
    i_frm_lambda_modifier = ihevce_get_frame_lambda_modifier((WORD8)I_PIC, 0, 1, 1, i4_num_b);
3337
    /* check should be wrt inter frame interval*/
3338
    /*If lap frames are not sufficient return default ratio*/
3339
0
    u4_rc_scene_number = ps_cur_rc_lap_out_I->u4_rc_scene_num;
3340
3341
0
    if(updated_window < 4)
3342
0
    {
3343
0
        return i_to_rest_bit_ratio;
3344
0
    }
3345
3346
0
    k = 0;
3347
0
    if(ps_cur_rc_lap_out != NULL)
3348
0
    {
3349
0
        WORD32 i4_temp_frame_qp;
3350
3351
0
        if(ps_cur_rc_lap_out->i4_L0_qp == -1)
3352
0
        {
3353
0
            i4_frame_qp = ps_cur_rc_lap_out->i4_L1_qp;
3354
0
            i4_I_frame_qp = ps_cur_rc_lap_out->i4_L1_qp - 3;
3355
0
        }
3356
0
        else
3357
0
        {
3358
0
            i4_frame_qp = ps_cur_rc_lap_out->i4_L0_qp;
3359
0
            i4_I_frame_qp = ps_cur_rc_lap_out->i4_L0_qp - 3;
3360
0
        }
3361
3362
0
        do
3363
0
        {
3364
0
            curr_rc_pic_type = ihevce_rc_conv_pic_type(
3365
0
                (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out->i4_rc_pic_type,
3366
0
                ps_rc_ctxt->i4_field_pic,
3367
0
                ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
3368
0
                ps_cur_rc_lap_out->i4_is_bottom_field,
3369
0
                ps_rc_ctxt->i4_top_field_first);
3370
0
            cur_lambda_modifer = ihevce_get_frame_lambda_modifier(
3371
0
                (WORD8)curr_rc_pic_type,
3372
0
                ps_cur_rc_lap_out->i4_rc_temporal_lyr_id,
3373
0
                1,
3374
0
                ps_cur_rc_lap_out->i4_rc_is_ref_pic,
3375
0
                i4_num_b);
3376
0
            if(curr_rc_pic_type == I_PIC)
3377
0
            {
3378
0
                i4_temp_frame_qp = i4_frame_qp + ai4_lambda_offsets[curr_rc_pic_type];
3379
0
            }
3380
0
            else
3381
0
            {
3382
0
                i4_temp_frame_qp =
3383
0
                    i4_frame_qp + ai4_lambda_offsets[ps_cur_rc_lap_out->i4_rc_temporal_lyr_id + 1];
3384
0
                i4_temp_frame_qp =
3385
0
                    i4_temp_frame_qp +
3386
0
                    ps_cur_rc_lap_out->ai4_offsets[ps_cur_rc_lap_out->i4_rc_temporal_lyr_id + 1];
3387
0
            }
3388
3389
0
            i4_temp_frame_qp = CLIP3(i4_temp_frame_qp, 1, 51);
3390
0
            i4_I_frame_qp = CLIP3(i4_I_frame_qp, 1, 51);
3391
3392
0
            if(curr_rc_pic_type == I_PIC)
3393
0
            {
3394
0
                complexity[I_PIC] += (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3395
0
                if(total_frms_considered == 0)
3396
0
                    d_first_i_complexity =
3397
0
                        (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3398
3399
0
                num_frames_in_lap[I_PIC]++;
3400
0
                i8_l1_analysis_lap_comp +=
3401
0
                    (LWORD64)(1.17 * ps_cur_rc_lap_out->i8_raw_pre_intra_sad);
3402
0
            }
3403
0
            else
3404
0
            {
3405
0
                if((num_frames_in_lap[P_PIC] == 0) && (curr_rc_pic_type == P_PIC))
3406
0
                    d_first_p_complexity =
3407
0
                        (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3408
3409
0
                if(total_frms_considered == 0)
3410
0
                {
3411
0
                    num_frames_in_lap[I_PIC]++;
3412
0
                    {
3413
0
                        complexity[I_PIC] +=
3414
0
                            (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3415
0
                        d_first_i_complexity =
3416
0
                            (double)ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp];
3417
0
                    }
3418
0
                }
3419
0
                else
3420
0
                {
3421
                    /*SAD is scaled according the lambda parametrs use to make it proportional to bits consumed in the end*/
3422
0
#if !USE_SQRT
3423
                    //complexity[curr_rc_pic_type] += (double)(MIN(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],ps_cur_rc_lap_out->i8_pre_intra_sad)/(/*(cur_lambda_modifer/i_frm_lambda_modifier) * */pow(1.125,(ps_rc_lap_out->i4_rc_temporal_lyr_id + 1/*i_to_p_qp_offset*/))));
3424
0
                    if((curr_rc_pic_type > P_PIC) &&
3425
0
                       (ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6))
3426
0
                        complexity[curr_rc_pic_type] +=
3427
0
                            (double)(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad
3428
0
                                         [i4_temp_frame_qp]);  // /(/*(cur_lambda_modifer/i_frm_lambda_modifier) * */pow(1.125,(ps_rc_lap_out->i4_rc_temporal_lyr_id + 1/*i_to_p_qp_offset*/))));
3429
0
                    else
3430
0
                        complexity[curr_rc_pic_type] += (double)(MIN(
3431
0
                            ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],
3432
0
                            ps_cur_rc_lap_out->ai8_pre_intra_sad
3433
0
                                [i4_temp_frame_qp]));  ///(/*(cur_lambda_modifer/i_frm_lambda_modifier) * */pow(1.125,(ps_rc_lap_out->i4_rc_temporal_lyr_id + 1/*i_to_p_qp_offset*/))));
3434
3435
#else
3436
                    complexity[curr_rc_pic_type] +=
3437
                        MIN(ps_cur_rc_lap_out->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp],
3438
                            ps_cur_rc_lap_out->i8_pre_intra_sad) /
3439
                        (sqrt(cur_lambda_modifer / i_frm_lambda_modifier) *
3440
                         pow(1.125, (ps_rc_lap_out->i4_rc_temporal_lyr_id + 1)));
3441
#endif
3442
0
                    num_frames_in_lap[curr_rc_pic_type]++;
3443
0
                }
3444
0
                i8_l1_analysis_lap_comp += (LWORD64)(
3445
0
                    (float)ps_cur_rc_lap_out->i8_raw_l1_coarse_me_sad /
3446
0
                    pow(1.125, curr_rc_pic_type));
3447
0
            }
3448
3449
0
            if(ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)
3450
0
            {
3451
0
                if(curr_rc_pic_type < B_PIC)
3452
0
                {
3453
                    /*accumulate average intra sad*/
3454
0
                    average_intra_complexity +=
3455
0
                        ps_cur_rc_lap_out
3456
0
                            ->ai8_pre_intra_sad[i4_I_frame_qp] /*/i_frm_lambda_modifier*/;
3457
0
                    i4_num_frms_traversed_in_lap++;
3458
0
                }
3459
0
            }
3460
0
            else
3461
0
            {
3462
                /*accumulate average intra sad*/
3463
0
                average_intra_complexity +=
3464
0
                    ps_cur_rc_lap_out->ai8_pre_intra_sad[i4_I_frame_qp] /*/i_frm_lambda_modifier*/;
3465
0
                i4_num_frms_traversed_in_lap++;
3466
0
            }
3467
3468
0
            ai4_pic_dist_in_cur_gop[curr_rc_pic_type]++;
3469
0
            i++;
3470
0
            total_frms_considered++;
3471
0
            i4_num_frms_traversed_in_lap++;
3472
0
            ps_cur_rc_lap_out = (rc_lap_out_params_t *)ps_cur_rc_lap_out->ps_rc_lap_out_next_encode;
3473
3474
0
            if((ps_cur_rc_lap_out == NULL) ||
3475
0
               ((total_frms_considered + k) == i4_intra_frame_interval) || (i >= updated_window))
3476
0
            {
3477
0
                break;
3478
0
            }
3479
3480
0
            if((i >= (ps_rc_ctxt->i4_next_sc_i_in_rc_look_ahead - k) ||
3481
0
                (ps_cur_rc_lap_out->i4_rc_pic_type == IV_I_FRAME) ||
3482
0
                (ps_cur_rc_lap_out->i4_rc_pic_type == IV_IDR_FRAME)) &&
3483
0
               (i4_offset_flag == 1))
3484
0
            {
3485
0
                break;
3486
0
            }
3487
            /*If an I frame enters the lookahead it can cause bit allocation to go bad
3488
            if corresponding p/b frames are absent*/
3489
0
            if(((total_frms_considered + k) > (WORD32)(0.75f * i4_intra_frame_interval)) &&
3490
0
               ((ps_cur_rc_lap_out->i4_rc_pic_type == IV_I_FRAME) ||
3491
0
                (ps_cur_rc_lap_out->i4_rc_pic_type == IV_IDR_FRAME)))
3492
0
            {
3493
0
                i4_flag_i_frame_exit = 1;
3494
0
                break;
3495
0
            }
3496
3497
0
        } while(1);
3498
3499
0
        if(total_frms_considered > 0)
3500
0
        {
3501
0
            float lap_L1_comp =
3502
0
                (float)i8_l1_analysis_lap_comp /
3503
0
                (total_frms_considered * ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width);
3504
3505
0
            lap_L1_comp = rc_get_offline_normalized_complexity(
3506
0
                ps_rc_ctxt->u4_intra_frame_interval,
3507
0
                ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width,
3508
0
                lap_L1_comp,
3509
0
                ps_rc_ctxt->i4_rc_pass);
3510
3511
0
            u4_L1_based_lap_complexity_q7 = (WORD32)((lap_L1_comp * (1 << 7)) + .05f);
3512
0
        }
3513
0
        else
3514
0
        {
3515
0
            u4_L1_based_lap_complexity_q7 = 25;
3516
0
        }
3517
3518
0
        if(i4_call_type == 1)
3519
0
        {
3520
0
            if(num_frames_in_lap[0] > 0)
3521
0
            {
3522
0
                float f_curr_i_to_sum = (float)(d_first_i_complexity / complexity[0]);
3523
0
                f_curr_i_to_sum = CLIP3(f_curr_i_to_sum, 0.1f, 100.0f);
3524
0
                rc_set_i_to_sum_api_ba(ps_rc_ctxt->rc_hdl, f_curr_i_to_sum);
3525
0
            }
3526
0
        }
3527
3528
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
3529
0
        {
3530
0
            if(num_frames_in_lap[i] > 0)
3531
0
            {
3532
0
                complexity[i] = complexity[i] / num_frames_in_lap[i];
3533
0
            }
3534
0
        }
3535
        /*for non - I scd case it is possible that entire LAP window might not have intra picture. Consider average intra sad when
3536
        atleast one I pic is not available*/
3537
0
        if(num_frames_in_lap[I_PIC] == 0)
3538
0
        {
3539
0
            ASSERT(i4_num_frms_traversed_in_lap);
3540
0
            complexity[I_PIC] = average_intra_complexity / i4_num_frms_traversed_in_lap;
3541
0
        }
3542
        /*get picture type distribution in LAP*/
3543
0
        if(num_frames_in_lap[I_PIC] == 0)
3544
0
        {
3545
0
            rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3546
0
        }
3547
0
        else
3548
0
        {
3549
0
            memmove(ai4_pic_dist, num_frames_in_lap, sizeof(WORD32) * MAX_PIC_TYPE);
3550
0
        }
3551
3552
0
        {
3553
0
            WORD32 num_inter_pic = 0;
3554
0
            for(i = 1; i < MAX_PIC_TYPE; i++)
3555
0
            {
3556
0
                den += complexity[i] * ai4_pic_dist[i];
3557
0
            }
3558
3559
0
            for(i = 1; i < MAX_PIC_TYPE; i++)
3560
0
            {
3561
0
                num_inter_pic += ai4_pic_dist[i];
3562
0
            }
3563
0
            if(num_inter_pic > 0)
3564
0
                den = den / num_inter_pic;
3565
0
            else
3566
0
                den = 0.0;
3567
0
        }
3568
3569
0
        if(den > 0)
3570
0
            i_to_rest_bit_ratio = (float)((complexity[I_PIC]) / den);
3571
0
        else
3572
0
            i_to_rest_bit_ratio = 15;
3573
3574
0
        if((total_frms_considered < (WORD32)(0.75f * i4_intra_frame_interval)) &&
3575
0
           (total_frms_considered < (updated_window - 1)) &&
3576
0
           ((UWORD32)total_frms_considered < ((ps_rc_ctxt->u4_max_frame_rate / 1000))))
3577
0
        {
3578
            /*This GOP will only sustain for few frames hence have strict restriction for I to rest ratio*/
3579
0
            if(i_to_rest_bit_ratio > 12)
3580
0
                i_to_rest_bit_ratio = 12;
3581
3582
0
            if(i_to_rest_bit_ratio > 8 &&
3583
0
               total_frms_considered < (ps_rc_ctxt->i4_max_inter_frm_int * 2))
3584
0
                i_to_rest_bit_ratio = 8;
3585
0
        }
3586
0
    }
3587
3588
0
    if((i4_call_type == 1) && (i_to_rest_bit_ratio < I_TO_REST_VVFAST) && (i4_offset_flag == 1))
3589
0
    {
3590
0
        float f_p_to_i_ratio = (float)(d_first_p_complexity / d_first_i_complexity);
3591
0
        if(ps_rc_lap_out->i8_frame_satd_act_accum <
3592
0
           (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width * 1.5f))
3593
0
            rc_set_p_to_i_complexity_ratio(ps_rc_ctxt->rc_hdl, f_p_to_i_ratio);
3594
0
    }
3595
3596
    /*Reset the pic distribution if I frame exit was encountered*/
3597
3598
0
    if(ps_rc_ctxt->e_rate_control_type != CONST_QP)
3599
0
    {
3600
0
        rc_get_pic_distribution(ps_rc_ctxt->rc_hdl, &ai4_pic_dist[0]);
3601
0
        if((ai4_pic_dist_in_cur_gop[I_PIC] > 1) && (ai4_pic_dist[0] == 1))
3602
0
        {
3603
0
            i4_flag_i_frame_exit = 1;
3604
0
        }
3605
0
        if(i4_flag_i_frame_exit && (i4_call_type == 1))
3606
0
        {
3607
0
            if(ai4_pic_dist_in_cur_gop[I_PIC] == 0)
3608
0
                memmove(ai4_pic_dist_in_cur_gop, num_frames_in_lap, sizeof(WORD32) * MAX_PIC_TYPE);
3609
3610
0
            rc_update_pic_distn_lap_to_rc(ps_rc_ctxt->rc_hdl, ai4_pic_dist_in_cur_gop);
3611
0
            rc_set_bits_based_on_complexity(
3612
0
                ps_rc_ctxt->rc_hdl, u4_L1_based_lap_complexity_q7, total_frms_considered);
3613
0
        }
3614
0
    }
3615
3616
0
    return i_to_rest_bit_ratio;
3617
0
}
3618
3619
/*##################################################*/
3620
/******* END OF I2AVG RATIO FUNCTIONS **************/
3621
/*################################################*/
3622
3623
/*#########################################################*/
3624
/******* START OF QSCALE CONVERSION FUNCTIONS *************/
3625
/*########################################################*/
3626
3627
/**
3628
******************************************************************************
3629
*
3630
*  @brief function to convert from qscale to qp
3631
*
3632
*  @par   Description
3633
*  @param[in]   i4_frame_qs_q3 : QP value in qscale
3634
*   return      frame qp
3635
******************************************************************************
3636
*/
3637
3638
WORD32 ihevce_rc_get_scaled_hevc_qp_from_qs_q3(WORD32 i4_frame_qs_q3, rc_quant_t *ps_rc_quant_ctxt)
3639
0
{
3640
0
    if(i4_frame_qs_q3 > ps_rc_quant_ctxt->i2_max_qscale)
3641
0
    {
3642
0
        i4_frame_qs_q3 = ps_rc_quant_ctxt->i2_max_qscale;
3643
0
    }
3644
0
    else if(i4_frame_qs_q3 < ps_rc_quant_ctxt->i2_min_qscale)
3645
0
    {
3646
0
        i4_frame_qs_q3 = ps_rc_quant_ctxt->i2_min_qscale;
3647
0
    }
3648
3649
0
    return (ps_rc_quant_ctxt->pi4_qscale_to_qp[i4_frame_qs_q3]);
3650
0
}
3651
3652
/**
3653
******************************************************************************
3654
*
3655
*  @brief function to convert from qp to qscale
3656
*
3657
*  @par   Description
3658
*  @param[in]   i4_frame_qp : QP value
3659
*   return      value in qscale
3660
******************************************************************************
3661
*/
3662
WORD32 ihevce_rc_get_scaled_mpeg2_qp(WORD32 i4_frame_qp, rc_quant_t *ps_rc_quant_ctxt)
3663
0
{
3664
    //i4_frame_qp = i4_frame_qp >> 3; // Q3 format is mantained for accuarate calc at lower qp
3665
0
    WORD32 i4_qscale;
3666
0
    if(i4_frame_qp > ps_rc_quant_ctxt->i2_max_qp)
3667
0
    {
3668
0
        i4_frame_qp = ps_rc_quant_ctxt->i2_max_qp;
3669
0
    }
3670
0
    else if(i4_frame_qp < ps_rc_quant_ctxt->i2_min_qp)
3671
0
    {
3672
0
        i4_frame_qp = ps_rc_quant_ctxt->i2_min_qp;
3673
0
    }
3674
3675
0
    i4_qscale = (ps_rc_quant_ctxt->pi4_qp_to_qscale[i4_frame_qp + ps_rc_quant_ctxt->i1_qp_offset] +
3676
0
                 (1 << (QSCALE_Q_FAC_3 - 1))) >>
3677
0
                QSCALE_Q_FAC_3;
3678
0
    return i4_qscale;
3679
0
}
3680
3681
/**
3682
******************************************************************************
3683
*
3684
*  @brief function to convert from qp to qscale
3685
*
3686
*  @par Description : This function maps logarithmic QP values to linear QP
3687
*   values. The linear values are represented in Q6 format.
3688
*
3689
*  @param[in]   i4_frame_qp : QP value (log scale)
3690
*
3691
*  @return value in QP (linear scale)
3692
*
3693
******************************************************************************
3694
*/
3695
WORD32 ihevce_rc_get_scaled_mpeg2_qp_q6(WORD32 i4_frame_qp, UWORD8 u1_bit_depth)
3696
0
{
3697
0
    WORD32 i4_frame_qp_q6;
3698
0
    number_t s_frame_qp;
3699
0
    float f_qp;
3700
3701
0
    (void)u1_bit_depth;
3702
0
    ASSERT(i4_frame_qp >= 0);
3703
0
    ASSERT(i4_frame_qp <= 51 + ((u1_bit_depth - 8) * 6));
3704
0
    f_qp = (float)pow((float)2, ((float)(i4_frame_qp - 4) / 6));
3705
0
    convert_float_to_fix(f_qp, &s_frame_qp);
3706
0
    convert_varq_to_fixq(s_frame_qp, &i4_frame_qp_q6, QSCALE_Q_FAC);
3707
3708
0
    if(i4_frame_qp_q6 < (1 << QSCALE_Q_FAC))
3709
0
        i4_frame_qp_q6 = 1 << QSCALE_Q_FAC;
3710
3711
0
    return i4_frame_qp_q6;
3712
0
}
3713
3714
/**
3715
******************************************************************************
3716
*
3717
*  @brief function to convert from qscale to qp
3718
*
3719
*  @par   Description
3720
*  @param[in]   i4_frame_qp_q6 : QP value in qscale. the input is assumed to be in q6 format
3721
*   return      frame qp
3722
******************************************************************************
3723
*/
3724
WORD32 ihevce_rc_get_scaled_hevce_qp_q6(WORD32 i4_frame_qp_q6, UWORD8 u1_bit_depth)
3725
0
{
3726
0
    WORD32 i4_hevce_qp;
3727
0
    number_t s_hevce_qp, s_temp;
3728
0
    float f_mpeg2_qp, f_hevce_qp;
3729
0
    f_mpeg2_qp = (float)i4_frame_qp_q6 / (1 << QSCALE_Q_FAC);
3730
0
    f_hevce_qp = (6 * ((float)log(f_mpeg2_qp) / (float)log((float)2))) + 4;
3731
0
    convert_float_to_fix(f_hevce_qp, &s_hevce_qp);
3732
3733
    /*rounf off to nearest integer*/
3734
0
    s_temp.sm = 1;
3735
0
    s_temp.e = 1;
3736
0
    add32_var_q(s_hevce_qp, s_temp, &s_hevce_qp);
3737
0
    number_t_to_word32(s_hevce_qp, &i4_hevce_qp);
3738
0
    if(i4_frame_qp_q6 == 0)
3739
0
    {
3740
0
        i4_hevce_qp = 0;
3741
0
    }
3742
3743
0
    i4_hevce_qp -= ((u1_bit_depth - 8) * 6);
3744
3745
0
    return i4_hevce_qp;
3746
0
}
3747
3748
/**
3749
******************************************************************************
3750
*
3751
*  @brief function to convert from qp scale to qp
3752
*
3753
*  @par Description : This function maps linear QP values to logarithimic QP
3754
*   values. The linear values are represented in Q3 format.
3755
*
3756
*  @param[in]   i4_frame_qp : QP value (linear scale, Q3 mode)
3757
*
3758
*  @return value in QP (log scale)
3759
*
3760
******************************************************************************
3761
*/
3762
WORD32 ihevce_rc_get_scaled_hevce_qp_q3(WORD32 i4_frame_qp, UWORD8 u1_bit_depth)
3763
0
{
3764
0
    WORD32 i4_hevce_qp;
3765
0
    number_t s_hevce_qp, s_temp;
3766
3767
0
    if(i4_frame_qp == 0)
3768
0
    {
3769
0
        i4_hevce_qp = 0;
3770
0
    }
3771
0
    else
3772
0
    {
3773
0
        float f_mpeg2_qp, f_hevce_qp;
3774
3775
0
        f_mpeg2_qp = (float)i4_frame_qp;
3776
0
        f_hevce_qp = (6 * ((float)log(f_mpeg2_qp) / (float)log((float)2) - 3)) + 4;
3777
0
        convert_float_to_fix(f_hevce_qp, &s_hevce_qp);
3778
3779
        /*rounf off to nearest integer*/
3780
0
        s_temp.sm = 1;
3781
0
        s_temp.e = 1;
3782
0
        add32_var_q(s_hevce_qp, s_temp, &s_hevce_qp);
3783
0
        number_t_to_word32(s_hevce_qp, &i4_hevce_qp);
3784
0
    }
3785
0
    i4_hevce_qp -= ((u1_bit_depth - 8) * 6);
3786
3787
0
    return i4_hevce_qp;
3788
0
}
3789
3790
/*#######################################################*/
3791
/******* END OF QSCALE CONVERSION FUNCTIONS *************/
3792
/*######################################################*/
3793
3794
/*###############################################*/
3795
/******* START OF SET,GET FUNCTIONS *************/
3796
/*#############################################*/
3797
3798
/**
3799
******************************************************************************
3800
*
3801
*  @brief Convert pic type to rc pic type
3802
*
3803
*  @par   Description
3804
*
3805
*
3806
*  @param[in]      pic_type
3807
*  Pic type
3808
*
3809
*  @return      rc_pic_type
3810
*
3811
******************************************************************************
3812
*/
3813
picture_type_e ihevce_rc_conv_pic_type(
3814
    IV_PICTURE_CODING_TYPE_T pic_type,
3815
    WORD32 i4_field_pic,
3816
    WORD32 i4_temporal_layer_id,
3817
    WORD32 i4_is_bottom_field,
3818
    WORD32 i4_top_field_first)
3819
0
{
3820
0
    picture_type_e rc_pic_type = (picture_type_e)pic_type;
3821
    /*interlaced pictype are not supported*/
3822
0
    if(pic_type > 9 && i4_temporal_layer_id > 3) /**/
3823
0
    {
3824
0
        DBG_PRINTF("unsupported picture type or temporal id\n");
3825
0
        exit(0);
3826
0
    }
3827
3828
0
    if(i4_field_pic == 0) /*Progressive Source*/
3829
0
    {
3830
0
        if(pic_type == IV_IDR_FRAME)
3831
0
        {
3832
0
            rc_pic_type = I_PIC;
3833
0
        }
3834
0
        else
3835
0
        {
3836
0
            rc_pic_type = (picture_type_e)pic_type;
3837
3838
            /*return different picture type based on temporal layer*/
3839
0
            if(i4_temporal_layer_id > 1)
3840
0
            {
3841
0
                rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3842
0
            }
3843
0
        }
3844
0
    }
3845
3846
0
    else if(i4_field_pic == 1)
3847
0
    {
3848
0
        if(pic_type == IV_IDR_FRAME || pic_type == IV_I_FRAME)
3849
0
        {
3850
0
            rc_pic_type = I_PIC;
3851
0
        }
3852
3853
0
        else if(i4_top_field_first == 1)
3854
0
        {
3855
0
            rc_pic_type = (picture_type_e)pic_type;
3856
3857
0
            if(i4_temporal_layer_id <= 1)
3858
3859
0
            {
3860
0
                if(i4_is_bottom_field == 1)
3861
0
                    rc_pic_type = (picture_type_e)(pic_type + 4);
3862
0
            }
3863
            /*return different picture type based on temporal layer*/
3864
0
            if(i4_temporal_layer_id > 1)
3865
0
            {
3866
0
                if(i4_is_bottom_field == 0)
3867
0
                    rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3868
0
                else
3869
0
                    rc_pic_type = (picture_type_e)(
3870
0
                        pic_type + (i4_temporal_layer_id - 1) +
3871
0
                        4); /*Offset of 4 for the bottomfield*/
3872
0
            }
3873
0
        }
3874
0
        else if(i4_top_field_first == 0)
3875
0
        {
3876
0
            rc_pic_type = (picture_type_e)pic_type;
3877
3878
0
            if(i4_temporal_layer_id <= 1)
3879
0
            {
3880
0
                if(i4_is_bottom_field == 1)
3881
0
                    rc_pic_type = (picture_type_e)(pic_type + 4);
3882
0
            }
3883
            /*return different picture type based on temporal layer*/
3884
0
            if(i4_temporal_layer_id > 1)
3885
0
            {
3886
0
                if(i4_is_bottom_field == 0)
3887
0
                    rc_pic_type = (picture_type_e)(pic_type + (i4_temporal_layer_id - 1));
3888
0
                else
3889
0
                    rc_pic_type = (picture_type_e)(
3890
0
                        pic_type + (i4_temporal_layer_id - 1) + 4); /*Offset of 4 for the topfield*/
3891
0
            }
3892
0
        }
3893
0
    }
3894
3895
0
    return rc_pic_type;
3896
0
}
3897
3898
/**
3899
******************************************************************************
3900
*
3901
*  @brief function to update current frame intra cost
3902
*
3903
*  @par   Description
3904
*  @param[inout] ps_rc_ctxt
3905
*  @param[in]    i8_cur_frm_intra_cost
3906
******************************************************************************
3907
*/
3908
void ihevce_rc_update_cur_frm_intra_satd(
3909
    void *pv_ctxt, LWORD64 i8_cur_frm_intra_cost, WORD32 i4_enc_frm_id)
3910
0
{
3911
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
3912
0
    ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id] = i8_cur_frm_intra_cost;
3913
0
}
3914
/**
3915
******************************************************************************
3916
*
3917
*  @brief function to return scene type
3918
*
3919
*  @par   Description
3920
*  @param[inout] ps_rc_lap_out
3921
*  @return       i4_rc_scene_type
3922
******************************************************************************
3923
*/
3924
/* Functions dependent on lap input*/
3925
WORD32 ihevce_rc_lap_get_scene_type(rc_lap_out_params_t *ps_rc_lap_out)
3926
0
{
3927
0
    return (WORD32)ps_rc_lap_out->i4_rc_scene_type;
3928
0
}
3929
3930
/**
3931
******************************************************************************
3932
*
3933
*  @name  ihevce_rc_get_pic_param
3934
*
3935
*  @par   Description
3936
*
3937
*  @param[in]   rc_pic_type
3938
*
3939
*  @return      void
3940
*
3941
******************************************************************************
3942
*/
3943
static void ihevce_rc_get_pic_param(
3944
    picture_type_e rc_pic_type, WORD32 *pi4_tem_lyr, WORD32 *pi4_is_bottom_field)
3945
0
{
3946
    /*bottom field determination*/
3947
0
    if(rc_pic_type >= P1_PIC)
3948
0
        *pi4_is_bottom_field = 1;
3949
0
    else
3950
0
        *pi4_is_bottom_field = 0;
3951
3952
    /*temporal lyr id determination*/
3953
0
    if(rc_pic_type == I_PIC || rc_pic_type == P_PIC || rc_pic_type == P1_PIC)
3954
0
    {
3955
0
        *pi4_tem_lyr = 0;
3956
0
    }
3957
0
    else if(rc_pic_type == B_PIC || rc_pic_type == BB_PIC)
3958
0
    {
3959
0
        *pi4_tem_lyr = 1;
3960
0
    }
3961
0
    else if(rc_pic_type == B1_PIC || rc_pic_type == B11_PIC)
3962
0
    {
3963
0
        *pi4_tem_lyr = 2;
3964
0
    }
3965
0
    else if(rc_pic_type == B2_PIC || rc_pic_type == B22_PIC)
3966
0
    {
3967
0
        *pi4_tem_lyr = 3;
3968
0
    }
3969
0
    else
3970
0
    {
3971
0
        ASSERT(0);
3972
0
    }
3973
0
}
3974
/**
3975
******************************************************************************
3976
*
3977
*  @name  ihevce_get_offline_index
3978
*
3979
*  @par   Description
3980
*
3981
*  @param[in]   ps_rc_ctxt  - pointer to rc context
3982
*
3983
*  @return      index
3984
*
3985
******************************************************************************
3986
*/
3987
static WORD32 ihevce_get_offline_index(rc_context_t *ps_rc_ctxt, WORD32 i4_num_pels_in_frame)
3988
0
{
3989
0
    WORD32 i4_rc_quality_preset = ps_rc_ctxt->i4_quality_preset;
3990
0
    WORD32 base = 1;
3991
0
    if(i4_num_pels_in_frame > 5000000) /*ultra HD*/
3992
0
    {
3993
0
        base = 0;
3994
0
    }
3995
0
    else if(i4_num_pels_in_frame > 1500000) /*Full HD*/
3996
0
    {
3997
0
        base = 5;
3998
0
    }
3999
0
    else if(i4_num_pels_in_frame > 600000) /*720p*/
4000
0
    {
4001
0
        base = 10;
4002
0
    }
4003
0
    else /*SD*/
4004
0
    {
4005
0
        base = 15;
4006
0
    }
4007
    /*based on preset choose coeff*/
4008
0
    if(i4_rc_quality_preset == IHEVCE_QUALITY_P0) /*Pristine quality*/
4009
0
    {
4010
0
        return base;
4011
0
    }
4012
0
    else if(i4_rc_quality_preset == IHEVCE_QUALITY_P2) /*High quality*/
4013
0
    {
4014
0
        return base + 1;
4015
0
    }
4016
0
    else if(
4017
0
        (i4_rc_quality_preset == IHEVCE_QUALITY_P5) ||
4018
0
        (i4_rc_quality_preset == IHEVCE_QUALITY_P6) ||
4019
0
        (i4_rc_quality_preset == IHEVCE_QUALITY_P7)) /*Extreme speed */
4020
0
    {
4021
0
        return base + 4;
4022
0
    }
4023
0
    else if(i4_rc_quality_preset == IHEVCE_QUALITY_P4) /*High speed */
4024
0
    {
4025
0
        return base + 3;
4026
0
    }
4027
0
    else if(i4_rc_quality_preset == IHEVCE_QUALITY_P3) /*default assume Medium speed*/
4028
0
    {
4029
0
        return base + 2;
4030
0
    }
4031
0
    else
4032
0
    {
4033
0
        ASSERT(0);
4034
0
    }
4035
0
    return base + 2;
4036
0
}
4037
4038
/**
4039
******************************************************************************
4040
*
4041
*  @name  ihevce_get_frame_lambda_modifier
4042
*
4043
*  @par   Description
4044
*
4045
*  @param[in]   pic_type
4046
*               i4_rc_temporal_lyr_id
4047
*  @param[in]   i4_first_field
4048
*  @param[in]   i4_rc_is_ref_pic
4049
*  @return      lambda_modifier
4050
*
4051
******************************************************************************
4052
*/
4053
static double ihevce_get_frame_lambda_modifier(
4054
    WORD8 pic_type,
4055
    WORD32 i4_rc_temporal_lyr_id,
4056
    WORD32 i4_first_field,
4057
    WORD32 i4_rc_is_ref_pic,
4058
    WORD32 i4_num_b_frms)
4059
0
{
4060
0
    double lambda_modifier;
4061
0
    WORD32 num_b_frms = i4_num_b_frms, first_field = i4_first_field;
4062
4063
0
    if(I_PIC == pic_type)
4064
0
    {
4065
0
        double temporal_correction_islice = 1.0 - 0.05 * num_b_frms;
4066
0
        temporal_correction_islice = MAX(0.5, temporal_correction_islice);
4067
4068
0
        lambda_modifier = 0.57 * temporal_correction_islice;
4069
0
    }
4070
0
    else if(P_PIC == pic_type)
4071
0
    {
4072
0
        if(first_field)
4073
0
            lambda_modifier = 0.442;  //0.442*0.8;
4074
0
        else
4075
0
            lambda_modifier = 0.442;
4076
4077
        //lambda_modifier *= pow(2.00,(double)(1.00/3.00));
4078
0
    }
4079
0
    else
4080
0
    {
4081
        /* BSLICE */
4082
0
        if(1 == i4_rc_is_ref_pic)
4083
0
        {
4084
0
            lambda_modifier = 0.3536;
4085
0
        }
4086
0
        else if(2 == i4_rc_is_ref_pic)
4087
0
        {
4088
0
            lambda_modifier = 0.45;
4089
0
        }
4090
0
        else
4091
0
        {
4092
0
            lambda_modifier = 0.68;
4093
0
        }
4094
4095
        /* TODO: Disable lambda modification for interlace encode to match HM runs */
4096
        //if(0 == ps_enc_ctxt->s_runtime_src_prms.i4_field_pic)
4097
0
        {
4098
            /* modify b lambda further based on temporal id */
4099
0
            if(i4_rc_temporal_lyr_id)
4100
0
            {
4101
0
                lambda_modifier *= 3.00;
4102
0
            }
4103
0
        }
4104
        //lambda_modifier *= pow(2.00,(double)((1.00/3.00) * (i4_rc_temporal_lyr_id + 1)));
4105
0
    }
4106
4107
    /* modify the base lambda according to lambda modifier */
4108
0
    lambda_modifier = sqrt(lambda_modifier);
4109
0
    return lambda_modifier;
4110
0
}
4111
4112
/*!
4113
******************************************************************************
4114
* \if Function name : get_avg_bitrate_bufsize
4115
*
4116
* \brief
4117
*
4118
* \param[in] *pv_ctxt -> rc context
4119
*
4120
* \return
4121
*
4122
* \author
4123
*  Ittiam
4124
*
4125
*****************************************************************************
4126
*/
4127
void get_avg_bitrate_bufsize(void *pv_ctxt, LWORD64 *pi8_bitrate, LWORD64 *pi8_ebf)
4128
0
{
4129
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4130
0
    *pi8_bitrate = rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
4131
0
    *pi8_ebf = rc_get_vbv_buf_size(ps_rc_ctxt->rc_hdl);
4132
0
}
4133
4134
/**
4135
******************************************************************************
4136
*
4137
*  @name  ihevce_get_dbf_buffer_size
4138
*
4139
*  @par   Description
4140
*
4141
*  @param[in]   ps_rc_ctxt  - pointer to rc context
4142
*
4143
*  @return      qp
4144
*
4145
******************************************************************************
4146
*/
4147
void ihevce_get_dbf_buffer_size(
4148
    void *pv_rc_ctxt, UWORD32 *pi4_buffer_size, UWORD32 *pi4_dbf, UWORD32 *pi4_bit_rate)
4149
0
{
4150
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4151
4152
0
    pi4_buffer_size[0] = (WORD32)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
4153
0
    pi4_dbf[0] = (WORD32)(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level);
4154
0
    ASSERT(
4155
0
        ps_rc_ctxt->s_vbv_compliance.f_buffer_size >=
4156
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level);
4157
4158
0
    pi4_bit_rate[0] = (WORD32)ps_rc_ctxt->s_vbv_compliance.f_bit_rate;
4159
0
}
4160
4161
/*!
4162
******************************************************************************
4163
* \if Function name : ihevce_set_L0_scd_qp
4164
*
4165
* \brief
4166
*
4167
* \param[in] *pv_ctxt -> rc context
4168
*
4169
* \return
4170
*
4171
* \author
4172
*  Ittiam
4173
*
4174
*****************************************************************************
4175
*/
4176
void ihevce_set_L0_scd_qp(void *pv_rc_ctxt, WORD32 i4_scd_qp)
4177
0
{
4178
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4179
4180
0
    ps_rc_ctxt->i4_L0_frame_qp = i4_scd_qp;
4181
0
}
4182
4183
/**
4184
******************************************************************************
4185
*
4186
*  @name  rc_get_buffer_level_unclip
4187
*
4188
*  @par   Description
4189
*
4190
*  @param[in]      pv_rc_ctxt
4191
*
4192
*
4193
*  @return      void
4194
*
4195
******************************************************************************
4196
*/
4197
float rc_get_buffer_level_unclip(void *pv_rc_ctxt)
4198
0
{
4199
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
4200
0
    return (ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip);
4201
0
}
4202
4203
/**
4204
******************************************************************************
4205
*
4206
*  @brief Clip QP based on min and max frame qp
4207
*
4208
*  @par   Description
4209
*
4210
*  @param[inout]   ps_rc_ctxt
4211
*  pointer to rc context
4212
*
4213
*  @param[in]      rc_pic_type
4214
*  Pic type
4215
*
4216
*  @return      i4_hevc_frame_qp
4217
*
4218
******************************************************************************
4219
*/
4220
static WORD32 ihevce_clip_min_max_qp(
4221
    rc_context_t *ps_rc_ctxt,
4222
    WORD32 i4_hevc_frame_qp,
4223
    picture_type_e rc_pic_type,
4224
    WORD32 i4_rc_temporal_lyr_id)
4225
0
{
4226
0
    ASSERT(i4_rc_temporal_lyr_id >= 0);
4227
    /**clip to min qp which is user configurable*/
4228
0
    if(rc_pic_type == I_PIC && i4_hevc_frame_qp < ps_rc_ctxt->i4_min_frame_qp)
4229
0
    {
4230
0
        i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp;
4231
0
    }
4232
0
    else if(rc_pic_type == P_PIC && i4_hevc_frame_qp < (ps_rc_ctxt->i4_min_frame_qp + 1))
4233
0
    {
4234
0
        i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp + 1;
4235
0
    }
4236
0
    else if(i4_hevc_frame_qp < (ps_rc_ctxt->i4_min_frame_qp + i4_rc_temporal_lyr_id + 1))
4237
0
    {
4238
        /** For B frame max qp is set based on temporal reference*/
4239
0
        i4_hevc_frame_qp = ps_rc_ctxt->i4_min_frame_qp + i4_rc_temporal_lyr_id + 1;
4240
0
    }
4241
    /* clip the Qp to MAX QP */
4242
0
    if(i4_hevc_frame_qp < ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qp)
4243
0
    {
4244
0
        i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_min_qp;
4245
0
    }
4246
    /**clip to max qp based on pic type*/
4247
0
    if(rc_pic_type == I_PIC && i4_hevc_frame_qp > ps_rc_ctxt->i4_max_frame_qp)
4248
0
    {
4249
0
        i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp;
4250
0
    }
4251
0
    else if(rc_pic_type == P_PIC && i4_hevc_frame_qp > (ps_rc_ctxt->i4_max_frame_qp + 1))
4252
0
    {
4253
0
        i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp + 1;
4254
0
    }
4255
0
    else if(i4_hevc_frame_qp > (ps_rc_ctxt->i4_max_frame_qp + i4_rc_temporal_lyr_id + 1))
4256
0
    {
4257
        /** For B frame max qp is set based on temporal reference*/
4258
0
        i4_hevc_frame_qp = ps_rc_ctxt->i4_max_frame_qp + i4_rc_temporal_lyr_id + 1;
4259
0
    }
4260
    /* clip the Qp to MAX QP */
4261
0
    if(i4_hevc_frame_qp > ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp)
4262
0
    {
4263
0
        i4_hevc_frame_qp = ps_rc_ctxt->ps_rc_quant_ctxt->i2_max_qp;
4264
0
    }
4265
0
    return i4_hevc_frame_qp;
4266
0
}
4267
4268
/*#############################################*/
4269
/******* END OF SET,GET FUNCTIONS *************/
4270
/*###########################################*/
4271
4272
/*#################################################*/
4273
/******* START OF RC UPDATE FUNCTIONS **************/
4274
/*#################################################*/
4275
4276
/**
4277
******************************************************************************
4278
*
4279
*  @brief updates the picture level information like bits consumed and
4280
*
4281
*  @par   Description
4282
*
4283
*  @param[inout]   ps_mem_tab
4284
*  pointer to memory descriptors table
4285
*
4286
*  @param[in]      ps_init_prms
4287
*  Create time static parameters
4288
*
4289
*  @return      void
4290
*
4291
******************************************************************************
4292
*/
4293
4294
void ihevce_rc_update_pic_info(
4295
    void *pv_ctxt,
4296
    UWORD32 u4_total_bits_consumed,
4297
    UWORD32 u4_total_header_bits,
4298
    UWORD32 u4_frame_sad,
4299
    UWORD32 u4_frame_intra_sad,
4300
    IV_PICTURE_CODING_TYPE_T pic_type,
4301
    WORD32 i4_avg_frame_hevc_qp,
4302
    WORD32 i4_suppress_bpic_update,
4303
    WORD32 *pi4_qp_normalized_8x8_cu_sum,
4304
    WORD32 *pi4_8x8_cu_sum,
4305
    LWORD64 *pi8_sad_by_qscale,
4306
    ihevce_lap_output_params_t *ps_lap_out,
4307
    rc_lap_out_params_t *ps_rc_lap_out,
4308
    WORD32 i4_buf_id,
4309
    UWORD32 u4_open_loop_intra_sad,
4310
    LWORD64 i8_total_ssd_frame,
4311
    WORD32 i4_enc_frm_id)
4312
0
{
4313
0
    LWORD64 a_mb_type_sad[2];
4314
0
    WORD32 a_mb_type_tex_bits[2];
4315
    /*dummy variables not used*/
4316
0
    WORD32 a_mb_in_type[2] = { 0, 0 };
4317
0
    LWORD64 a_mb_type_qp_q6[2] = { 0, 0 };
4318
    /*qp accumulation at */
4319
0
    WORD32 i4_avg_activity = 250;  //hardcoding to usual value
4320
0
    WORD32 i4_intra_cost, i4_avg_frame_qp_q6, i;
4321
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4322
0
    WORD32 i4_frame_complexity, i4_bits_to_be_stuffed = 0, i4_is_last_frm_period = 0;
4323
0
    picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
4324
0
        pic_type,
4325
0
        ps_rc_ctxt->i4_field_pic,
4326
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
4327
0
        ps_rc_lap_out->i4_is_bottom_field,
4328
0
        ps_rc_ctxt->i4_top_field_first);
4329
0
    frame_info_t s_frame_info;
4330
0
    WORD32 i4_ctr = -1, i4_i, i4_j;
4331
0
    WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
4332
4333
    /*update bit consumption. used only in rdopt*/
4334
    //ASSERT(ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[ps_rc_ctxt->i4_rdopt_bit_count] == -1);
4335
    //ASSERT(i4_buf_id>=0);
4336
0
    ps_rc_ctxt->ai4_rdopt_bit_consumption_estimate[ps_rc_ctxt->i4_rdopt_bit_count] =
4337
0
        u4_total_bits_consumed;
4338
0
    ps_rc_ctxt->ai4_rdopt_bit_consumption_buf_id[ps_rc_ctxt->i4_rdopt_bit_count] = i4_buf_id;
4339
0
    ps_rc_ctxt->i4_rdopt_bit_count =
4340
0
        (ps_rc_ctxt->i4_rdopt_bit_count + 1) % NUM_BUF_RDOPT_ENT_CORRECT;
4341
4342
0
    {
4343
0
        LWORD64 i8_texture_bits = u4_total_bits_consumed - u4_total_header_bits;
4344
0
        ps_rc_lap_out->i4_use_offline_model_2pass = 0;
4345
4346
        /*flag to guide whether 2nd pass can use offline model or not*/
4347
0
        if((abs(ps_rc_lap_out->i4_orig_rc_qp - i4_avg_frame_hevc_qp) < 2) &&
4348
0
           (i8_texture_bits <= (ps_rc_lap_out->i8_est_text_bits * 2.0f)) &&
4349
0
           (i8_texture_bits >= (ps_rc_lap_out->i8_est_text_bits * 0.5f)))
4350
4351
0
        {
4352
0
            ps_rc_lap_out->i4_use_offline_model_2pass = 1;
4353
0
        }
4354
0
    }
4355
    /*Counter of number of bit alloction periods*/
4356
0
    if(rc_pic_type == I_PIC)
4357
0
        ps_rc_ctxt
4358
0
            ->i8_num_bit_alloc_period++;  //Currently only I frame periods are considerd as bit allocation period (Ignoring non- I scd and complexity reset flag
4359
    /*initialze frame info*/
4360
0
    init_frame_info(&s_frame_info);
4361
0
    s_frame_info.i4_rc_hevc_qp = i4_avg_frame_hevc_qp;
4362
0
    s_frame_info.i4_num_entries++;
4363
0
    s_frame_info.i8_L1_me_sad = ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
4364
0
    s_frame_info.i8_L1_ipe_raw_sad = ps_rc_lap_out->i8_raw_pre_intra_sad;
4365
0
    s_frame_info.i4_num_entries++;
4366
0
    s_frame_info.i4_num_entries++;
4367
0
    s_frame_info.i8_L0_open_cost = (LWORD64)u4_open_loop_intra_sad;
4368
0
    s_frame_info.i4_num_entries++;
4369
4370
0
    if(rc_pic_type == I_PIC)
4371
0
        s_frame_info.i8_L1_me_or_ipe_raw_sad = ps_rc_lap_out->i8_raw_pre_intra_sad;
4372
0
    else
4373
0
        s_frame_info.i8_L1_me_or_ipe_raw_sad = ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
4374
0
    s_frame_info.i4_num_entries++;
4375
0
    s_frame_info.i4_poc = ps_rc_lap_out->i4_rc_poc;
4376
0
    s_frame_info.i4_num_entries++;
4377
0
    s_frame_info.i4_scene_type = ps_rc_lap_out->i4_rc_scene_type;
4378
0
    s_frame_info.i4_num_entries++;
4379
0
    s_frame_info.i4_non_i_scd = ps_rc_lap_out->i4_is_non_I_scd || ps_rc_lap_out->i4_is_I_only_scd;
4380
0
    s_frame_info.i4_num_entries++;
4381
0
    s_frame_info.i8_cl_sad = u4_frame_sad;
4382
0
    s_frame_info.i4_num_entries++;
4383
0
    s_frame_info.i8_header_bits = u4_total_header_bits;
4384
0
    s_frame_info.i4_num_entries++;
4385
0
    s_frame_info.i8_tex_bits = u4_total_bits_consumed - u4_total_header_bits;
4386
0
    s_frame_info.i4_num_entries++;
4387
0
    s_frame_info.e_pic_type = rc_pic_type;
4388
0
    s_frame_info.i4_num_entries++;
4389
0
    s_frame_info.i8_est_texture_bits = ps_rc_lap_out->i8_est_text_bits;
4390
0
    s_frame_info.i4_num_entries++;
4391
0
    s_frame_info.i4_lap_complexity_q7 = ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id];
4392
0
    s_frame_info.i4_num_entries++;
4393
0
    s_frame_info.i4_lap_f_sim = ps_rc_ctxt->ai4_lap_f_sim[i4_enc_frm_id];
4394
0
    s_frame_info.i4_num_entries++;
4395
0
    s_frame_info.i8_frame_acc_coarse_me_cost = ps_rc_lap_out->i8_frame_acc_coarse_me_cost;
4396
0
    s_frame_info.i4_num_entries++;
4397
0
    s_frame_info.i_to_avg_bit_ratio = ps_rc_ctxt->ai_to_avg_bit_ratio[i4_enc_frm_id];
4398
0
    s_frame_info.i4_num_entries++;
4399
0
    s_frame_info.i4_num_scd_in_lap_window = ps_rc_ctxt->ai4_num_scd_in_lap_window[i4_enc_frm_id];
4400
0
    s_frame_info.i4_num_entries++;
4401
0
    s_frame_info.i4_num_frames_b4_scd = ps_rc_ctxt->ai4_num_frames_b4_scd[i4_enc_frm_id];
4402
0
    s_frame_info.i4_num_entries++;
4403
0
    s_frame_info.i8_num_bit_alloc_period = ps_rc_ctxt->i8_num_bit_alloc_period;
4404
0
    s_frame_info.i4_num_entries++;
4405
0
    s_frame_info.i1_is_complexity_based_bits_reset =
4406
0
        (WORD8)ps_rc_lap_out->i4_is_cmplx_change_reset_bits;
4407
0
    s_frame_info.i4_num_entries++;
4408
    /*For the complexity based movement in 2nd pass*/
4409
0
    memmove(
4410
0
        (void *)s_frame_info.af_sum_weigh,
4411
0
        ps_rc_lap_out->ps_frame_info->af_sum_weigh,
4412
0
        sizeof(float) * MAX_PIC_TYPE * 3);
4413
0
    s_frame_info.i4_num_entries++;
4414
4415
    /*store frame qp to clip qp accordingly*/
4416
0
    if(ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated)
4417
0
    {
4418
0
        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type] = i4_avg_frame_hevc_qp;
4419
0
    }
4420
4421
0
    for(i4_i = 0; i4_i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i4_i++)
4422
0
    {
4423
0
        if(ps_rc_lap_out->u4_rc_scene_num == ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_i])
4424
0
        {
4425
0
            i4_ctr = i4_i;
4426
0
            break;
4427
0
        }
4428
0
    }
4429
0
    if(-1 == i4_ctr)
4430
0
    {
4431
0
        ps_rc_ctxt->i4_prev_qp_ctr++;
4432
0
        ps_rc_ctxt->i4_prev_qp_ctr = ps_rc_ctxt->i4_prev_qp_ctr % MAX_NON_REF_B_PICS_IN_QUEUE_SGI;
4433
0
        i4_ctr = ps_rc_ctxt->i4_prev_qp_ctr;
4434
0
        ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_ctr] = ps_rc_lap_out->u4_rc_scene_num;
4435
0
        for(i4_j = 0; i4_j < MAX_PIC_TYPE; i4_j++)
4436
0
        {
4437
0
            ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][i4_j] = 0;
4438
0
        }
4439
0
    }
4440
4441
0
    {
4442
0
        ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][rc_pic_type] =
4443
0
            i4_avg_frame_hevc_qp;
4444
0
    }
4445
0
    if(i4_scene_num < HALF_MAX_SCENE_ARRAY_QP)
4446
0
    {
4447
0
        WORD32 i4_i;
4448
0
        ps_rc_ctxt->ai4_scene_numbers[i4_scene_num + HALF_MAX_SCENE_ARRAY_QP] = 0;
4449
0
        for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
4450
0
            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num + HALF_MAX_SCENE_ARRAY_QP][i4_i] =
4451
0
                INIT_HEVCE_QP_RC;
4452
0
    }
4453
0
    else
4454
0
    {
4455
0
        WORD32 i4_i;
4456
0
        ps_rc_ctxt->ai4_scene_numbers[i4_scene_num - HALF_MAX_SCENE_ARRAY_QP] = 0;
4457
0
        for(i4_i = 0; i4_i < MAX_PIC_TYPE; i4_i++)
4458
0
            ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num - HALF_MAX_SCENE_ARRAY_QP][i4_i] =
4459
0
                INIT_HEVCE_QP_RC;
4460
0
    }
4461
4462
    /*update will have HEVC qp, convert it back to mpeg2 range qp for all internal calculations of RC*/
4463
4464
0
    i4_avg_frame_qp_q6 = ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor
4465
0
                             [i4_avg_frame_hevc_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
4466
4467
0
    if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4468
0
    {
4469
        /*TODO : Take care of precision of a_mb_type_sad*/
4470
0
        a_mb_type_sad[0] =
4471
0
            (((pi8_sad_by_qscale[1] * i4_avg_frame_qp_q6) +
4472
0
              (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4473
0
             (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));  //u4_frame_sad;
4474
4475
0
        a_mb_type_sad[1] =
4476
0
            (((pi8_sad_by_qscale[0] * i4_avg_frame_qp_q6) +
4477
0
              (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4478
0
             (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));
4479
0
        a_mb_type_tex_bits[0] =
4480
0
            u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4481
0
        a_mb_type_tex_bits[1] = 0;
4482
0
        a_mb_in_type[0] = (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 8;
4483
0
        a_mb_in_type[1] = 0;
4484
0
    }
4485
0
    else
4486
0
    {
4487
        /*TODO : Take care of precision of a_mb_type_sad*/
4488
0
        a_mb_type_sad[1] =
4489
0
            (((pi8_sad_by_qscale[0] * i4_avg_frame_qp_q6) +
4490
0
              (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4491
0
             (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));
4492
4493
0
        a_mb_type_tex_bits[0] =
4494
0
            u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4495
0
        a_mb_type_sad[0] =
4496
0
            (((pi8_sad_by_qscale[1] * i4_avg_frame_qp_q6) +
4497
0
              (((LWORD64)1) << (SAD_BY_QSCALE_Q + QSCALE_Q_FAC - 1))) >>
4498
0
             (SAD_BY_QSCALE_Q + QSCALE_Q_FAC));  //u4_frame_sad;
4499
0
        a_mb_type_tex_bits[1] =
4500
0
            u4_total_bits_consumed - u4_total_header_bits;  //(u4_total_bits_consumed >> 3);
4501
0
        a_mb_type_tex_bits[0] = 0;
4502
0
        a_mb_in_type[1] = (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 8;
4503
0
        a_mb_in_type[0] = 0;
4504
0
    }
4505
0
    ASSERT(a_mb_type_sad[0] >= 0);
4506
0
    ASSERT(a_mb_type_sad[1] >= 0);
4507
    /*THis calclates sum of Qps of all MBs as per the corresponding mb type*/
4508
    /*THis is different from a_mb_in_type,a_mb_type_sad and a_mb_type_tex_bits*/
4509
0
    a_mb_type_qp_q6[0] = ((LWORD64)i4_avg_frame_qp_q6) * a_mb_in_type[0];
4510
0
    a_mb_type_qp_q6[1] = ((LWORD64)i4_avg_frame_qp_q6) * a_mb_in_type[1];
4511
0
    {
4512
0
        WORD32 i4_avg_qp_q6_without_offset = 0, i4_hevc_qp_rc = i4_avg_frame_hevc_qp;
4513
0
        WORD32 i4_rc_pic_type_rc_for_offset = rc_pic_type;
4514
0
        if(i4_rc_pic_type_rc_for_offset > B2_PIC)
4515
0
            i4_rc_pic_type_rc_for_offset = i4_rc_pic_type_rc_for_offset - B2_PIC;
4516
0
        i4_hevc_qp_rc = i4_hevc_qp_rc - ps_rc_lap_out->ai4_offsets[i4_rc_pic_type_rc_for_offset] +
4517
0
                        ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset;
4518
4519
0
        i4_hevc_qp_rc =
4520
0
            CLIP3(i4_hevc_qp_rc, 1, MAX_HEVC_QP + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset);
4521
0
        i4_avg_qp_q6_without_offset =
4522
0
            ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor[i4_hevc_qp_rc];
4523
4524
        /*Store the HBD qscale with and without accounting for offset*/
4525
0
        s_frame_info.f_hbd_q_scale_without_offset =
4526
0
            (float)i4_avg_qp_q6_without_offset / (1 << QSCALE_Q_FAC);
4527
0
        s_frame_info.f_hbd_q_scale = (float)i4_avg_frame_qp_q6 / (1 << QSCALE_Q_FAC);
4528
0
        s_frame_info.i4_num_entries++;
4529
0
        s_frame_info.i4_num_entries++;
4530
4531
        /*Store the 8 bit qscale with and without accounting for offset*/
4532
        /*Can be useful for pre-enc stage*/
4533
0
        if(ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset != 0)
4534
0
        {
4535
0
            s_frame_info.f_8bit_q_scale_without_offset =
4536
0
                s_frame_info.f_hbd_q_scale_without_offset / (1 << (ps_rc_ctxt->u1_bit_depth - 8));
4537
0
            s_frame_info.f_8bit_q_scale =
4538
0
                s_frame_info.f_hbd_q_scale / (1 << (ps_rc_ctxt->u1_bit_depth - 8));
4539
0
        }
4540
0
        else
4541
0
        {
4542
0
            s_frame_info.f_8bit_q_scale_without_offset = s_frame_info.f_hbd_q_scale_without_offset;
4543
0
            s_frame_info.f_8bit_q_scale = s_frame_info.f_hbd_q_scale;
4544
0
        }
4545
0
        s_frame_info.i4_num_entries++;
4546
0
        s_frame_info.i4_num_entries++;
4547
0
    }
4548
4549
    /*making intra cost same as ssd as of now*/
4550
0
    i4_intra_cost = u4_frame_intra_sad;
4551
4552
    /* Handling bits stuffing and skips */
4553
0
    {
4554
0
        WORD32 i4_num_bits_to_prevent_vbv_underflow;
4555
0
        vbv_buf_status_e vbv_buffer_status;
4556
0
        vbv_buffer_status = get_buffer_status(
4557
0
            ps_rc_ctxt->rc_hdl,
4558
0
            u4_total_bits_consumed,
4559
0
            rc_pic_type,  //the picture type convention is different in buffer handling
4560
0
            &i4_num_bits_to_prevent_vbv_underflow);
4561
4562
0
        if(vbv_buffer_status == VBV_UNDERFLOW)
4563
0
        {
4564
0
        }
4565
0
        if(vbv_buffer_status == VBV_OVERFLOW)
4566
0
        {
4567
0
            i4_bits_to_be_stuffed =
4568
0
                get_bits_to_stuff(ps_rc_ctxt->rc_hdl, u4_total_bits_consumed, rc_pic_type);
4569
            //i4_bits_to_be_stuffed = 0;/*STORAGE_RC*/
4570
0
        }
4571
0
    }
4572
0
    {
4573
0
        WORD32 ai4_sad[MAX_PIC_TYPE], i4_valid_sad_entry = 0;
4574
0
        UWORD32 u4_avg_sad = 0;
4575
4576
        /*calculate frame complexity. Given same content frame complexity should not vary across I,P and Bpic. Hence frame complexity is calculated
4577
        based on average of all pic types SAD*/
4578
0
        if(rc_pic_type == I_PIC)
4579
0
        {
4580
0
            ai4_sad[I_PIC] = u4_frame_intra_sad;
4581
0
        }
4582
0
        else
4583
0
        {
4584
            /*call to get previous I-PIC sad*/
4585
0
            rc_get_sad(ps_rc_ctxt->rc_hdl, &ai4_sad[0]);
4586
0
        }
4587
4588
        /*since intra sad is not available for every frame use previous I pic intra frame SAD*/
4589
0
        rc_put_sad(ps_rc_ctxt->rc_hdl, ai4_sad[I_PIC], u4_frame_sad, rc_pic_type);
4590
0
        rc_get_sad(ps_rc_ctxt->rc_hdl, &ai4_sad[0]);
4591
        /*for first few frame valid SAD is not available. This will make sure invalid data is not used*/
4592
0
        if(ps_rc_ctxt->i4_field_pic == 0)
4593
0
        {
4594
0
            for(i = 0; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
4595
0
            {
4596
0
                if(ai4_sad[i] >= 0)
4597
0
                {
4598
0
                    u4_avg_sad += ai4_sad[i];
4599
0
                    i4_valid_sad_entry++;
4600
0
                }
4601
0
            }
4602
0
        }
4603
0
        else /*for field case*/
4604
0
        {
4605
0
            if(ai4_sad[0] >= 0)
4606
0
            {
4607
0
                u4_avg_sad += ai4_sad[0];
4608
0
                i4_valid_sad_entry++;
4609
0
            }
4610
4611
0
            for(i = 1; i < ps_rc_ctxt->i4_num_active_pic_type; i++)
4612
0
            {
4613
0
                if(ai4_sad[i] >= 0)
4614
0
                {
4615
0
                    u4_avg_sad += ai4_sad[i];
4616
0
                    i4_valid_sad_entry++;
4617
0
                }
4618
4619
0
                if(ai4_sad[i + FIELD_OFFSET] >= 0)
4620
0
                {
4621
0
                    u4_avg_sad += ai4_sad[i + FIELD_OFFSET];
4622
0
                    i4_valid_sad_entry++;
4623
0
                }
4624
0
            }
4625
0
        }
4626
4627
0
        if(i4_valid_sad_entry > 0)
4628
0
        {
4629
0
            i4_frame_complexity =
4630
0
                (u4_avg_sad) /
4631
0
                (i4_valid_sad_entry * (ps_rc_ctxt->i4_frame_width * ps_rc_ctxt->i4_frame_height));
4632
0
        }
4633
0
        else
4634
0
        {
4635
0
            i4_frame_complexity = 1;
4636
0
        }
4637
0
    }
4638
0
    ASSERT(i4_frame_complexity >= 0);
4639
    /*I_model only reset In case of fade-in and fade-out*/
4640
0
    if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
4641
0
    {
4642
0
        ASSERT(rc_pic_type == I_PIC);
4643
0
        rc_reset_pic_model(ps_rc_ctxt->rc_hdl, I_PIC);
4644
0
        ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 0;
4645
0
    }
4646
4647
    /*check if next picture is I frame, both scene cuts and I pictures are treated as end of period*/
4648
0
    {
4649
0
        if(ps_rc_lap_out->i4_rc_pic_type != -1 && ps_rc_lap_out->i4_rc_scene_type != -1)
4650
0
        {
4651
0
            if(ps_rc_ctxt->u4_intra_frame_interval != 1)
4652
0
            {
4653
                /*TBD: For second pass this should be only criteria, While merging to latest verison make sure non - I SCD is not considered as one of the condition*/
4654
0
                i4_is_last_frm_period = (WORD32)(
4655
0
                    ps_rc_lap_out->i4_next_pic_type == IV_IDR_FRAME ||
4656
0
                    ps_rc_lap_out->i4_next_pic_type == IV_I_FRAME);
4657
0
            }
4658
0
            else
4659
0
            {
4660
0
                i4_is_last_frm_period =
4661
0
                    (WORD32)(ps_rc_lap_out->i4_next_scene_type == SCENE_TYPE_SCENE_CUT);
4662
0
            }
4663
0
        }
4664
4665
        /*In two pass only I frame ending should be considered end of period, otherwise complexity changes should be allowed to reset model in CBR and VBR modes*/
4666
0
        if(ps_rc_ctxt->i4_rc_pass != 2)
4667
0
            i4_is_last_frm_period = i4_is_last_frm_period ||
4668
0
                                    ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id];
4669
0
    }
4670
4671
0
#if 1  //FRAME_PARALLEL_LVL //ELP_RC
4672
0
    ps_rc_ctxt->i4_est_text_bits_ctr_update_qp++;
4673
0
    ps_rc_ctxt->i4_est_text_bits_ctr_update_qp =
4674
0
        (ps_rc_ctxt->i4_est_text_bits_ctr_update_qp % (ps_rc_ctxt->i4_num_frame_parallel));
4675
0
#endif
4676
4677
0
    update_frame_level_info(
4678
0
        ps_rc_ctxt->rc_hdl,
4679
0
        rc_pic_type,
4680
0
        a_mb_type_sad,
4681
0
        u4_total_bits_consumed, /*total bits consumed by frame*/
4682
0
        u4_total_header_bits,
4683
0
        a_mb_type_tex_bits,
4684
0
        a_mb_type_qp_q6, /*sum of qp of all mb in frame, since no ctb level modulation*/
4685
0
        a_mb_in_type,
4686
0
        i4_avg_activity,
4687
0
        ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id], /*currenlty SCD is not enabled*/
4688
0
        0, /*not a pre encode skip*/
4689
0
        i4_intra_cost,
4690
0
        0,
4691
0
        ps_rc_lap_out
4692
0
            ->i4_ignore_for_rc_update, /*HEVC_hierarchy: do not supress update for non-ref B pic*/
4693
0
        i4_bits_to_be_stuffed,
4694
0
        (ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
4695
0
         ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
4696
0
         ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id]),
4697
0
        ps_rc_ctxt->ai4_lap_complexity_q7[i4_enc_frm_id],
4698
0
        i4_is_last_frm_period,
4699
0
        ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id],
4700
0
        &s_frame_info,
4701
0
        ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated,
4702
0
        ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset,
4703
0
        i4_scene_num,
4704
0
        ps_rc_ctxt->ai4_scene_numbers[i4_scene_num],
4705
0
        ps_rc_ctxt->i4_est_text_bits_ctr_update_qp);
4706
    /** reset flags valid for only one frame*/
4707
0
    ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id] = 0;
4708
0
    ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] = 0;
4709
0
    ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] = 0;
4710
0
    ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id] = 0;
4711
0
    ps_rc_ctxt->ai4_is_cmplx_change_reset_bits[i4_enc_frm_id] = 0;
4712
4713
0
    ps_rc_ctxt->i4_is_first_frame_encoded = 1;
4714
4715
    /** update the scene num for current frame*/
4716
0
    ps_rc_ctxt->au4_scene_num_temp_id[ps_rc_lap_out->i4_rc_temporal_lyr_id] =
4717
0
        ps_rc_lap_out->u4_rc_scene_num;
4718
4719
0
    if(ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id])
4720
0
    {
4721
        /*reset pre-enc SAD whenever SCD is detected so that it does not detect scene cut for other pictures*/
4722
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
4723
0
        {
4724
0
            ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
4725
0
        }
4726
0
    }
4727
4728
    /*remember i frame's cost metric to scale SAD of next of I frame*/
4729
0
    if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4730
0
    {
4731
0
        ps_rc_ctxt->i8_prev_i_frm_cost = ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4732
0
        ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4733
0
            ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4734
0
    }
4735
    /*for other picture types update hme cost*/
4736
0
    else
4737
0
    {
4738
0
        ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4739
0
            ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id];
4740
0
    }
4741
0
}
4742
/*!
4743
******************************************************************************
4744
* \if Function name : ihevce_rc_interface_update \endif
4745
*
4746
* \brief
4747
*   Updating rate control interface parameters after the query call.
4748
*
4749
* \param[in] Rate control interface context,
4750
*            Picture Type
4751
*            Lap out structure pointer
4752
*
4753
*
4754
* \return
4755
*    None
4756
*
4757
* \author Ittiam
4758
*  Ittiam
4759
*
4760
*****************************************************************************
4761
*/
4762
void ihevce_rc_interface_update(
4763
    void *pv_ctxt,
4764
    IV_PICTURE_CODING_TYPE_T pic_type,
4765
    rc_lap_out_params_t *ps_rc_lap_out,
4766
    WORD32 i4_avg_frame_hevc_qp,
4767
    WORD32 i4_enc_frm_id)
4768
0
{
4769
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4770
0
    picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
4771
0
        pic_type,
4772
0
        ps_rc_ctxt->i4_field_pic,
4773
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
4774
0
        ps_rc_lap_out->i4_is_bottom_field,
4775
0
        ps_rc_ctxt->i4_top_field_first);
4776
0
    WORD32 i;
4777
0
    WORD32 i4_avg_frame_qp_q6, i4_ctr = -1, i4_i, i4_j;
4778
0
    WORD32 i4_scene_num = ps_rc_lap_out->u4_rc_scene_num % MAX_SCENE_NUM;
4779
4780
    /*store frame qp to clip qp accordingly*/
4781
0
    if(ps_rc_lap_out->i4_is_rc_model_needs_to_be_updated)
4782
0
    {
4783
0
        WORD32 i4_i, i4_temp_i_qp, i4_temp_qp;
4784
0
        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][rc_pic_type] = i4_avg_frame_hevc_qp;
4785
0
        ps_rc_ctxt->ai4_scene_numbers[i4_scene_num]++;
4786
4787
0
        if(rc_pic_type < P1_PIC)
4788
0
            i4_temp_i_qp = i4_avg_frame_hevc_qp - rc_pic_type;
4789
0
        else
4790
0
            i4_temp_i_qp = i4_avg_frame_hevc_qp - rc_pic_type + 4;
4791
4792
0
        i4_temp_i_qp = ihevce_clip_min_max_qp(ps_rc_ctxt, i4_temp_i_qp, I_PIC, 0);
4793
4794
0
        if(ps_rc_ctxt->ai4_scene_numbers[i4_scene_num] == 1)
4795
0
        {
4796
0
            for(i4_i = 0; i4_i < 5; i4_i++)
4797
0
            {
4798
0
                if(ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i] == INIT_HEVCE_QP_RC)
4799
0
                {
4800
0
                    i4_temp_qp = i4_temp_i_qp + i4_i;
4801
0
                    i4_temp_qp = ihevce_clip_min_max_qp(
4802
0
                        ps_rc_ctxt, i4_temp_qp, (picture_type_e)i4_i, MAX(i4_i - 1, 0));
4803
0
                    ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i] = i4_temp_qp;
4804
4805
0
                    if(i4_i > 0)
4806
0
                        ps_rc_ctxt->ai4_prev_pic_hevc_qp[i4_scene_num][i4_i + 4] = i4_temp_qp;
4807
0
                }
4808
0
            }
4809
0
        }
4810
0
    }
4811
4812
0
    for(i4_i = 0; i4_i < MAX_NON_REF_B_PICS_IN_QUEUE_SGI; i4_i++)
4813
0
    {
4814
0
        if(ps_rc_lap_out->u4_rc_scene_num == ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_i])
4815
0
        {
4816
0
            i4_ctr = i4_i;
4817
0
            break;
4818
0
        }
4819
0
    }
4820
0
    if(-1 == i4_ctr)
4821
0
    {
4822
0
        ps_rc_ctxt->i4_prev_qp_ctr++;
4823
0
        ps_rc_ctxt->i4_prev_qp_ctr = ps_rc_ctxt->i4_prev_qp_ctr % MAX_NON_REF_B_PICS_IN_QUEUE_SGI;
4824
0
        i4_ctr = ps_rc_ctxt->i4_prev_qp_ctr;
4825
0
        ps_rc_ctxt->au4_prev_scene_num_multi_scene[i4_ctr] = ps_rc_lap_out->u4_rc_scene_num;
4826
0
        for(i4_j = 0; i4_j < MAX_PIC_TYPE; i4_j++)
4827
0
        {
4828
0
            ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][i4_j] = 0;
4829
0
        }
4830
0
    }
4831
4832
0
    {
4833
0
        ps_rc_ctxt->ai4_qp_for_previous_scene_multi_scene[i4_ctr][rc_pic_type] =
4834
0
            i4_avg_frame_hevc_qp;
4835
0
    }
4836
4837
    /*I_model only reset In case of fade-in and fade-out*/
4838
0
    if(ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id])
4839
0
    {
4840
0
        ASSERT(rc_pic_type == I_PIC);
4841
0
        rc_reset_pic_model(ps_rc_ctxt->rc_hdl, I_PIC);
4842
0
        ps_rc_ctxt->ai4_I_model_only_reset[i4_enc_frm_id] = 0;
4843
0
    }
4844
4845
0
    i4_avg_frame_qp_q6 = ps_rc_ctxt->ps_rc_quant_ctxt->pi4_qp_to_qscale_q_factor
4846
0
                             [i4_avg_frame_hevc_qp + ps_rc_ctxt->ps_rc_quant_ctxt->i1_qp_offset];
4847
4848
0
    update_frame_rc_get_frame_qp_info(
4849
0
        ps_rc_ctxt->rc_hdl,
4850
0
        rc_pic_type,
4851
0
        ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id],
4852
0
        (ps_rc_ctxt->ai4_is_pause_to_resume[i4_enc_frm_id] ||
4853
0
         ps_rc_ctxt->ai4_is_non_I_scd_pic[i4_enc_frm_id] ||
4854
0
         ps_rc_ctxt->ai4_is_cmplx_change_reset_model[i4_enc_frm_id]),
4855
0
        i4_avg_frame_qp_q6,
4856
0
        ps_rc_lap_out->i4_ignore_for_rc_update,
4857
0
        i4_scene_num,
4858
0
        ps_rc_ctxt->ai4_scene_numbers[i4_scene_num]);
4859
4860
    /** update the scene num for current frame*/
4861
0
    ps_rc_ctxt->au4_scene_num_temp_id[ps_rc_lap_out->i4_rc_temporal_lyr_id] =
4862
0
        ps_rc_lap_out->u4_rc_scene_num;
4863
4864
0
    if(ps_rc_ctxt->ai4_is_frame_scd[i4_enc_frm_id])
4865
0
    {
4866
        /*reset pre-enc SAD whenever SCD is detected so that it does not detect scene cut for other pictures*/
4867
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
4868
0
        {
4869
0
            ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[i] = -1;
4870
0
        }
4871
0
    }
4872
4873
    /*remember i frame's cost metric to scale SAD of next of I frame*/
4874
0
    if(pic_type == IV_I_FRAME || pic_type == IV_IDR_FRAME)
4875
0
    {
4876
0
        ps_rc_ctxt->i8_prev_i_frm_cost = ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4877
0
        ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4878
0
            ps_rc_ctxt->ai8_cur_frm_intra_cost[i4_enc_frm_id];
4879
0
    }
4880
    /*for other picture types update hme cost*/
4881
0
    else
4882
0
    {
4883
0
        ps_rc_ctxt->ai8_prev_frm_pre_enc_cost[rc_pic_type] =
4884
0
            ps_rc_ctxt->ai8_cur_frame_coarse_ME_cost[i4_enc_frm_id];
4885
0
    }
4886
4887
0
    ps_rc_ctxt->i4_is_first_frame_encoded = 1;
4888
0
}
4889
4890
/****************************************************************************
4891
Function Name : ihevce_rc_store_retrive_update_info
4892
Description   : for storing and retrieving the data in case of the Enc Loop Parallelism.
4893
Inputs        :
4894
Globals       :
4895
Processing    :
4896
Outputs       :
4897
Returns       :
4898
Issues        :
4899
Revision History:
4900
DD MM YYYY   Author(s)       Changes (Describe the changes made)
4901
*****************************************************************************/
4902
4903
void ihevce_rc_store_retrive_update_info(
4904
    void *pv_ctxt,
4905
    rc_bits_sad_t *ps_rc_frame_stat,
4906
    WORD32 i4_enc_frm_id_rc,
4907
    WORD32 bit_rate_id,
4908
    WORD32 i4_store_retrive,
4909
    WORD32 *pout_buf_id,
4910
    WORD32 *pi4_rc_pic_type,
4911
    WORD32 *pcur_qp,
4912
    void *ps_lap_out,
4913
    void *ps_rc_lap_out)
4914
0
{
4915
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
4916
0
    if(1 == i4_store_retrive)
4917
0
    {
4918
0
        memcpy(
4919
0
            &ps_rc_ctxt->as_rc_frame_stat_store[i4_enc_frm_id_rc][bit_rate_id],
4920
0
            ps_rc_frame_stat,
4921
0
            sizeof(rc_bits_sad_t));
4922
0
        memcpy(&ps_rc_ctxt->out_buf_id[i4_enc_frm_id_rc][bit_rate_id], pout_buf_id, sizeof(WORD32));
4923
0
        memcpy(&ps_rc_ctxt->i4_pic_type[i4_enc_frm_id_rc], pi4_rc_pic_type, sizeof(WORD32));
4924
0
        memcpy(&ps_rc_ctxt->cur_qp[i4_enc_frm_id_rc][bit_rate_id], pcur_qp, sizeof(WORD32));
4925
0
        memcpy(
4926
0
            &ps_rc_ctxt->as_lap_out[i4_enc_frm_id_rc],
4927
0
            ps_lap_out,
4928
0
            sizeof(ihevce_lap_output_params_t));
4929
0
        memcpy(
4930
0
            &ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc],
4931
0
            ps_rc_lap_out,
4932
0
            sizeof(rc_lap_out_params_t));
4933
4934
0
        {
4935
0
            rc_lap_out_params_t *ps_rc_lap_out_curr = (rc_lap_out_params_t *)ps_rc_lap_out;
4936
0
            rc_lap_out_params_t *ps_rc_lap_out_next_encode =
4937
0
                (rc_lap_out_params_t *)ps_rc_lap_out_curr->ps_rc_lap_out_next_encode;
4938
4939
0
            if(NULL != ps_rc_lap_out_next_encode)
4940
0
            {
4941
0
                ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type =
4942
0
                    ps_rc_lap_out_next_encode->i4_rc_pic_type;
4943
0
                ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_scene_type =
4944
0
                    ps_rc_lap_out_next_encode->i4_rc_scene_type;
4945
0
            }
4946
0
            else
4947
0
            {
4948
0
                if(ps_rc_ctxt->u4_intra_frame_interval <= 1 ||
4949
0
                   (ps_rc_lap_out_curr->i4_rc_display_num &&
4950
0
                    (ps_rc_lap_out_curr->i4_rc_display_num %
4951
0
                     (ps_rc_ctxt->u4_intra_frame_interval - 1)) == 0))
4952
0
                {
4953
0
                    ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type = IV_I_FRAME;
4954
0
                }
4955
0
                else
4956
0
                {
4957
0
                    ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_pic_type = -1;
4958
0
                }
4959
0
                ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].i4_next_scene_type = -1;
4960
0
            }
4961
0
            ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc].ps_rc_lap_out_next_encode = NULL;
4962
0
        }
4963
0
    }
4964
0
    else if(2 == i4_store_retrive)
4965
0
    {
4966
0
        memcpy(
4967
0
            ps_rc_frame_stat,
4968
0
            &ps_rc_ctxt->as_rc_frame_stat_store[i4_enc_frm_id_rc][bit_rate_id],
4969
0
            sizeof(rc_bits_sad_t));
4970
0
        memcpy(pout_buf_id, &ps_rc_ctxt->out_buf_id[i4_enc_frm_id_rc][bit_rate_id], sizeof(WORD32));
4971
0
        memcpy(pi4_rc_pic_type, &ps_rc_ctxt->i4_pic_type[i4_enc_frm_id_rc], sizeof(WORD32));
4972
0
        memcpy(pcur_qp, &ps_rc_ctxt->cur_qp[i4_enc_frm_id_rc][bit_rate_id], sizeof(WORD32));
4973
0
        memcpy(
4974
0
            ps_lap_out,
4975
0
            &ps_rc_ctxt->as_lap_out[i4_enc_frm_id_rc],
4976
0
            sizeof(ihevce_lap_output_params_t));
4977
0
        memcpy(
4978
0
            ps_rc_lap_out,
4979
0
            &ps_rc_ctxt->as_rc_lap_out[i4_enc_frm_id_rc],
4980
0
            sizeof(rc_lap_out_params_t));
4981
0
    }
4982
0
    else
4983
0
    {
4984
0
        ASSERT(0);
4985
0
    }
4986
0
}
4987
4988
/*###############################################*/
4989
/******* END OF RC UPDATE FUNCTIONS **************/
4990
/*###############################################*/
4991
4992
/*#################################################*/
4993
/******* START OF RC UTILS FUNCTIONS **************/
4994
/*#################################################*/
4995
4996
/**
4997
******************************************************************************
4998
*
4999
*  @brief function to account for error correction between bits rdopt estimate
5000
*           and actual entropy bit generation
5001
*
5002
*  @par   Description
5003
*
5004
*  @param[in]   pv_rc_ctxt
5005
*               void pointer to rc ctxt
5006
*  @param[in]   i4_rdopt_bits_gen_error
5007
*               WODd32 variable with error correction between rdopt and entropy bytes gen
5008
*
5009
*  @return      void
5010
*
5011
******************************************************************************
5012
*/
5013
5014
void ihevce_rc_rdopt_entropy_bit_correct(
5015
    void *pv_rc_ctxt, WORD32 i4_cur_entropy_consumption, WORD32 i4_buf_id)
5016
0
{
5017
0
    rc_context_t *ps_ctxt = (rc_context_t *)pv_rc_ctxt;
5018
0
    WORD32 i4_error;
5019
0
    WORD32 i, count = 0;
5020
0
    ASSERT(i4_buf_id >= 0);
5021
0
    ps_ctxt->ai4_entropy_bit_consumption[ps_ctxt->i4_entropy_bit_count] =
5022
0
        i4_cur_entropy_consumption;
5023
0
    ps_ctxt->ai4_entropy_bit_consumption_buf_id[ps_ctxt->i4_entropy_bit_count] = i4_buf_id;
5024
0
    ps_ctxt->i4_entropy_bit_count = (ps_ctxt->i4_entropy_bit_count + 1) % NUM_BUF_RDOPT_ENT_CORRECT;
5025
5026
0
    for(i = 0; i < NUM_BUF_RDOPT_ENT_CORRECT; i++)
5027
0
    {
5028
0
        if(ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] >= 0 &&
5029
0
           (ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] ==
5030
0
            ps_ctxt->ai4_entropy_bit_consumption_buf_id[i]))
5031
0
        {
5032
0
            i4_error = ps_ctxt->ai4_rdopt_bit_consumption_estimate[i] -
5033
0
                       ps_ctxt->ai4_entropy_bit_consumption[i];
5034
            //DBG_PRINTF("entropy mismatch error = %d\n",i4_error/ps_ctxt->ai4_rdopt_bit_consumption_estimate[i]);
5035
0
            ps_ctxt->ai4_rdopt_bit_consumption_estimate[i] = -1;
5036
0
            ps_ctxt->ai4_rdopt_bit_consumption_buf_id[i] = -1;
5037
0
            ps_ctxt->ai4_entropy_bit_consumption[i] = -1;
5038
0
            ps_ctxt->ai4_entropy_bit_consumption_buf_id[i] = -1;
5039
            /*accumulate mismatch along with gop level bit error that is propogated to next frame*/
5040
            /*error = rdopt - entropy so it is expected to be negative*/
5041
0
            rc_update_mismatch_error(ps_ctxt->rc_hdl, i4_error);
5042
0
            count++;
5043
0
        }
5044
0
    }
5045
0
}
5046
5047
/**
5048
******************************************************************************
5049
*
5050
*  @name  ihevce_rc_check_non_lap_scd
5051
*
5052
*  @par   Description Detects SCD frames as I_only_scds or non_I_scds based
5053
                      on intrasatd & ME costs. Updates scd flags
5054
*
5055
*  @param[in]   ps_rc_ctxt  - pointer to rc context
5056
*               ps_rc_lap_out
5057
*  @return      void
5058
*
5059
******************************************************************************
5060
*/
5061
void ihevce_rc_check_non_lap_scd(void *pv_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out)
5062
0
{
5063
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5064
0
    picture_type_e rc_pic_type = ihevce_rc_conv_pic_type(
5065
0
        (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
5066
0
        ps_rc_ctxt->i4_field_pic,
5067
0
        ps_rc_lap_out->i4_rc_temporal_lyr_id,
5068
0
        ps_rc_lap_out->i4_is_bottom_field,
5069
0
        ps_rc_ctxt->i4_top_field_first);
5070
5071
    /*Init to normal frames*/
5072
0
    ps_rc_lap_out->i4_is_I_only_scd = 0;
5073
0
    ps_rc_lap_out->i4_is_non_I_scd = 0;
5074
5075
    /*None of the above check is valid if marked as scene cut*/
5076
0
    if(ps_rc_lap_out->i4_rc_scene_type == SCENE_TYPE_SCENE_CUT)
5077
0
    {
5078
0
        WORD32 i;
5079
        /*reset all older data*/
5080
0
        for(i = 0; i < MAX_PIC_TYPE; i++)
5081
0
        {
5082
0
            ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[i] = -1;
5083
0
            ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[i] = -1;
5084
0
            ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[i] = -1;
5085
0
        }
5086
0
    }
5087
0
    else
5088
0
    {
5089
        /*Check if it is I only reset case, lap_out is assumed to have latest data which is used to set the corresponding flags*/
5090
        /*For I pic check for I only reset case and for other pictures check for non-I scd case*/
5091
0
        if(rc_pic_type == I_PIC)
5092
0
        {
5093
0
            if(ps_rc_lap_out->i8_pre_intra_satd <
5094
0
                   (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] >> 1) ||
5095
0
               ps_rc_lap_out->i8_pre_intra_satd >
5096
0
                   (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] << 1))
5097
0
            {
5098
                /*Check if atleast one frame data is available*/
5099
0
                if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] >= 0)
5100
0
                    ps_rc_lap_out->i4_is_I_only_scd = 1;
5101
0
            }
5102
0
        }
5103
0
        else if(
5104
0
            ((rc_pic_type == P_PIC) &&
5105
0
             (ps_rc_lap_out->i4_rc_quality_preset == IHEVCE_QUALITY_P6)) ||
5106
0
            (ps_rc_lap_out->i4_rc_quality_preset < IHEVCE_QUALITY_P6))
5107
0
        {
5108
0
#define SAD_THREASHOLD_30FPS (2.5)
5109
            /*Choose threshold as 2.5 for 30 fps content and 1.75 for 60 fps. Scale accordingly for intermediate framerate*/
5110
0
            WORD32 i4_non_simple_repeat_prev_frame_detect = 0;
5111
0
            float sad_change_threshold =
5112
0
                (float)(-0.8f * ((float)ps_rc_ctxt->u4_max_frame_rate / 30000) + 3.05f); /*Change of SAD threshold for 30 fps content, this should be lowered for 60 fps*/
5113
0
            if(sad_change_threshold < 1.5f)
5114
0
                sad_change_threshold = 1.5f;
5115
0
            if(sad_change_threshold > 3.0f)
5116
0
                sad_change_threshold = 3.0f;
5117
0
            ASSERT(ps_rc_lap_out->i8_raw_l1_coarse_me_sad >= 0);
5118
5119
            /*block variance computed at 4x4 level in w/4*h/4,
5120
                percent dc blks is how many block's variance are less than or equal to 16*/
5121
0
            if(ps_rc_lap_out->i4_perc_dc_blks < 85)
5122
0
            {
5123
                /*me sad is expected to be zero for repeat frames*/
5124
0
                if((ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[rc_pic_type] ==
5125
0
                    0) &&
5126
0
                   (ps_rc_lap_out->i4_rc_temporal_lyr_id == ps_rc_ctxt->i4_max_temporal_lyr))
5127
0
                {
5128
0
                    i4_non_simple_repeat_prev_frame_detect = 1;
5129
0
                }
5130
0
            }
5131
0
            if(ps_rc_lap_out->i8_frame_acc_coarse_me_cost >
5132
0
                   (sad_change_threshold *
5133
0
                    ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type]) &&
5134
0
               (ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] >= 0) &&
5135
0
               (!i4_non_simple_repeat_prev_frame_detect))
5136
0
            {
5137
0
                WORD32 one_per_pixel_sad_L1;
5138
                /*per pixel sad has to be greater than 1 to avoid repeat frames influence non-I scd detection*/
5139
0
                if((ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) < 4000000)
5140
0
                {
5141
                    /*1080*/
5142
0
                    one_per_pixel_sad_L1 =
5143
0
                        (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 2;
5144
0
                }
5145
0
                else
5146
0
                {
5147
                    /*4k*/
5148
0
                    one_per_pixel_sad_L1 =
5149
0
                        (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width) >> 4;
5150
0
                }
5151
0
                if(ps_rc_lap_out->i8_frame_acc_coarse_me_cost > one_per_pixel_sad_L1)
5152
0
                {
5153
0
                    {
5154
0
                        ps_rc_lap_out->i4_is_non_I_scd = 1;
5155
0
                    }
5156
0
                }
5157
0
            }
5158
5159
0
            if(rc_pic_type == P_PIC)
5160
0
            {
5161
0
                if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] < 0)
5162
0
                {
5163
0
                    if(ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[I_PIC] > 0)
5164
0
                    {
5165
0
                        if(ps_rc_lap_out->i8_pre_intra_satd >
5166
0
                           ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[I_PIC] << 1)
5167
0
                        {
5168
0
                            ps_rc_lap_out->i4_is_non_I_scd = 1;
5169
0
                        }
5170
0
                    }
5171
0
                }
5172
0
            }
5173
0
        }
5174
0
    }
5175
5176
    /*remember the previous frame stats*/
5177
0
    ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_I_intra_raw_satd[rc_pic_type] =
5178
0
        ps_rc_lap_out->i8_pre_intra_satd;  //ps_rc_lap_out->i8_pre_intra_satd;
5179
0
    ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_cost[rc_pic_type] =
5180
0
        ps_rc_lap_out->i8_frame_acc_coarse_me_cost;  //ps_rc_lap_out->i8_frame_acc_coarse_me_sad;
5181
0
    ps_rc_ctxt->s_l1_state_metric.ai8_L1_prev_pic_coarse_me_sad[rc_pic_type] =
5182
0
        ps_rc_lap_out->i8_raw_l1_coarse_me_sad;
5183
0
}
5184
5185
/**
5186
******************************************************************************
5187
*
5188
*  @name  ihevce_rc_check_is_pre_enc_qp_valid
5189
*
5190
*  @par   Description  checking whether enc thread has updated qp in reverse queue
5191
*
5192
*  @param[in]   ps_rc_ctxt  - pointer to rc context
5193
*
5194
*  @return      zero on success
5195
*
5196
******************************************************************************
5197
*/
5198
/**only function accessed by encoder without using mutex lock*/
5199
WORD32 ihevce_rc_check_is_pre_enc_qp_valid(void *pv_rc_ctxt, volatile WORD32 *pi4_force_end_flag)
5200
0
{
5201
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5202
5203
0
    volatile WORD32 i4_is_qp_valid;
5204
0
    volatile WORD32 *pi4_is_qp_valid;
5205
5206
0
    pi4_is_qp_valid =
5207
0
        (volatile WORD32 *)&ps_rc_ctxt->as_pre_enc_qp_queue[ps_rc_ctxt->i4_pre_enc_qp_read_index]
5208
0
            .i4_is_qp_valid;
5209
0
    i4_is_qp_valid = *pi4_is_qp_valid;
5210
5211
    /*Due to stagger between L1 IPE and L0 IPE, towards the end (when encoder is in flush mode) L0 IPE can race ahead of enc
5212
    since it will suddenly get stagger between L1 and L0 worth of free buffers. It could try to start L0 even before enc has
5213
    populated qp for such frames. qp = -1 is returned in such case which implies encoder should wait for qp to be pop*/
5214
5215
0
    while(i4_is_qp_valid == -1)
5216
0
    {
5217
        /*this rate control call is outside mutex lock to avoid deadlock. If this acquires mutex lock enc will not be able to
5218
        populate qp*/
5219
0
        i4_is_qp_valid = *pi4_is_qp_valid;
5220
5221
0
        if(1 == (*pi4_force_end_flag))
5222
0
        {
5223
0
            *pi4_is_qp_valid = 1;
5224
0
            i4_is_qp_valid = 1;
5225
0
        }
5226
0
    }
5227
0
    return 0;
5228
0
}
5229
5230
/*!
5231
******************************************************************************
5232
* \if Function name : ihevce_compute_temporal_complexity_reset_Kp_Kb
5233
*
5234
* \brief
5235
*
5236
* \param[in] *pv_ctxt -> rc context
5237
*
5238
* \return
5239
*
5240
* \author
5241
*  Ittiam
5242
*
5243
*****************************************************************************
5244
*/
5245
void ihevce_compute_temporal_complexity_reset_Kp_Kb(
5246
    rc_lap_out_params_t *ps_rc_lap_out, void *pv_rc_ctxt, WORD32 i4_Kp_Kb_reset_flag)
5247
0
{
5248
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5249
0
    rc_lap_out_params_t *ps_cur_rc_lap_out_temporal_offset,
5250
0
        *ps_cur_rc_lap_out_temporal_offset_scd_detect;
5251
0
    picture_type_e curr_rc_pic_type;
5252
0
    LWORD64 i8_total_acc_coarse_me_sad = 0, i8_avg_acc_coarse_me_sad = 0;
5253
0
    WORD8 i1_num_frames_in_Sub_GOP = 0, i = 0, i1_no_reset = 0;
5254
0
    WORD32 i4_inter_frame_interval = rc_get_inter_frame_interval(ps_rc_ctxt->rc_hdl);
5255
0
    WORD32 i4_frame_qp = 0, i4_temp_frame_qp = 0;
5256
0
    WORD32 ai4_offsets[5] = { -3, -2, 2, 6, 7 };
5257
0
    ps_cur_rc_lap_out_temporal_offset = ps_rc_lap_out;
5258
0
    ps_cur_rc_lap_out_temporal_offset_scd_detect = ps_rc_lap_out;
5259
5260
0
    curr_rc_pic_type = ihevce_rc_conv_pic_type(
5261
0
        (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5262
0
        ps_rc_ctxt->i4_field_pic,
5263
0
        ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5264
0
        ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5265
0
        ps_rc_ctxt->i4_top_field_first);
5266
5267
0
    if(curr_rc_pic_type == I_PIC)
5268
0
    {
5269
0
        ps_cur_rc_lap_out_temporal_offset_scd_detect =
5270
0
            (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5271
0
        ps_cur_rc_lap_out_temporal_offset =
5272
0
            (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5273
5274
0
        if(NULL != ps_cur_rc_lap_out_temporal_offset)
5275
0
        {
5276
0
            curr_rc_pic_type = ihevce_rc_conv_pic_type(
5277
0
                (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5278
0
                ps_rc_ctxt->i4_field_pic,
5279
0
                ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5280
0
                ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5281
0
                ps_rc_ctxt->i4_top_field_first);
5282
0
        }
5283
0
        else
5284
0
            return;
5285
0
    }
5286
5287
0
    if(ps_cur_rc_lap_out_temporal_offset->i4_L1_qp == -1)
5288
0
        return;
5289
5290
0
    if(ps_cur_rc_lap_out_temporal_offset->i4_L0_qp == -1)
5291
0
        i4_frame_qp = ps_cur_rc_lap_out_temporal_offset->i4_L1_qp;
5292
0
    else
5293
0
        i4_frame_qp = ps_cur_rc_lap_out_temporal_offset->i4_L0_qp;
5294
5295
0
    i1_num_frames_in_Sub_GOP = 0;
5296
0
    i = 0;
5297
5298
0
    i1_no_reset = 0;
5299
0
    do
5300
0
    {
5301
0
        if(ps_cur_rc_lap_out_temporal_offset != NULL)
5302
0
        {
5303
0
            if(curr_rc_pic_type != I_PIC)
5304
0
                i4_temp_frame_qp =
5305
0
                    i4_frame_qp + ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id + 1;
5306
5307
0
            i4_temp_frame_qp += ai4_offsets[curr_rc_pic_type];
5308
0
            i4_temp_frame_qp = CLIP3(i4_temp_frame_qp, 1, 51);
5309
5310
0
            {
5311
0
                if(curr_rc_pic_type != I_PIC)
5312
0
                {
5313
0
                    i8_total_acc_coarse_me_sad +=
5314
0
                        ps_cur_rc_lap_out_temporal_offset
5315
0
                            ->ai8_frame_acc_coarse_me_sad[i4_temp_frame_qp];
5316
0
                    i1_num_frames_in_Sub_GOP++;
5317
0
                    i++;
5318
0
                }
5319
0
                else
5320
0
                {
5321
0
                    break;
5322
0
                }
5323
0
            }
5324
5325
0
            ps_cur_rc_lap_out_temporal_offset =
5326
0
                (rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5327
5328
0
            if(ps_cur_rc_lap_out_temporal_offset == NULL)
5329
0
            {
5330
0
                break;
5331
0
            }
5332
0
            curr_rc_pic_type = ihevce_rc_conv_pic_type(
5333
0
                (IV_PICTURE_CODING_TYPE_T)ps_cur_rc_lap_out_temporal_offset->i4_rc_pic_type,
5334
0
                ps_rc_ctxt->i4_field_pic,
5335
0
                ps_cur_rc_lap_out_temporal_offset->i4_rc_temporal_lyr_id,
5336
0
                ps_cur_rc_lap_out_temporal_offset->i4_is_bottom_field,
5337
0
                ps_rc_ctxt->i4_top_field_first);
5338
0
        }
5339
0
        else
5340
0
        {
5341
0
            i1_num_frames_in_Sub_GOP = 0;
5342
0
            break;
5343
0
        }
5344
0
    } while(
5345
0
        ((((curr_rc_pic_type != P_PIC) && ((curr_rc_pic_type != I_PIC))) ||
5346
0
          (curr_rc_pic_type == P_PIC)) &&
5347
0
         (i1_num_frames_in_Sub_GOP < i4_inter_frame_interval)));
5348
5349
0
    if((i1_num_frames_in_Sub_GOP) && (i1_no_reset == 0))
5350
0
    {
5351
0
        float f_hme_sad_per_pixel;
5352
0
        i8_avg_acc_coarse_me_sad = (i8_total_acc_coarse_me_sad / i1_num_frames_in_Sub_GOP);
5353
0
        f_hme_sad_per_pixel =
5354
0
            ((float)i8_avg_acc_coarse_me_sad /
5355
0
             (ps_rc_ctxt->i4_frame_height * ps_rc_ctxt->i4_frame_width));
5356
0
        f_hme_sad_per_pixel = CLIP3(f_hme_sad_per_pixel, 0.01f, 5.0f);
5357
        /*reset the QP offsets for the next sub GOP depending on the offline model based on the temporal complexity */
5358
0
        if(i4_Kp_Kb_reset_flag)
5359
0
        {
5360
0
            WORD32 i4_bin;
5361
5362
0
            rc_reset_Kp_Kb(
5363
0
                ps_rc_ctxt->rc_hdl,
5364
0
                8.00,
5365
0
                ps_rc_ctxt->i4_num_active_pic_type,
5366
0
                f_hme_sad_per_pixel,
5367
0
                &i4_bin,
5368
0
                ps_rc_ctxt->i4_rc_pass);
5369
0
        }
5370
0
        else
5371
0
        {
5372
0
            rc_ba_get_qp_offset_offline_data(
5373
0
                ps_rc_ctxt->rc_hdl,
5374
0
                ps_rc_lap_out->ai4_offsets,
5375
0
                f_hme_sad_per_pixel,
5376
0
                ps_rc_ctxt->i4_num_active_pic_type,
5377
0
                &ps_rc_lap_out->i4_complexity_bin);
5378
5379
0
            ps_cur_rc_lap_out_temporal_offset = ps_rc_lap_out;
5380
0
            ps_cur_rc_lap_out_temporal_offset->i4_offsets_set_flag = 1;
5381
5382
0
            curr_rc_pic_type = ihevce_rc_conv_pic_type(
5383
0
                (IV_PICTURE_CODING_TYPE_T)ps_rc_lap_out->i4_rc_pic_type,
5384
0
                ps_rc_ctxt->i4_field_pic,
5385
0
                ps_rc_lap_out->i4_rc_temporal_lyr_id,
5386
0
                ps_rc_lap_out->i4_is_bottom_field,
5387
0
                ps_rc_ctxt->i4_top_field_first);
5388
5389
0
            if((curr_rc_pic_type == I_PIC) &&
5390
0
               ((rc_lap_out_params_t *)ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode)
5391
0
                       ->i4_rc_pic_type == P_PIC)
5392
0
                i1_num_frames_in_Sub_GOP++;
5393
5394
0
            for(i = 1; i < i1_num_frames_in_Sub_GOP; i++)
5395
0
            {
5396
0
                ps_cur_rc_lap_out_temporal_offset =
5397
0
                    (rc_lap_out_params_t *)
5398
0
                        ps_cur_rc_lap_out_temporal_offset->ps_rc_lap_out_next_encode;
5399
0
                memmove(
5400
0
                    ps_cur_rc_lap_out_temporal_offset->ai4_offsets,
5401
0
                    ps_rc_lap_out->ai4_offsets,
5402
0
                    sizeof(WORD32) * 5);
5403
0
                ps_cur_rc_lap_out_temporal_offset->i4_complexity_bin =
5404
0
                    ps_rc_lap_out->i4_complexity_bin;
5405
0
                ps_cur_rc_lap_out_temporal_offset->i4_offsets_set_flag = 1;
5406
0
            }
5407
0
        }
5408
0
    }
5409
0
}
5410
5411
/**
5412
******************************************************************************
5413
*
5414
*  @brief function to get delta QP or In frame RC bits estimate to avoid buffer underflow
5415
*
5416
*  @par   Description
5417
*  @param[in]
5418
******************************************************************************
5419
*/
5420
5421
WORD32 ihevce_ebf_based_rc_correction_to_avoid_overflow(
5422
    rc_context_t *ps_rc_ctxt, rc_lap_out_params_t *ps_rc_lap_out, WORD32 *pi4_tot_bits_estimated)
5423
0
{
5424
0
    WORD32 i4_modelQP, i4_clipQP, i4_maxEbfQP, i4_diffQP, i4_is_model_valid, i4_deltaQP = 0;
5425
0
    LWORD64 i8_bitsClipQP, i8_grwEbf;  // i8_bitsComp;
5426
0
    WORD32 i4_is_offline_model_used;
5427
0
    WORD32 i4_vbv_buffer_size, i4_drain_rate, i4_currEbf, i4_maxEbf;
5428
0
    WORD32 i4_case = -1;
5429
0
    float f_thrsh_i_pic_delta_qp_1, f_thrsh_i_pic_delta_qp_2, f_thrsh_p_pic_delta_qp_1,
5430
0
        f_thrsh_p_pic_delta_qp_2;
5431
0
    float f_thrsh_br_pic_delta_qp_1, f_thrsh_br_pic_delta_qp_2, f_thrsh_bnr_pic_delta_qp_1,
5432
0
        f_thrsh_bnr_pic_delta_qp_2;
5433
0
    float f_vbv_thrsh_delta_qp;
5434
5435
    /*initialization of all the variables*/
5436
0
    rc_init_buffer_info(
5437
0
        ps_rc_ctxt->rc_hdl, &i4_vbv_buffer_size, &i4_currEbf, &i4_maxEbf, &i4_drain_rate);
5438
5439
0
    i4_is_model_valid = ps_rc_lap_out->i4_is_model_valid;
5440
0
    i4_modelQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_modelQP;
5441
0
    i4_clipQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_finalQP;
5442
0
    i4_maxEbfQP = ps_rc_ctxt->s_rc_high_lvl_stat.i4_maxEbfQP;
5443
0
    i8_bitsClipQP = ps_rc_ctxt->s_rc_high_lvl_stat.i8_bits_from_finalQP;
5444
0
    i4_is_offline_model_used = ps_rc_ctxt->s_rc_high_lvl_stat.i4_is_offline_model_used;
5445
0
    ASSERT(i4_clipQP != INVALID_QP);
5446
5447
0
    if(ps_rc_ctxt->i4_num_frame_parallel > 1)
5448
0
    {
5449
0
        f_thrsh_i_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_1;
5450
0
        f_thrsh_i_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_I_PIC_DELTA_QP_2;
5451
0
        f_thrsh_p_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_1;
5452
0
        f_thrsh_p_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_P_PIC_DELTA_QP_2;
5453
0
        f_thrsh_br_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_1;
5454
0
        f_thrsh_br_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_BR_PIC_DELTA_QP_2;
5455
0
        f_thrsh_bnr_pic_delta_qp_1 = (float)VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_1;
5456
0
        f_thrsh_bnr_pic_delta_qp_2 = (float)VBV_THRSH_FRM_PRLL_BNR_PIC_DELTA_QP_2;
5457
0
        f_vbv_thrsh_delta_qp = (float)VBV_THRSH_FRM_PRLL_DELTA_QP;
5458
0
    }
5459
0
    else
5460
0
    {
5461
0
        f_thrsh_i_pic_delta_qp_1 = (float)VBV_THRSH_I_PIC_DELTA_QP_1;
5462
0
        f_thrsh_i_pic_delta_qp_2 = (float)VBV_THRSH_I_PIC_DELTA_QP_2;
5463
0
        f_thrsh_p_pic_delta_qp_1 = (float)VBV_THRSH_P_PIC_DELTA_QP_1;
5464
0
        f_thrsh_p_pic_delta_qp_2 = (float)VBV_THRSH_P_PIC_DELTA_QP_2;
5465
0
        f_thrsh_br_pic_delta_qp_1 = (float)VBV_THRSH_BR_PIC_DELTA_QP_1;
5466
0
        f_thrsh_br_pic_delta_qp_2 = (float)VBV_THRSH_BR_PIC_DELTA_QP_2;
5467
0
        f_thrsh_bnr_pic_delta_qp_1 = (float)VBV_THRSH_BNR_PIC_DELTA_QP_1;
5468
0
        f_thrsh_bnr_pic_delta_qp_2 = (float)VBV_THRSH_BNR_PIC_DELTA_QP_2;
5469
0
        f_vbv_thrsh_delta_qp = (float)VBV_THRSH_DELTA_QP;
5470
0
    }
5471
5472
    /* function logic starts */
5473
0
    if(i4_is_model_valid)
5474
0
    {
5475
0
        ASSERT(i4_modelQP != INVALID_QP);
5476
0
        i8_grwEbf = i8_bitsClipQP - (LWORD64)i4_drain_rate;
5477
0
        if(((i4_currEbf + i8_grwEbf) > (0.6*i4_vbv_buffer_size)) /*&&
5478
0
                 i4_modelQP >= i4_clipQP*/)
5479
0
        {
5480
            /* part of existing scene (i.e. no new scene)
5481
            In which case this is not first I/P/Bref/Bnref etc
5482
            The models for I/P/Bref/Bnref are all valid*/
5483
0
            if(((i4_currEbf + i8_grwEbf) <
5484
0
                i4_maxEbf)) /* does not matter whether this is 2pass, 1 pass, VBR, CBR etc*/
5485
0
            {
5486
                /* clipQP has been determined keeping in view certain other quality constraints like pusling etc.
5487
                So better to honour it if possible*/
5488
                //if (i8_bitsClipQP > i8_drain_rate)
5489
0
                {
5490
0
                    LWORD64 i8_thrsh_for_deltaQP_2 = i4_vbv_buffer_size,
5491
0
                            i8_thrsh_for_deltaQP_1 = i4_vbv_buffer_size;
5492
                    /*even when (modelQP - clipQP) = 0, we intend to QP increase as expected ebf is above 60%*/
5493
0
                    i4_diffQP = MAX(i4_modelQP - i4_clipQP, 1);
5494
0
                    switch(ps_rc_lap_out->i4_rc_pic_type)
5495
0
                    {
5496
0
                    case IV_I_FRAME:
5497
0
                    case IV_IDR_FRAME:
5498
0
                    {
5499
0
                        i8_thrsh_for_deltaQP_1 =
5500
0
                            (LWORD64)(f_thrsh_i_pic_delta_qp_1 * i4_vbv_buffer_size);
5501
0
                        i8_thrsh_for_deltaQP_2 =
5502
0
                            (LWORD64)(f_thrsh_i_pic_delta_qp_2 * i4_vbv_buffer_size);
5503
0
                        break;
5504
0
                    }
5505
0
                    case IV_P_FRAME:
5506
0
                    {
5507
0
                        i8_thrsh_for_deltaQP_1 =
5508
0
                            (LWORD64)(f_thrsh_p_pic_delta_qp_1 * i4_vbv_buffer_size);
5509
0
                        i8_thrsh_for_deltaQP_2 =
5510
0
                            (LWORD64)(f_thrsh_p_pic_delta_qp_2 * i4_vbv_buffer_size);
5511
0
                        break;
5512
0
                    }
5513
0
                    case IV_B_FRAME:
5514
0
                    {
5515
0
                        if(ps_rc_lap_out->i4_rc_is_ref_pic)
5516
0
                        {
5517
0
                            i8_thrsh_for_deltaQP_1 =
5518
0
                                (LWORD64)(f_thrsh_br_pic_delta_qp_1 * i4_vbv_buffer_size);
5519
0
                            i8_thrsh_for_deltaQP_2 =
5520
0
                                (LWORD64)(f_thrsh_br_pic_delta_qp_2 * i4_vbv_buffer_size);
5521
0
                        }
5522
0
                        else
5523
0
                        {
5524
                            /*as of now using the same thresholds as B reference, later may have to tune if required*/
5525
0
                            i8_thrsh_for_deltaQP_1 =
5526
0
                                (LWORD64)(f_thrsh_bnr_pic_delta_qp_1 * i4_vbv_buffer_size);
5527
0
                            i8_thrsh_for_deltaQP_2 =
5528
0
                                (LWORD64)(f_thrsh_bnr_pic_delta_qp_2 * i4_vbv_buffer_size);
5529
0
                        }
5530
0
                        break;
5531
0
                    }
5532
0
                    default:
5533
0
                        break;
5534
0
                    }
5535
5536
0
                    if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_1)
5537
0
                    {
5538
                        /*For more than 2 QP chnage this means a larger scale issue and probably needs to be handled elsewhere ?*/
5539
0
                        i4_deltaQP =
5540
0
                            MIN(2, i4_diffQP); /* we dont intend to change QP by more than 2 */
5541
0
                        i4_case = 0;
5542
0
                    }
5543
0
                    else if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_2)
5544
0
                    {
5545
0
                        i4_deltaQP = MIN(1, i4_diffQP);
5546
0
                        i4_case = 1;
5547
0
                    }
5548
0
                }
5549
                /* else  if (i8_bitsClipQP > i8_drain_rate)
5550
        {
5551
                we have no correection, buffer will be healthy after this.
5552
                However, there could be one problem if the currEbf is already close to say 80% of EBF.
5553
                This means we have not reacted well early - needs to be handled?
5554
5555
                This could be the case where it is a simple scene immediately following a complex scene
5556
                and is the I picture (not the first I since model is valid).
5557
                Is this possible - maybe, what to do - dont know?
5558
        }
5559
                */
5560
0
            }
5561
0
            else /*(i4_clipQP < i4_maxEbfQP)*/
5562
0
            {
5563
0
                i4_deltaQP = 2;
5564
0
                i4_case = 2;
5565
0
            }
5566
0
        }
5567
0
        if((i4_currEbf + i8_grwEbf) < (0.6 * i4_vbv_buffer_size))
5568
0
        {
5569
0
            *pi4_tot_bits_estimated = i8_bitsClipQP;
5570
0
        }
5571
0
    }
5572
0
    else
5573
0
    {
5574
0
        if(i4_is_offline_model_used)
5575
0
        {
5576
            /* this can be only for non-I SCD, where we reset RC */
5577
0
            WORD32 i4_bits_est_for_in_frm_rc = *pi4_tot_bits_estimated;
5578
0
            i8_grwEbf = i4_bits_est_for_in_frm_rc - i4_drain_rate;
5579
0
            if((i4_currEbf + i8_grwEbf) > (f_vbv_thrsh_delta_qp * i4_vbv_buffer_size))
5580
0
            {
5581
0
                i4_bits_est_for_in_frm_rc =
5582
0
                    i4_drain_rate + (WORD32)(0.85 * i4_vbv_buffer_size) - i4_currEbf;
5583
                /* if pi4_tot_bits_estimated becomes less than zero or less than drain rate this indiactes that we are near or above 85% of the buffer */
5584
                /* this needs a reaction */
5585
0
                if(i4_bits_est_for_in_frm_rc < i4_drain_rate)
5586
0
                {
5587
0
                    *pi4_tot_bits_estimated =
5588
0
                        MAX((i4_drain_rate + (WORD32)(0.95 * i4_vbv_buffer_size) - i4_currEbf),
5589
0
                            i4_drain_rate);
5590
0
                    i4_deltaQP = 2; /* this needs some review, needs to be handled well */
5591
0
                }
5592
0
            }
5593
0
            i4_case = 3;
5594
0
        }
5595
0
        else
5596
0
        {
5597
0
            i8_bitsClipQP = *pi4_tot_bits_estimated;
5598
0
            i8_grwEbf = i8_bitsClipQP - i4_drain_rate;
5599
5600
0
            if(((i4_currEbf + i8_grwEbf) <
5601
0
                i4_maxEbf)) /* does not matter whether this is 2pass, 1 pass, VBR, CBR etc*/
5602
0
            {
5603
                /* clipQP has been determined keeping in view certain other quality constraints like pusling etc.
5604
                    So better to honour it if possible*/
5605
                //if (i8_bitsClipQP > i8_drain_rate)
5606
0
                {
5607
0
                    LWORD64 i8_thrsh_for_deltaQP_2 = i4_vbv_buffer_size,
5608
0
                            i8_thrsh_for_deltaQP_1 = i4_vbv_buffer_size;
5609
5610
0
                    switch(ps_rc_lap_out->i4_rc_pic_type)
5611
0
                    {
5612
0
                    case IV_I_FRAME:
5613
0
                    case IV_IDR_FRAME:
5614
0
                    {
5615
0
                        i8_thrsh_for_deltaQP_1 =
5616
0
                            (LWORD64)(f_thrsh_i_pic_delta_qp_1 * i4_vbv_buffer_size);
5617
0
                        i8_thrsh_for_deltaQP_2 =
5618
0
                            (LWORD64)(f_thrsh_i_pic_delta_qp_2 * i4_vbv_buffer_size);
5619
0
                        break;
5620
0
                    }
5621
0
                    case IV_P_FRAME:
5622
0
                    {
5623
0
                        i8_thrsh_for_deltaQP_1 =
5624
0
                            (LWORD64)(f_thrsh_p_pic_delta_qp_1 * i4_vbv_buffer_size);
5625
0
                        i8_thrsh_for_deltaQP_2 =
5626
0
                            (LWORD64)(f_thrsh_p_pic_delta_qp_2 * i4_vbv_buffer_size);
5627
0
                        break;
5628
0
                    }
5629
0
                    case IV_B_FRAME:
5630
0
                    {
5631
0
                        if(ps_rc_lap_out->i4_rc_is_ref_pic)
5632
0
                        {
5633
0
                            i8_thrsh_for_deltaQP_1 =
5634
0
                                (LWORD64)(f_thrsh_br_pic_delta_qp_1 * i4_vbv_buffer_size);
5635
0
                            i8_thrsh_for_deltaQP_2 =
5636
0
                                (LWORD64)(f_thrsh_br_pic_delta_qp_2 * i4_vbv_buffer_size);
5637
0
                        }
5638
0
                        else
5639
0
                        {
5640
                            /*as of now using the same thresholds as B reference, later may have to tune if required*/
5641
0
                            i8_thrsh_for_deltaQP_1 =
5642
0
                                (LWORD64)(f_thrsh_bnr_pic_delta_qp_1 * i4_vbv_buffer_size);
5643
0
                            i8_thrsh_for_deltaQP_2 =
5644
0
                                (LWORD64)(f_thrsh_bnr_pic_delta_qp_2 * i4_vbv_buffer_size);
5645
0
                        }
5646
0
                        break;
5647
0
                    }
5648
0
                    default:
5649
0
                        break;
5650
0
                    }
5651
5652
0
                    if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_1)
5653
0
                    {
5654
                        /*For more than 2 QP chnage this means a larger scale issue and probably needs to be handled elsewhere ?*/
5655
0
                        i4_deltaQP = 2; /* we dont intend to change QP by more than 2 */
5656
0
                        i4_case = 5;
5657
0
                    }
5658
0
                    else if((i4_currEbf + i8_grwEbf) > i8_thrsh_for_deltaQP_2)
5659
0
                    {
5660
0
                        i4_deltaQP = 1;
5661
0
                        i4_case = 6;
5662
0
                    }
5663
0
                }
5664
0
            }
5665
0
            else
5666
0
            {
5667
0
                i4_deltaQP = 2;
5668
0
                i4_case = 7;
5669
0
            }
5670
0
        }
5671
0
    }
5672
0
    return i4_deltaQP;
5673
0
}
5674
5675
/*###############################################*/
5676
/******* END OF RC UTILS FUNCTIONS ***************/
5677
/*###############################################*/
5678
5679
/*########################################################*/
5680
/******* START OF VBV COMPLIANCE FUNCTIONS ***************/
5681
/*#######################################################*/
5682
5683
/*!
5684
******************************************************************************
5685
* \if Function name : ihevce_vbv_compliance_frame_level_update
5686
*
5687
* \brief
5688
*    this function initializes the hrd buffer level to be used for vbv compliance testing using the parameters feeded in VUI parameters
5689
*
5690
* \param[in] *pv_ctxt -> rc context
5691
*           i4_bits_generated -> bits generated from entropy
5692
*           i4_resolution_id -> info needed for log Dump
5693
*           i4_appln_bitrate_inst -> info needed for log Dump
5694
*           u4_cur_cpb_removal_delay_minus1 -> cbp removal delay of present frame
5695
* \return
5696
*
5697
* \author
5698
*  Ittiam
5699
*
5700
*****************************************************************************
5701
*/
5702
5703
void ihevce_vbv_compliance_frame_level_update(
5704
    void *pv_rc_ctxt,
5705
    WORD32 i4_bits_generated,
5706
    WORD32 i4_resolution_id,
5707
    WORD32 i4_appln_bitrate_inst,
5708
    UWORD32 u4_cur_cpb_removal_delay_minus1)
5709
0
{
5710
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_rc_ctxt;
5711
0
    float f_max_vbv_buff_size = (float)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5712
0
    WORD32 i4_cbp_removal_delay_diff = 1;
5713
5714
0
    if((ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 > 0) &&
5715
0
       (u4_cur_cpb_removal_delay_minus1 >
5716
0
        ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1))
5717
0
        i4_cbp_removal_delay_diff =
5718
0
            (u4_cur_cpb_removal_delay_minus1 -
5719
0
             ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1);
5720
5721
0
    ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5722
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level - (float)i4_bits_generated +
5723
0
        (i4_cbp_removal_delay_diff * ps_rc_ctxt->s_vbv_compliance.f_drain_rate);
5724
5725
0
    ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip =
5726
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level;
5727
5728
0
    if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level < 0)
5729
0
    {
5730
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level = 0;
5731
0
    }
5732
5733
0
    if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level >
5734
0
       ps_rc_ctxt->s_vbv_compliance.f_buffer_size)
5735
0
    {
5736
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5737
0
            ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5738
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip -=
5739
0
            ps_rc_ctxt->s_vbv_compliance.f_buffer_size;
5740
0
    }
5741
0
    else if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip > 0)
5742
0
    {
5743
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip = 0;
5744
0
    }
5745
5746
0
    if(ps_rc_ctxt->e_rate_control_type == VBR_STREAMING)
5747
0
    {
5748
0
        if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip > 0)
5749
0
            ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level_unclip = 0;
5750
0
    }
5751
0
    ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 = u4_cur_cpb_removal_delay_minus1;
5752
0
}
5753
5754
/*!
5755
******************************************************************************
5756
* \if Function name : ihevce_vbv_complaince_init_level
5757
*
5758
* \brief
5759
*    this function initializes the hrd buffer level to be used for vbv compliance testing using the parameters feeded in VUI parameters
5760
*
5761
* \param[in] *pv_ctxt -> rc context
5762
*            *ps_vui      -> VUI parameters
5763
* \return
5764
*
5765
* \author
5766
*  Ittiam
5767
*
5768
*****************************************************************************
5769
*/
5770
5771
void ihevce_vbv_complaince_init_level(void *pv_ctxt, vui_t *ps_vui)
5772
0
{
5773
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5774
5775
0
    ps_rc_ctxt->s_vbv_compliance.f_frame_rate =
5776
0
        (float)((float)ps_vui->u4_vui_time_scale / ps_vui->u4_vui_num_units_in_tick);  //rc_get_frame_rate(ps_rc_ctxt->rc_hdl);
5777
5778
0
    if(1 == ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag)
5779
0
    {
5780
0
        ASSERT(1 == ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag);
5781
5782
0
        ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)((
5783
0
            (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_bit_rate_du_value_minus1[0] +
5784
0
             1)
5785
0
            << (6 + ps_vui->s_vui_hrd_parameters
5786
0
                        .u4_bit_rate_scale)));  //rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
5787
5788
0
        ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)((
5789
0
            (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_cpb_size_du_value_minus1[0] +
5790
0
             1)
5791
0
            << (4 + ps_vui->s_vui_hrd_parameters
5792
0
                        .u4_cpb_size_du_scale)));  //ps_rc_ctxt->u4_max_vbv_buff_size;
5793
0
    }
5794
0
    else
5795
0
    {
5796
0
        ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)((
5797
0
            (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_bit_rate_value_minus1[0] +
5798
0
             1)
5799
0
            << (6 + ps_vui->s_vui_hrd_parameters
5800
0
                        .u4_bit_rate_scale)));  //rc_get_bit_rate(ps_rc_ctxt->rc_hdl);
5801
5802
0
        ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)((
5803
0
            (ps_vui->s_vui_hrd_parameters.as_sub_layer_hrd_params[0].au4_cpb_size_value_minus1[0] +
5804
0
             1)
5805
0
            << (4 + ps_vui->s_vui_hrd_parameters
5806
0
                        .u4_cpb_size_scale)));  //ps_rc_ctxt->u4_max_vbv_buff_size;
5807
0
    }
5808
0
    ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level =
5809
0
        (float)ps_rc_ctxt->s_vbv_compliance.f_buffer_size;  //ps_rc_ctxt->u4_max_vbv_buff_size;
5810
5811
0
    ps_rc_ctxt->s_vbv_compliance.f_drain_rate =
5812
0
        ((ps_rc_ctxt->s_vbv_compliance.f_bit_rate) / ps_rc_ctxt->s_vbv_compliance.f_frame_rate);
5813
5814
0
    ps_rc_ctxt->s_vbv_compliance.u4_prev_cpb_removal_delay_minus1 = 0;
5815
0
}
5816
5817
/*########################################################*/
5818
/******* END OF VBV COMPLIANCE FUNCTIONS *****************/
5819
/*#######################################################*/
5820
5821
/*################################################################*/
5822
/******* START OF DYN CHANGE iN BITRATE FUNCTIONS *****************/
5823
/*################################################################*/
5824
/*!
5825
******************************************************************************
5826
* \if Function name : change_bitrate_vbv_complaince
5827
*
5828
* \brief
5829
*    this function updates the new bitrate and re calculates the drain rate
5830
*
5831
* \param[in] *pv_ctxt -> rc context
5832
* \return
5833
*
5834
* \author
5835
*  Ittiam
5836
*
5837
*****************************************************************************
5838
*/
5839
void change_bitrate_vbv_complaince(void *pv_ctxt, LWORD64 i8_new_bitrate, LWORD64 i8_buffer_size)
5840
0
{
5841
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5842
0
    ps_rc_ctxt->s_vbv_compliance.f_buffer_size = (float)i8_buffer_size;
5843
0
    ps_rc_ctxt->s_vbv_compliance.f_bit_rate = (float)i8_new_bitrate;
5844
0
    if(ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level > i8_buffer_size)
5845
0
        ps_rc_ctxt->s_vbv_compliance.f_curr_buffer_level = (float)i8_buffer_size;
5846
0
    ps_rc_ctxt->s_vbv_compliance.f_drain_rate =
5847
0
        ps_rc_ctxt->s_vbv_compliance.f_bit_rate / ps_rc_ctxt->s_vbv_compliance.f_frame_rate;
5848
0
}
5849
/*!
5850
******************************************************************************
5851
* \if Function name : ihevce_rc_register_dyn_change_bitrate
5852
*
5853
* \brief
5854
*    this function registers call to change bitrate dynamically.
5855
*
5856
* \param[in] *pv_ctxt -> rc context
5857
*
5858
* \return
5859
*
5860
* \author
5861
*  Ittiam
5862
*
5863
*****************************************************************************
5864
*/
5865
5866
void ihevce_rc_register_dyn_change_bitrate(
5867
    void *pv_ctxt, LWORD64 i8_new_bitrate, LWORD64 i8_new_peak_bitrate)
5868
0
{
5869
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5870
0
    ps_rc_ctxt->i8_new_bitrate = i8_new_bitrate;
5871
0
    ps_rc_ctxt->i8_new_peak_bitrate = i8_new_peak_bitrate;
5872
0
    ps_rc_ctxt->i4_bitrate_changed = 1;
5873
0
    ASSERT(ps_rc_ctxt->i8_new_bitrate > 0);
5874
0
    ASSERT(ps_rc_ctxt->i8_new_peak_bitrate > 0);
5875
0
}
5876
5877
/*!
5878
******************************************************************************
5879
* \if Function name : ihevce_rc_get_new_bitrate
5880
*
5881
* \brief
5882
*    get new bitrate
5883
*
5884
* \param[in] *pv_ctxt -> rc context
5885
*
5886
* \return
5887
*
5888
* \author
5889
*  Ittiam
5890
*
5891
*****************************************************************************
5892
*/
5893
LWORD64 ihevce_rc_get_new_bitrate(void *pv_ctxt)
5894
0
{
5895
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5896
0
    return ps_rc_ctxt->i8_new_bitrate;
5897
0
}
5898
/*!
5899
******************************************************************************
5900
* \if Function name : ihevce_rc_get_new_peak_bitrate
5901
*
5902
* \brief
5903
*    get new peak rate
5904
*
5905
* \param[in] *pv_ctxt -> rc context
5906
*
5907
* \return
5908
*
5909
* \author
5910
*  Ittiam
5911
*
5912
*****************************************************************************
5913
*/
5914
LWORD64 ihevce_rc_get_new_peak_bitrate(void *pv_ctxt)
5915
0
{
5916
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5917
0
    return ps_rc_ctxt->i8_new_peak_bitrate;
5918
0
}
5919
5920
/*!
5921
******************************************************************************
5922
* \if Function name : ihevce_rc_change_avg_bitrate
5923
*
5924
* \brief
5925
*    change average bitrate configured based on new bitrate
5926
*
5927
* \param[in] *pv_ctxt -> rc context
5928
*
5929
* \return
5930
*
5931
* \author
5932
*  Ittiam
5933
*
5934
*****************************************************************************
5935
*/
5936
LWORD64 ihevce_rc_change_avg_bitrate(void *pv_ctxt)
5937
0
{
5938
0
    rc_context_t *ps_rc_ctxt = (rc_context_t *)pv_ctxt;
5939
0
    LWORD64 vbv_buffer_level_b4_change;
5940
5941
0
    ASSERT(ps_rc_ctxt->i8_new_bitrate != -1);
5942
0
    ASSERT(ps_rc_ctxt->i8_new_peak_bitrate != -1);
5943
    /*Get the VBV buffer level just before forcing bitrate change*/
5944
0
    vbv_buffer_level_b4_change = (LWORD64)rc_get_ebf(ps_rc_ctxt->rc_hdl);
5945
5946
0
    change_avg_bit_rate(
5947
0
        ps_rc_ctxt->rc_hdl,
5948
0
        (UWORD32)ps_rc_ctxt->i8_new_bitrate,
5949
0
        (UWORD32)ps_rc_ctxt->i8_new_peak_bitrate);
5950
    /*Once the request is serviced set new bitrate to -1*/
5951
0
    ps_rc_ctxt->i8_new_bitrate = -1;
5952
0
    ps_rc_ctxt->i8_new_peak_bitrate = -1;
5953
0
    return vbv_buffer_level_b4_change;
5954
0
}
5955
5956
/*##############################################################*/
5957
/******* END OF DYN CHNAGE iN BITRATE FUNCTIONS *****************/
5958
/*##############################################################*/