1 /******************************************************************************
2 *
3 * Copyright (C) 2022 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
24 * isvce_sub_pic_rc.c
25 *
26 * @brief
27 * Contains functions used in sub-pic RC
28 *
29 *******************************************************************************
30 */
31 #include <stdbool.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <math.h>
35
36 #include "ih264_typedefs.h"
37 #include "ih264_cavlc_tables.h"
38 #include "ih264_platform_macros.h"
39 #include "ithread.h"
40 #include "isvc_defs.h"
41 #include "isvc_structs.h"
42 #include "isvce_structs.h"
43 #include "isvce_defs.h"
44 #include "isvce_sub_pic_rc.h"
45 #include "isvce_sub_pic_rc_private_defs.h"
46
47 /* Dependencies of 'irc_picture_type.h' */
48 #include "irc_mem_req_and_acq.h"
49
50 /* Dependencies of 'irc_rate_control_api_structs' */
51 #include "irc_picture_type.h"
52 #include "irc_rd_model.h"
53 #include "irc_vbr_storage_vbv.h"
54 #include "irc_est_sad.h"
55 #include "irc_bit_allocation.h"
56 #include "irc_mb_model_based.h"
57 #include "irc_cbr_buffer_control.h"
58 #include "irc_vbr_str_prms.h"
59 #include "irc_common.h"
60
61 #include "irc_rate_control_api_structs.h"
62 #include "irc_rate_control_api.h"
63
64 /**
65 *******************************************************************************
66 *
67 * @brief
68 * Returns size of buffers for storing subPicRC ctxt
69 *
70 * @returns Size of buffers
71 *
72 *******************************************************************************
73 */
isvce_get_sub_pic_rc_ctxt_size(UWORD8 u1_num_spatial_layers,DOUBLE d_spatial_res_ratio,UWORD32 u4_wd,UWORD32 u4_ht)74 UWORD32 isvce_get_sub_pic_rc_ctxt_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
75 UWORD32 u4_wd, UWORD32 u4_ht)
76 {
77 WORD32 i;
78
79 UWORD32 u4_size = MAX_PROCESS_CTXT * sizeof(svc_sub_pic_rc_ctxt_t);
80
81 u4_size += sizeof(sub_pic_rc_state_t);
82 u4_size += ithread_get_mutex_struct_size();
83
84 for(i = u1_num_spatial_layers - 1; i >= 0; i--)
85 {
86 WORD32 i4_layer_wd =
87 (WORD32) ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
88 0.99;
89 WORD32 i4_layer_ht =
90 ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
91 WORD32 i4_layer_mbs = (i4_layer_wd / MB_SIZE) * (i4_layer_ht / MB_SIZE);
92
93 /* ps_mb_bits_info */
94 u4_size += i4_layer_mbs * sizeof(mb_bits_info_t);
95
96 #if DUMP_SUB_PIC_RC_DATA
97 /* ps_mb_bits_actual */
98 u4_size += i4_layer_mbs * sizeof(mb_bits_info_t);
99 #endif
100 }
101
102 return u4_size;
103 }
104
isvce_sub_pic_rc_ctxt_init(isvce_codec_t * ps_codec,iv_mem_rec_t * ps_mem_rec)105 void isvce_sub_pic_rc_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
106 {
107 sub_pic_rc_state_t *ps_sub_pic_rc_state;
108
109 WORD32 i, j;
110
111 DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
112 UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
113 UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
114 UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
115 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
116 WORD64 i8_alloc_mem_size =
117 isvce_get_sub_pic_rc_ctxt_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
118
119 for(i = 0; i < MAX_PROCESS_CTXT; i++)
120 {
121 svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_codec->as_process[i].ps_sub_pic_rc_ctxt =
122 (svc_sub_pic_rc_ctxt_t *) pu1_buf;
123
124 pu1_buf += sizeof(ps_sub_pic_rc_ctxt[0]);
125 i8_alloc_mem_size -= sizeof(ps_sub_pic_rc_ctxt[0]);
126
127 if(0 == i)
128 {
129 ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants.pv_state = ps_sub_pic_rc_state =
130 (sub_pic_rc_state_t *) pu1_buf;
131 pu1_buf += sizeof(ps_sub_pic_rc_state[0]);
132 i8_alloc_mem_size -= sizeof(ps_sub_pic_rc_state[0]);
133
134 ASSERT(i8_alloc_mem_size >= 0);
135 ASSERT(NULL != ps_codec->s_rate_control.apps_rate_control_api);
136 ASSERT(NULL != ps_codec->as_process->s_me_ctxt.pu1_mv_bits);
137
138 ps_sub_pic_rc_state->s_svc_params = ps_codec->s_cfg.s_svc_params;
139 ps_sub_pic_rc_state->pu1_uev_codeword_to_bits_map = gau1_uev_codeword_to_bits_map;
140 ps_sub_pic_rc_state->pu1_sev_codeword_to_bits_map =
141 ps_codec->as_process->s_me_ctxt.pu1_mv_bits;
142 ps_sub_pic_rc_state->e_rc_mode = ps_codec->s_cfg.e_rc_mode;
143
144 ps_sub_pic_rc_state->pv_bits_accumulator_mutex = (void *) pu1_buf;
145 pu1_buf += ithread_get_mutex_struct_size();
146 i8_alloc_mem_size -= ithread_get_mutex_struct_size();
147 ithread_mutex_init(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
148
149 for(j = u1_num_spatial_layers - 1; j >= 0; j--)
150 {
151 sub_pic_rc_layer_state_t *ps_layer_state =
152 &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[j];
153
154 WORD32 i4_layer_wd =
155 (WORD32) ((DOUBLE) u4_wd /
156 pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
157 0.99;
158 WORD32 i4_layer_ht =
159 ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
160 0.99;
161 WORD32 i4_layer_mbs = (i4_layer_wd / MB_SIZE) * (i4_layer_ht / MB_SIZE);
162
163 ps_layer_state->i4_wd = i4_layer_wd;
164 ps_layer_state->i4_ht = i4_layer_ht;
165 ps_layer_state->i4_num_mbs = i4_layer_mbs;
166 ps_layer_state->pv_layer_rc_ctxt =
167 ps_codec->s_rate_control.apps_rate_control_api[j];
168 ps_layer_state->ps_mb_bits_info = (mb_bits_info_t *) pu1_buf;
169 pu1_buf += i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_info[0]);
170 i8_alloc_mem_size -= i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_info[0]);
171
172 ASSERT(i8_alloc_mem_size >= 0);
173
174 #if DUMP_SUB_PIC_RC_DATA
175 ps_layer_state->ps_mb_bits_actual = (mb_bits_info_t *) pu1_buf;
176 pu1_buf += i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_actual[0]);
177 i8_alloc_mem_size -= i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_actual[0]);
178
179 ASSERT(i8_alloc_mem_size >= 0);
180
181 {
182 UWORD8 au1_file_path[MAX_SUB_PIC_RC_DUMP_FILE_PATH_LENGTH + 1];
183
184 sprintf((WORD8 *) au1_file_path, "%ssubPicRC%1d.txt", SUB_PIC_RC_DUMP_FILE_PATH,
185 j);
186
187 ps_layer_state->ps_data_dump_file = fopen(au1_file_path, "w");
188
189 ASSERT(NULL != ps_layer_state->ps_data_dump_file);
190 }
191 #endif
192 }
193 }
194 else
195 {
196 svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt_src =
197 ps_codec->as_process[0].ps_sub_pic_rc_ctxt;
198 svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt_dst =
199 ps_codec->as_process[i].ps_sub_pic_rc_ctxt;
200 sub_pic_rc_state_t *ps_proc0_state =
201 (sub_pic_rc_state_t *) ps_sub_pic_rc_ctxt_src->s_sub_pic_rc_constants.pv_state;
202
203 ps_sub_pic_rc_ctxt_dst->s_sub_pic_rc_constants.pv_state = ps_proc0_state;
204 }
205 }
206 }
207
isvce_sub_pic_rc_qp_params_init(sub_pic_rc_qp_params_t * ps_qp_params,UWORD8 u1_min_qp,UWORD8 u1_max_qp)208 static FORCEINLINE void isvce_sub_pic_rc_qp_params_init(sub_pic_rc_qp_params_t *ps_qp_params,
209 UWORD8 u1_min_qp, UWORD8 u1_max_qp)
210 {
211 ps_qp_params->u1_min_qp = u1_min_qp;
212 ps_qp_params->u1_max_qp = u1_max_qp;
213 ps_qp_params->pu4_qp_to_qscale_map = gau4_qp_to_qscale_map;
214 ps_qp_params->pu1_qscale_to_qp_map = gau1_qscale_to_qp_map;
215 }
216
isvce_sub_pic_rc_ctxt_layer_init(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt)217 void isvce_sub_pic_rc_ctxt_layer_init(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
218 {
219 sub_pic_rc_layer_state_t *ps_layer_state;
220
221 svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
222 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
223 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
224 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
225 sub_pic_rc_state_t *ps_sub_pic_rc_state =
226 (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
227
228 UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
229
230 ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
231
232 memset(&ps_layer_state->s_cumulative_mb_bits, 0, sizeof(ps_layer_state->s_cumulative_mb_bits));
233 ps_layer_state->u4_num_mbs_sampled = 0;
234
235 /* Frames with frameNum=0 are usually IDR's. RC model will be reset for IDR's.
236 */
237 /* Hence, using VBVBufSize as a proxy for estimated bits */
238 if(0 == ps_sub_pic_rc_variables->s_layer_variables.i4_frame_num)
239 {
240 ps_layer_state->u4_allocated_bits =
241 irc_get_vbv_buf_size(ps_layer_state->pv_layer_rc_ctxt) / 10.;
242 }
243 else
244 {
245 ps_layer_state->u4_allocated_bits =
246 irc_get_prev_frm_est_bits(ps_layer_state->pv_layer_rc_ctxt);
247 }
248
249 isvce_sub_pic_rc_qp_params_init(&ps_layer_state->s_qp_params,
250 ps_sub_pic_rc_variables->s_layer_variables.u1_min_qp,
251 ps_sub_pic_rc_variables->s_layer_variables.u1_max_qp);
252 }
253
isvce_sub_pic_rc_get_res_pred_flag_bits(svc_sub_pic_rc_variables_t * ps_sub_pic_rc_variables,sub_pic_rc_state_t * ps_sub_pic_rc_state)254 static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_res_pred_flag_bits(
255 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
256 {
257 isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
258
259 UNUSED(ps_sub_pic_rc_state);
260
261 return (ENABLE_RESIDUAL_PREDICTION && !ps_mb_info->u1_is_intra);
262 }
263
isvce_sub_pic_rc_get_cbp_bits(svc_sub_pic_rc_variables_t * ps_sub_pic_rc_variables,sub_pic_rc_state_t * ps_sub_pic_rc_state)264 static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_cbp_bits(
265 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
266 {
267 isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
268
269 UWORD32 u4_cbp = ps_sub_pic_rc_variables->s_mb_variables.u4_cbp;
270 bool b_use_inter_cbp_map = !ps_mb_info->u1_is_intra || ps_mb_info->u1_base_mode_flag;
271
272 return ps_sub_pic_rc_state
273 ->pu1_uev_codeword_to_bits_map[gu1_cbp_map_tables[u4_cbp][b_use_inter_cbp_map]];
274 }
275
isvce_sub_pic_rc_get_mb_type_bits(svc_sub_pic_rc_variables_t * ps_sub_pic_rc_variables,sub_pic_rc_state_t * ps_sub_pic_rc_state)276 static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_mb_type_bits(
277 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
278 {
279 UWORD32 u4_mb_type;
280
281 isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
282
283 UWORD32 u4_cbp = ps_sub_pic_rc_variables->s_mb_variables.u4_cbp;
284 UWORD32 au4_cbps[NUM_SP_COMPONENTS] = {u4_cbp & 15, u4_cbp >> 4};
285
286 switch(ps_mb_info->u2_mb_type)
287 {
288 case I16x16:
289 {
290 u4_mb_type = ps_mb_info->s_intra_pu.s_i16x16_mode_data.u1_mode + 1 +
291 (au4_cbps[UV] << 2) + (au4_cbps[Y] == 15) * 12;
292
293 break;
294 }
295 case I4x4:
296 {
297 u4_mb_type = 5 * (ps_sub_pic_rc_variables->s_layer_variables.i4_slice_type != ISLICE);
298
299 break;
300 }
301 case P16x16:
302 {
303 u4_mb_type = 0;
304
305 break;
306 }
307 default:
308 {
309 return 0;
310 }
311 }
312
313 return ps_sub_pic_rc_state->pu1_uev_codeword_to_bits_map[u4_mb_type];
314 }
315
isvce_sub_pic_rc_get_mb_pred_bits(svc_sub_pic_rc_variables_t * ps_sub_pic_rc_variables,sub_pic_rc_state_t * ps_sub_pic_rc_state)316 static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_mb_pred_bits(
317 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
318 {
319 WORD32 i;
320
321 isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
322
323 UWORD32 u4_bits = 0;
324
325 switch(ps_mb_info->u2_mb_type)
326 {
327 case I16x16:
328 {
329 /* intra_chroma_pred_mode */
330 u4_bits +=
331 ps_sub_pic_rc_state
332 ->pu1_uev_codeword_to_bits_map[ps_mb_info->s_intra_pu.u1_chroma_intra_mode];
333
334 break;
335 }
336 case I4x4:
337 {
338 intra4x4_mode_data_t *ps_i4x4_mode_data = ps_mb_info->s_intra_pu.as_i4x4_mode_data;
339
340 for(i = 0; i < MAX_TU_IN_MB; i++)
341 {
342 /* prev_intra4x4_pred_mode_flag */
343 u4_bits += 1;
344
345 /* rem_intra4x4_pred_mode */
346 u4_bits +=
347 3 * (ps_i4x4_mode_data[i].u1_mode != ps_i4x4_mode_data[i].u1_predicted_mode);
348 }
349
350 /* intra_chroma_pred_mode */
351 u4_bits +=
352 ps_sub_pic_rc_state
353 ->pu1_uev_codeword_to_bits_map[ps_mb_info->s_intra_pu.u1_chroma_intra_mode];
354
355 break;
356 }
357 case P16x16:
358 {
359 mv_t s_mvd;
360
361 /* motion_prediction_flag_l0 */
362 u4_bits += USE_ILP_MV_AS_MVP;
363
364 /* ref_idx_l0 */
365 if(2 == ps_sub_pic_rc_variables->s_layer_variables.i4_max_num_reference_frames)
366 {
367 u4_bits += 1;
368 }
369 else if(2 < ps_sub_pic_rc_variables->s_layer_variables.i4_max_num_reference_frames)
370 {
371 u4_bits += ps_sub_pic_rc_state->pu1_uev_codeword_to_bits_map
372 [ps_mb_info->as_pu->as_me_info[L0].i1_ref_idx];
373 }
374
375 /* mvd_l0 */
376 s_mvd.i2_mvx = ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
377 ps_sub_pic_rc_variables->s_mb_variables
378 .aps_mvps[ps_mb_info->as_pu->au1_mvp_idx[L0]]
379 ->s_mv.i2_mvx;
380 s_mvd.i2_mvy = ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
381 ps_sub_pic_rc_variables->s_mb_variables
382 .aps_mvps[ps_mb_info->as_pu->au1_mvp_idx[L0]]
383 ->s_mv.i2_mvy;
384 u4_bits += ps_sub_pic_rc_state->pu1_sev_codeword_to_bits_map[s_mvd.i2_mvx];
385 u4_bits += ps_sub_pic_rc_state->pu1_sev_codeword_to_bits_map[s_mvd.i2_mvy];
386
387 break;
388 }
389 default:
390 {
391 break;
392 }
393 }
394
395 return u4_bits;
396 }
397
ihevce_svc_sub_pic_rc_set_header_bits(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt)398 static void ihevce_svc_sub_pic_rc_set_header_bits(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
399 {
400 sub_pic_rc_layer_state_t *ps_layer_state;
401 mb_bits_info_t *ps_mb_bits_info;
402
403 UWORD32 u4_mb_idx;
404
405 svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
406 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
407 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
408 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
409 sub_pic_rc_state_t *ps_sub_pic_rc_state =
410 (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
411 isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
412
413 UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
414
415 ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
416 u4_mb_idx = ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_abscissa +
417 ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_ordinate *
418 (ps_layer_state->i4_wd / MB_SIZE);
419 ps_mb_bits_info = &ps_layer_state->ps_mb_bits_info[u4_mb_idx];
420
421 /* Hypotheses used for header bits estimation - */
422 /* 1. mb_skip_run, base_mode_flag, mb_type, mb_pred, residual_prediction_flag,
423 * and cbp */
424 /* are considered as contibuting to header bits. */
425 /* 2. mb_skip_run = 1 bit */
426 /* 3. base_mode_flag = 1 bit */
427 /* 4. mb_type = LUT mapping mbType to corresponding ue(v) */
428 /* 5. mb_pred.I4x4 = 1 bit for 16 'prev_intra4x4_pred_mode_flag'; */
429 /* 3 bits for each explicitly signaled
430 * 'rem_intra4x4_pred_mode' */
431 /* 6. mb_pred.Inter = 1 bit for 'motion_prediction_flag_l0' and
432 * 'motion_prediction_flag_l1', when necessary; */
433 /* mvbits LUT for 'mvd_l0' and 'mvd_l1' */
434 /* 7. mb_pred.intra_chroma_pred_mode = LUT mapping intra_chroma_pred_mode to
435 * corresponding ue(v) */
436 /* 8. residual_prediction_flag = 1 bit */
437 /* 9. coded_block_pattern = LUT mapping mbType to corresponding me(v) */
438
439 /* mb_skip_run is assumed to be either 0 or 1 */
440 ps_mb_bits_info->i8_header_bits += 1;
441
442 /* 'base_mode_flag' */
443 if((ENABLE_ILP_MV || ENABLE_IBL_MODE) && u1_spatial_layer_id)
444 {
445 ps_mb_bits_info->i8_header_bits += 1;
446
447 if(ps_mb_info->u1_base_mode_flag)
448 {
449 /* 'residual_prediction_flag' */
450 ps_mb_bits_info->i8_header_bits += isvce_sub_pic_rc_get_res_pred_flag_bits(
451 ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
452
453 /* 'coded_block_pattern' */
454 ps_mb_bits_info->i8_header_bits +=
455 isvce_sub_pic_rc_get_cbp_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
456
457 return;
458 }
459 }
460
461 /* 'mb_type' */
462 ps_mb_bits_info->i8_header_bits +=
463 isvce_sub_pic_rc_get_mb_type_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
464
465 if(PSKIP == ps_mb_info->u2_mb_type)
466 {
467 return;
468 }
469
470 /* 'mb_pred' */
471 ps_mb_bits_info->i8_header_bits +=
472 isvce_sub_pic_rc_get_mb_pred_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
473
474 /* 'residual_prediction_flag' */
475 ps_mb_bits_info->i8_header_bits +=
476 isvce_sub_pic_rc_get_res_pred_flag_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
477 }
478
isvce_sub_pic_rc_get_tu_residual_bits(svc_sub_pic_rc_variables_t * ps_sub_pic_rc_variables,WORD32 i4_coeff_start_idx,UWORD8 u1_num_coded_coeffs,UWORD8 u1_num_coeffs,bool b_is_chroma)479 static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_tu_residual_bits(
480 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, WORD32 i4_coeff_start_idx,
481 UWORD8 u1_num_coded_coeffs, UWORD8 u1_num_coeffs, bool b_is_chroma)
482 {
483 WORD32 i;
484 UWORD32 u4_num_bits;
485
486 UWORD32 u4_bits = 0;
487 WORD16 *pi2_coeff =
488 ((WORD16 *) ps_sub_pic_rc_variables->s_mb_variables.as_quant_coeffs[b_is_chroma ? UV : Y]
489 .pv_data) +
490 i4_coeff_start_idx;
491
492 if(0 == u1_num_coded_coeffs)
493 {
494 return 0;
495 }
496
497 GETRANGE(u4_num_bits, u1_num_coded_coeffs);
498 u4_bits += u4_num_bits;
499
500 for(i = 0; i < u1_num_coeffs; i++)
501 {
502 if(pi2_coeff[i])
503 {
504 GETRANGE(u4_num_bits, pi2_coeff[i]);
505 u4_bits += u4_num_bits;
506 }
507 }
508 return u4_bits;
509 }
510
ihevce_svc_sub_pic_rc_set_texture_bits(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt)511 static void ihevce_svc_sub_pic_rc_set_texture_bits(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
512 {
513 sub_pic_rc_layer_state_t *ps_layer_state;
514 mb_bits_info_t *ps_mb_bits_info;
515
516 UWORD32 u4_mb_idx;
517 WORD32 i, j;
518
519 svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
520 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
521 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
522 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
523 sub_pic_rc_state_t *ps_sub_pic_rc_state =
524 (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
525 isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
526
527 UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
528 UWORD32 au4_cbps[NUM_SP_COMPONENTS] = {ps_sub_pic_rc_variables->s_mb_variables.u4_cbp & 15,
529 ps_sub_pic_rc_variables->s_mb_variables.u4_cbp >> 4};
530
531 if(0 == ps_sub_pic_rc_variables->s_mb_variables.u4_cbp)
532 {
533 return;
534 }
535
536 if(MIN_TU_SIZE != ps_mb_info->u1_tx_size)
537 {
538 return;
539 }
540
541 ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
542 u4_mb_idx = ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_abscissa +
543 ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_ordinate *
544 (ps_layer_state->i4_wd / MB_SIZE);
545 ps_mb_bits_info = &ps_layer_state->ps_mb_bits_info[u4_mb_idx];
546
547 /* Hypotheses used for texture bits estimation - */
548 /* 1. Only level information is considered. */
549 /* 2. nnz is used as a proxy for coeff_token. */
550 /* 3. Both of the above are assumed coded via i(n). */
551 if(au4_cbps[Y])
552 {
553 /* Y - DC */
554 if(I16x16 == ps_mb_info->u2_mb_type)
555 {
556 ps_mb_bits_info->i8_texture_bits += isvce_sub_pic_rc_get_tu_residual_bits(
557 ps_sub_pic_rc_variables, 0, ps_sub_pic_rc_variables->s_mb_variables.apu1_nnzs[Y][0],
558 NUM_COEFFS_IN_MIN_TU, false);
559 }
560
561 for(i = 0; i < MIN_TU_IN_MB; i++)
562 {
563 if(au4_cbps[Y] & (1 << i))
564 {
565 UWORD32 u4_csbp = (ps_mb_info->u4_csbp >> (4 * i)) & 15;
566
567 for(j = 0; j < NUM_4x4_IN_8x8; j++)
568 {
569 if(u4_csbp & (1 << j))
570 {
571 /* 1 added to account for DC TU */
572 UWORD8 u1_blk_id = 1 + gau4_tu_zscan_id_to_rasterscan_id_map[i][j];
573 UWORD8 u1_nnz =
574 ps_sub_pic_rc_variables->s_mb_variables.apu1_nnzs[Y][u1_blk_id];
575
576 if(u1_nnz && (I16x16 == ps_mb_info->u2_mb_type))
577 {
578 u1_nnz -= !!(((WORD16 *) (ps_sub_pic_rc_variables->s_mb_variables
579 .as_quant_coeffs[Y]
580 .pv_data))[u1_blk_id - 1]);
581
582 ps_mb_bits_info->i8_texture_bits +=
583 isvce_sub_pic_rc_get_tu_residual_bits(
584 ps_sub_pic_rc_variables,
585 u1_blk_id * ps_sub_pic_rc_variables->s_mb_variables
586 .as_quant_coeffs[Y]
587 .i4_data_stride +
588 (I16x16 == ps_mb_info->u2_mb_type),
589 u1_nnz,
590 NUM_COEFFS_IN_MIN_TU - (I16x16 == ps_mb_info->u2_mb_type),
591 false);
592 }
593 }
594 }
595 }
596 }
597 }
598
599 if(au4_cbps[UV])
600 {
601 for(i = ((WORD32) U); i <= ((WORD32) V); i++)
602 {
603 bool b_is_v = (i == ((WORD32) V));
604
605 ps_mb_bits_info->i8_texture_bits += isvce_sub_pic_rc_get_tu_residual_bits(
606 ps_sub_pic_rc_variables, b_is_v * NUM_4x4_IN_8x8,
607 ps_sub_pic_rc_variables->s_mb_variables
608 .apu1_nnzs[UV][0 + b_is_v * (1 + NUM_4x4_IN_8x8)],
609 NUM_4x4_IN_8x8, true);
610
611 for(j = 0; j < NUM_4x4_IN_8x8; j++)
612 {
613 UWORD8 u1_nnz = ps_sub_pic_rc_variables->s_mb_variables
614 .apu1_nnzs[UV][j + b_is_v * (1 + NUM_4x4_IN_8x8) + 1];
615
616 if(u1_nnz)
617 {
618 u1_nnz -=
619 !!(((WORD16 *) (ps_sub_pic_rc_variables->s_mb_variables.as_quant_coeffs[UV]
620 .pv_data))[j + b_is_v * NUM_4x4_IN_8x8]);
621
622 ps_mb_bits_info->i8_texture_bits += isvce_sub_pic_rc_get_tu_residual_bits(
623 ps_sub_pic_rc_variables,
624 (j + b_is_v * NUM_4x4_IN_8x8 + 1) *
625 ps_sub_pic_rc_variables->s_mb_variables.as_quant_coeffs[UV]
626 .i4_data_stride +
627 1,
628 u1_nnz, NUM_COEFFS_IN_MIN_TU - 1, true);
629 }
630 }
631 }
632 }
633 }
634
isvce_sub_pic_rc_ctxt_update(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt)635 void isvce_sub_pic_rc_ctxt_update(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
636 {
637 sub_pic_rc_layer_state_t *ps_layer_state;
638 mb_bits_info_t *ps_mb_bits_info;
639
640 UWORD32 u4_mb_idx;
641
642 svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
643 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
644 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
645 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
646 sub_pic_rc_state_t *ps_sub_pic_rc_state =
647 (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
648 isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
649
650 UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
651 bool b_is_skip_mb = (PSKIP == ps_mb_info->u2_mb_type) || (BSKIP == ps_mb_info->u2_mb_type);
652
653 if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
654 {
655 return;
656 }
657
658 ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
659 u4_mb_idx = ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_abscissa +
660 ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_ordinate *
661 (ps_layer_state->i4_wd / MB_SIZE);
662 ps_mb_bits_info = &ps_layer_state->ps_mb_bits_info[u4_mb_idx];
663
664 memset(ps_mb_bits_info, 0, sizeof(ps_mb_bits_info[0]));
665
666 if(!b_is_skip_mb)
667 {
668 ihevce_svc_sub_pic_rc_set_header_bits(ps_sub_pic_rc_ctxt);
669
670 ihevce_svc_sub_pic_rc_set_texture_bits(ps_sub_pic_rc_ctxt);
671 }
672
673 ithread_mutex_lock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
674
675 ps_layer_state->s_cumulative_mb_bits.i8_header_bits += ps_mb_bits_info->i8_header_bits;
676 ps_layer_state->s_cumulative_mb_bits.i8_texture_bits += ps_mb_bits_info->i8_texture_bits;
677 ps_layer_state->u4_num_mbs_sampled++;
678
679 ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
680 }
681
isvce_sub_pic_rc_get_mb_qp(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt,UWORD8 u1_cur_mb_qp)682 UWORD8 isvce_sub_pic_rc_get_mb_qp(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt, UWORD8 u1_cur_mb_qp)
683 {
684 sub_pic_rc_layer_state_t *ps_layer_state;
685
686 DOUBLE d_bit_consumption_ratio;
687 UWORD32 u4_frame_qscale;
688 UWORD8 u1_mb_qp;
689 UWORD32 u4_num_mbs_sampled;
690 WORD32 i4_cumulative_mb_bits;
691
692 svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
693 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
694 svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
695 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
696 sub_pic_rc_state_t *ps_sub_pic_rc_state =
697 (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
698
699 UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
700 UWORD8 u1_frame_qp = ps_sub_pic_rc_variables->s_layer_variables.u1_frame_qp;
701
702 if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
703 {
704 return u1_cur_mb_qp;
705 }
706
707 ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
708
709 ithread_mutex_lock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
710
711 u4_num_mbs_sampled = ps_layer_state->u4_num_mbs_sampled;
712
713 if(u4_num_mbs_sampled <
714 ((UWORD32) ceil(MIN_SAMPLED_MB_RATIO * ((DOUBLE) ps_layer_state->i4_num_mbs))))
715 {
716 ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
717
718 return u1_cur_mb_qp;
719 }
720
721 i4_cumulative_mb_bits = (WORD32) (ps_layer_state->s_cumulative_mb_bits.i8_header_bits +
722 ps_layer_state->s_cumulative_mb_bits.i8_texture_bits);
723
724 if((0 == ps_layer_state->u4_allocated_bits) || (0 == u4_num_mbs_sampled))
725 {
726 d_bit_consumption_ratio = nextafter(BIT_RATIO_FOR_OVERCONSUMPTION, INFINITY);
727 }
728 else
729 {
730 d_bit_consumption_ratio =
731 (((DOUBLE) i4_cumulative_mb_bits) * ((DOUBLE) ps_layer_state->i4_num_mbs)) /
732 (((DOUBLE) ps_layer_state->u4_allocated_bits) * ((DOUBLE) u4_num_mbs_sampled));
733 }
734
735 ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
736
737 if((d_bit_consumption_ratio > BIT_RATIO_FOR_OVERCONSUMPTION) ||
738 (d_bit_consumption_ratio < BIT_RATIO_FOR_UNDERCONSUMPTION))
739 {
740 u4_frame_qscale = ps_layer_state->s_qp_params.pu4_qp_to_qscale_map[u1_frame_qp] *
741 d_bit_consumption_ratio +
742 0.5;
743 u4_frame_qscale = CLIP3(ps_layer_state->s_qp_params.pu4_qp_to_qscale_map[0], MAX_SVC_QSCALE,
744 u4_frame_qscale);
745 u1_mb_qp = ps_layer_state->s_qp_params.pu1_qscale_to_qp_map[u4_frame_qscale];
746 u1_mb_qp = CLIP3(ps_layer_state->s_qp_params.u1_min_qp,
747 ps_layer_state->s_qp_params.u1_max_qp, u1_mb_qp);
748 u1_mb_qp = CLIP3(MAX(MIN_H264_QP, ((WORD16) u1_cur_mb_qp) - MAX_MB_QP_DECREMENT),
749 MIN(MAX_H264_QP, ((WORD16) u1_cur_mb_qp) + MAX_MB_QP_INCREMENT),
750 ((WORD16) u1_mb_qp));
751 /* This ensures mb_qp_delta stays within the interval [-26, 25] */
752 u1_mb_qp = CLIP3(MAX(MIN_H264_QP, ((WORD16) u1_frame_qp) - MAX_FRAME_QP_DECREMENT),
753 MIN(MAX_H264_QP, ((WORD16) u1_frame_qp) + MAX_FRAME_QP_INCREMENT),
754 ((WORD16) u1_mb_qp));
755 }
756 else
757 {
758 u1_mb_qp = u1_cur_mb_qp;
759 }
760
761 {
762 vbv_buf_status_e e_vbv_buf_status;
763 picture_type_e e_rc_pic_type;
764
765 DOUBLE d_est_frame_bits;
766
767 WORD32 i4_num_bits_to_prevent_vbv_underflow;
768
769 d_est_frame_bits = ((DOUBLE) i4_cumulative_mb_bits) * ((DOUBLE) ps_layer_state->i4_num_mbs);
770 d_est_frame_bits /= u4_num_mbs_sampled;
771
772 switch(ps_sub_pic_rc_variables->s_layer_variables.i4_slice_type)
773 {
774 case ISLICE:
775 {
776 e_rc_pic_type = I_PIC;
777 break;
778 }
779 case PSLICE:
780 {
781 e_rc_pic_type = P_PIC;
782 break;
783 }
784 default:
785 {
786 e_rc_pic_type = B_PIC;
787 break;
788 }
789 }
790
791 e_vbv_buf_status =
792 irc_get_buffer_status(ps_layer_state->pv_layer_rc_ctxt, (WORD32) d_est_frame_bits,
793 e_rc_pic_type, &i4_num_bits_to_prevent_vbv_underflow);
794
795 /* This models dec VBV buffer */
796 if(VBV_OVERFLOW == e_vbv_buf_status)
797 {
798 u1_mb_qp--;
799 }
800 else if(VBV_UNDERFLOW == e_vbv_buf_status)
801 {
802 u1_mb_qp++;
803 }
804
805 /* This ensures mb_qp_delta stays within the interval [-26, 25] */
806 u1_mb_qp = CLIP3(ps_layer_state->s_qp_params.u1_min_qp,
807 ps_layer_state->s_qp_params.u1_max_qp, u1_mb_qp);
808 u1_mb_qp = CLIP3(MAX(MIN_H264_QP, ((WORD16) u1_frame_qp) - MAX_FRAME_QP_DECREMENT),
809 MIN(MAX_H264_QP, ((WORD16) u1_frame_qp) + MAX_FRAME_QP_INCREMENT),
810 ((WORD16) u1_mb_qp));
811 }
812
813 return u1_mb_qp;
814 }
815
isvce_sub_pic_rc_get_entropy_data(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt)816 void isvce_sub_pic_rc_get_entropy_data(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
817 {
818 #if DUMP_SUB_PIC_RC_DATA
819 sub_pic_rc_layer_state_t *ps_layer_state;
820
821 UWORD32 u4_mb_idx;
822
823 svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
824 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
825 svc_sub_pic_rc_entropy_variables_t *ps_sub_pic_rc_variables =
826 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_entropy_variables;
827 sub_pic_rc_state_t *ps_sub_pic_rc_state =
828 (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
829
830 UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->u1_spatial_layer_id;
831
832 if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
833 {
834 return;
835 }
836
837 ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
838 u4_mb_idx = ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa +
839 ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate * (ps_layer_state->i4_wd / MB_SIZE);
840
841 ps_layer_state->ps_mb_bits_actual[u4_mb_idx] = ps_sub_pic_rc_variables->s_mb_bits;
842 #else
843 UNUSED(ps_sub_pic_rc_ctxt);
844 #endif
845 }
846
isvce_sub_pic_rc_dump_data(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt)847 void isvce_sub_pic_rc_dump_data(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
848 {
849 #if DUMP_SUB_PIC_RC_DATA
850 WORD32 i, j, k;
851
852 svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
853 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
854 sub_pic_rc_state_t *ps_sub_pic_rc_state =
855 (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
856
857 if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
858 {
859 return;
860 }
861
862 for(i = 0; i < ps_sub_pic_rc_state->s_svc_params.u1_num_spatial_layers; i++)
863 {
864 sub_pic_rc_layer_state_t *ps_layer_state =
865 &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[i];
866
867 for(j = 0; j < (ps_layer_state->i4_ht / MB_SIZE); j++)
868 {
869 for(k = 0; k < (ps_layer_state->i4_wd / MB_SIZE); k++)
870 {
871 mb_bits_info_t *ps_mb_bits_est =
872 &ps_layer_state->ps_mb_bits_info[k + j * (ps_layer_state->i4_wd / MB_SIZE)];
873 mb_bits_info_t *ps_mb_bits_actual =
874 &ps_layer_state->ps_mb_bits_actual[k + j * (ps_layer_state->i4_wd / MB_SIZE)];
875
876 fprintf(ps_layer_state->ps_data_dump_file, "%ld,%ld,%ld,%ld,\n",
877 ps_mb_bits_est->i8_header_bits, ps_mb_bits_est->i8_texture_bits,
878 ps_mb_bits_actual->i8_header_bits, ps_mb_bits_actual->i8_texture_bits);
879 }
880 }
881 }
882 #else
883 UNUSED(ps_sub_pic_rc_ctxt);
884 #endif
885 }
886
isvce_sub_pic_rc_ctxt_delete(svc_sub_pic_rc_ctxt_t * ps_sub_pic_rc_ctxt)887 void isvce_sub_pic_rc_ctxt_delete(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
888 {
889 sub_pic_rc_state_t *ps_sub_pic_rc_state =
890 (sub_pic_rc_state_t *) ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants.pv_state;
891
892 ithread_mutex_destroy(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
893
894 #if DUMP_SUB_PIC_RC_DATA
895 {
896 WORD32 i;
897
898 UWORD8 u1_num_spatial_layers = ps_sub_pic_rc_state->s_svc_params.u1_num_spatial_layers;
899
900 for(i = u1_num_spatial_layers - 1; i >= 0; i--)
901 {
902 sub_pic_rc_layer_state_t *ps_layer_state =
903 &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[i];
904
905 if(ps_layer_state->ps_data_dump_file)
906 {
907 fclose(ps_layer_state->ps_data_dump_file);
908 }
909
910 ps_layer_state->ps_data_dump_file = NULL;
911 }
912 }
913 #endif
914 }
915