/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 | | /*##############################################################*/ |