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 * @file ihevce_cabac_rdo.c 23 * 24 * @brief 25 * This file contains function definitions for rdopt cabac entropy modules 26 * 27 * @author 28 * ittiam 29 * 30 * @List of Functions 31 * ihevce_entropy_rdo_frame_init() 32 * ihevce_entropy_rdo_ctb_init() 33 * ihevce_entropy_rdo_encode_cu() 34 * ihevce_cabac_rdo_encode_sao() 35 * ihevce_update_best_sao_cabac_state() 36 * ihevce_entropy_update_best_cu_states() 37 * ihevce_entropy_rdo_encode_tu() 38 * ihevce_entropy_rdo_encode_tu_rdoq() 39 * ihevce_entropy_rdo_copy_states() 40 * 41 ****************************************************************************** 42 */ 43 44 /*****************************************************************************/ 45 /* File Includes */ 46 /*****************************************************************************/ 47 /* System include files */ 48 #include <stdio.h> 49 #include <string.h> 50 #include <stdlib.h> 51 #include <assert.h> 52 #include <stdarg.h> 53 #include <math.h> 54 55 /* User include files */ 56 #include "ihevc_typedefs.h" 57 #include "itt_video_api.h" 58 #include "ihevce_api.h" 59 60 #include "rc_cntrl_param.h" 61 #include "rc_frame_info_collector.h" 62 #include "rc_look_ahead_params.h" 63 64 #include "ihevc_defs.h" 65 #include "ihevc_structs.h" 66 #include "ihevc_platform_macros.h" 67 #include "ihevc_deblk.h" 68 #include "ihevc_itrans_recon.h" 69 #include "ihevc_chroma_itrans_recon.h" 70 #include "ihevc_chroma_intra_pred.h" 71 #include "ihevc_intra_pred.h" 72 #include "ihevc_inter_pred.h" 73 #include "ihevc_mem_fns.h" 74 #include "ihevc_padding.h" 75 #include "ihevc_weighted_pred.h" 76 #include "ihevc_sao.h" 77 #include "ihevc_resi_trans.h" 78 #include "ihevc_quant_iquant_ssd.h" 79 #include "ihevc_cabac_tables.h" 80 81 #include "ihevce_defs.h" 82 #include "ihevce_lap_enc_structs.h" 83 #include "ihevce_multi_thrd_structs.h" 84 #include "ihevce_me_common_defs.h" 85 #include "ihevce_had_satd.h" 86 #include "ihevce_error_codes.h" 87 #include "ihevce_bitstream.h" 88 #include "ihevce_cabac.h" 89 #include "ihevce_rdoq_macros.h" 90 #include "ihevce_function_selector.h" 91 #include "ihevce_enc_structs.h" 92 #include "ihevce_entropy_structs.h" 93 #include "ihevce_cmn_utils_instr_set_router.h" 94 #include "ihevce_enc_loop_structs.h" 95 #include "ihevce_cabac_rdo.h" 96 #include "ihevce_trace.h" 97 98 /*****************************************************************************/ 99 /* Function Definitions */ 100 /*****************************************************************************/ 101 102 /** 103 ****************************************************************************** 104 * 105 * @brief Cabac rdopt frame level initialization. 106 * 107 * @par Description 108 * Registers the sps,vps,pps,slice header pointers in rdopt enntropy contexts 109 * and intializes cabac engine (init states) for each init cu and scratch cu 110 * contexts 111 * 112 * @param[inout] ps_rdopt_entropy_ctxt 113 * pointer to rdopt entropy context (handle) 114 * 115 * @param[in] ps_slice_hdr 116 * pointer to current slice header 117 * 118 * @param[in] ps_sps 119 * pointer to active SPS params 120 * 121 * @param[in] ps_pps 122 * pointer to active PPS params 123 * 124 * @param[in] ps_vps 125 * pointer to active VPS params 126 * 127 * @param[in] pu1_cu_skip_top_row 128 * pointer to top row cu skip flags (registered at frame level) 129 * 130 * @return none 131 * 132 ****************************************************************************** 133 */ 134 void ihevce_entropy_rdo_frame_init( 135 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, 136 slice_header_t *ps_slice_hdr, 137 pps_t *ps_pps, 138 sps_t *ps_sps, 139 vps_t *ps_vps, 140 UWORD8 *pu1_cu_skip_top_row, 141 rc_quant_t *ps_rc_quant_ctxt) 142 { 143 WORD32 slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp; 144 145 /* Initialize the CTB size from sps parameters */ 146 WORD32 log2_ctb_size = 147 ps_sps->i1_log2_min_coding_block_size + ps_sps->i1_log2_diff_max_min_coding_block_size; 148 149 WORD32 cabac_init_idc; 150 151 (void)ps_rc_quant_ctxt; 152 /* sanity checks */ 153 ASSERT((log2_ctb_size >= 3) && (log2_ctb_size <= 6)); 154 ASSERT((slice_qp >= ps_rc_quant_ctxt->i2_min_qp) && (slice_qp <= ps_rc_quant_ctxt->i2_max_qp)); 155 156 /* register the sps,vps,pps, slice header pts in all cu entropy ctxts */ 157 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_vps = ps_vps; 158 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_sps = ps_sps; 159 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_pps = ps_pps; 160 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_slice_hdr = ps_slice_hdr; 161 162 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].ps_vps = ps_vps; 163 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].ps_sps = ps_sps; 164 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].ps_pps = ps_pps; 165 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].ps_slice_hdr = ps_slice_hdr; 166 167 /* initialze the skip cu top row ptrs for all rdo entropy contexts */ 168 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].pu1_skip_cu_top = pu1_cu_skip_top_row; 169 170 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].pu1_skip_cu_top = pu1_cu_skip_top_row; 171 172 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i1_log2_ctb_size = log2_ctb_size; 173 174 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i1_log2_ctb_size = log2_ctb_size; 175 176 /* initialze the skip cu left flagd for all rdo entropy contexts */ 177 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].u4_skip_cu_left = 0; 178 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].u4_skip_cu_left = 0; 179 180 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i1_ctb_num_pcm_blks = 0; 181 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i1_ctb_num_pcm_blks = 0; 182 183 /* residue encoding should be enaled if ZERO_CBF eval is disabled */ 184 #if((!RDOPT_ZERO_CBF_ENABLE) && (RDOPT_ENABLE)) 185 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i4_enable_res_encode = 1; 186 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i4_enable_res_encode = 1; 187 #else 188 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i4_enable_res_encode = 0; 189 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i4_enable_res_encode = 0; 190 #endif 191 192 /*************************************************************************/ 193 /* Note pu1_cbf_cb, pu1_cbf_cr initialization are done with array idx 1 */ 194 /* This is because these flags are accessed as pu1_cbf_cb[tfr_depth - 1] */ 195 /* without cheking for tfr_depth= 0 */ 196 /*************************************************************************/ 197 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cb[0] = 198 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cb[0][1]; 199 200 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cb[0] = 201 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cb[0][1]; 202 203 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cr[0] = 204 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cr[0][1]; 205 206 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cr[0] = 207 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cr[0][1]; 208 209 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cb[1] = 210 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cb[1][1]; 211 212 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cb[1] = 213 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cb[1][1]; 214 215 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cr[1] = 216 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cr[1][1]; 217 218 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cr[1] = 219 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cr[1][1]; 220 221 memset( 222 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cb, 223 0, 224 (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8)); 225 226 memset( 227 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cb, 228 0, 229 (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8)); 230 231 memset( 232 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cr, 233 0, 234 (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8)); 235 236 memset( 237 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cr, 238 0, 239 (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8)); 240 241 /* initialize the cabac init idc based on slice type */ 242 if(ps_slice_hdr->i1_slice_type == ISLICE) 243 { 244 cabac_init_idc = 0; 245 } 246 else if(ps_slice_hdr->i1_slice_type == PSLICE) 247 { 248 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 2 : 1; 249 } 250 else 251 { 252 cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 1 : 2; 253 } 254 255 /* all the entropy contexts in rdo initialized in bit compute mode */ 256 ihevce_cabac_init( 257 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].s_cabac_ctxt, 258 NULL, /* bitstream buffer not required in bits compute mode */ 259 CLIP3(slice_qp, 0, IHEVC_MAX_QP), 260 cabac_init_idc, 261 CABAC_MODE_COMPUTE_BITS); 262 263 ihevce_cabac_init( 264 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].s_cabac_ctxt, 265 NULL, /* bitstream buffer not required in bits compute mode */ 266 CLIP3(slice_qp, 0, IHEVC_MAX_QP), 267 cabac_init_idc, 268 CABAC_MODE_COMPUTE_BITS); 269 270 /* initialize the entropy states in rdopt struct */ 271 COPY_CABAC_STATES( 272 &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0], 273 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].s_cabac_ctxt.au1_ctxt_models[0], 274 sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states)); 275 } 276 277 /** 278 ****************************************************************************** 279 * 280 * @brief Cabac rdopt ctb level initialization. 281 * 282 * @par Description 283 * initialzes the ctb x and y co-ordinates for all the rdopt entropy contexts 284 * 285 * @param[inout] ps_rdopt_entropy_ctxt 286 * pointer to rdopt entropy context (handle) 287 * 288 * @param[in] ctb_x 289 * current ctb x offset w.r.t frame start (ctb units) 290 * 291 * @param[in] ctb_y 292 * current ctb y offset w.r.t frame start (ctb units) 293 * 294 * @return none 295 * 296 ****************************************************************************** 297 */ 298 void ihevce_entropy_rdo_ctb_init( 299 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, WORD32 ctb_x, WORD32 ctb_y) 300 { 301 /* initialze the ctb x and y co-ordinates for all the rdopt entropy contexts */ 302 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i4_ctb_x = ctb_x; 303 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i4_ctb_x = ctb_x; 304 305 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i4_ctb_y = ctb_y; 306 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i4_ctb_y = ctb_y; 307 } 308 309 /** 310 ****************************************************************************** 311 * 312 * @brief Cabac rdopt cu encode function to compute luma bits for a given cu 313 * only luma bits are used for rd optimization currently 314 * 315 * @par Description 316 * use a scratch CU entropy context (indicated by rdopt_buf_idx) whose cabac 317 * states are reset (to CU init state) and calls the cabac entropy coding 318 * unit function to compute the total bits for current CU 319 * 320 * A local CU structutre is prepared (in stack) as the structures that entropy 321 * encode expects and the rdopt gets are different 322 * 323 * @param[inout] ps_rdopt_entropy_ctxt 324 * pointer to rdopt entropy context (handle) 325 * 326 * @param[in] ps_cu_prms 327 * pointer to current CU params whose bits are computed 328 * 329 * @param[in] cu_pos_x 330 * current CU x position w.r.t ctb (in 8x8 units) 331 * 332 * @param[in] cu_pos_y 333 * current CU y position w.r.t ctb (in 8x8 units) 334 * 335 * @param[in] cu_size 336 * current cu size (in pel units) 337 * 338 * @param[in] top_avail 339 * top avaialability flag for current CU (required for encoding skip flag) 340 * 341 * @param[in] left_avail 342 * left avaialability flag for current CU (required for encoding skip flag) 343 * 344 * @param[in] pv_ecd_coeff 345 * Compressed coeff residue buffer (for luma) 346 * 347 * @param[in] rdopt_buf_idx 348 * corresponds to the id of the scratch CU entropy context that needs to be 349 * used for bit estimation 350 * 351 * @param[out] pi4_cu_rdopt_tex_bits 352 * returns cbf bits if zer0 cbf eval flag is enabled otherwiese returns total 353 * tex(including cbf bits) 354 * 355 * @return total bits required to encode the current CU 356 * 357 ****************************************************************************** 358 */ 359 WORD32 ihevce_entropy_rdo_encode_cu( 360 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, 361 enc_loop_cu_final_prms_t *ps_cu_prms, 362 WORD32 cu_pos_x, 363 WORD32 cu_pos_y, 364 WORD32 cu_size, 365 WORD32 top_avail, 366 WORD32 left_avail, 367 void *pv_ecd_coeff, 368 WORD32 *pi4_cu_rdopt_tex_bits) 369 { 370 /* local cu structure for passing to entrop encode cu module */ 371 cu_enc_loop_out_t s_enc_cu; 372 WORD32 rdopt_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx; 373 374 entropy_context_t *ps_cur_cu_entropy = 375 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[rdopt_buf_idx]; 376 377 WORD32 total_bits = 0; 378 379 WORD32 log2_ctb_size = ps_cur_cu_entropy->i1_log2_ctb_size; 380 WORD32 log2_cu_size; 381 382 WORD32 cu_depth; 383 384 /* sanity checks */ 385 ASSERT((rdopt_buf_idx == 0) || (rdopt_buf_idx == 1)); 386 ASSERT((cu_size >= 8) && (cu_size <= (1 << log2_ctb_size))); 387 ASSERT((cu_pos_x >= 0) && (cu_pos_x <= (1 << (log2_ctb_size - 3)))); 388 ASSERT((cu_pos_y >= 0) && (cu_pos_y <= (1 << (log2_ctb_size - 3)))); 389 390 GETRANGE(log2_cu_size, cu_size); 391 log2_cu_size -= 1; 392 cu_depth = log2_ctb_size - log2_cu_size; 393 394 { 395 /**********************************************************/ 396 /* prepare local cu structure before calling cabac encode */ 397 /**********************************************************/ 398 399 /* default be canged to have orred val*/ 400 s_enc_cu.b1_no_residual_syntax_flag = 0; 401 402 /* initialize cu posx, posy and size */ 403 s_enc_cu.b3_cu_pos_x = cu_pos_x; 404 s_enc_cu.b3_cu_pos_y = cu_pos_y; 405 s_enc_cu.b4_cu_size = (cu_size >> 3); 406 407 /* PCM not supported */ 408 s_enc_cu.b1_pcm_flag = 0; 409 s_enc_cu.b1_pred_mode_flag = ps_cu_prms->u1_intra_flag; 410 s_enc_cu.b3_part_mode = ps_cu_prms->u1_part_mode; 411 412 s_enc_cu.b1_skip_flag = ps_cu_prms->u1_skip_flag; 413 s_enc_cu.b1_tq_bypass_flag = 0; 414 s_enc_cu.pv_coeff = pv_ecd_coeff; 415 416 /* store the number of TUs */ 417 s_enc_cu.u2_num_tus_in_cu = ps_cu_prms->u2_num_tus_in_cu; 418 419 /* ---- intialize the PUs and TUs start ptrs for cur CU ----- */ 420 s_enc_cu.ps_pu = &ps_cu_prms->as_pu_enc_loop[0]; 421 s_enc_cu.ps_enc_tu = &ps_cu_prms->as_tu_enc_loop[0]; 422 423 /* Corner case : If Part is 2Nx2N and Merge has all TU with zero cbf */ 424 /* then it has to be coded as skip CU */ 425 if((SIZE_2Nx2N == ps_cu_prms->u1_part_mode) && 426 /*(1 == ps_cu_prms->u2_num_tus_in_cu) &&*/ 427 (1 == ps_cu_prms->as_pu_enc_loop[0].b1_merge_flag) && (0 == ps_cu_prms->u1_skip_flag) && 428 (0 == ps_cu_prms->u1_is_cu_coded)) 429 { 430 s_enc_cu.b1_skip_flag = 1; 431 } 432 433 if(s_enc_cu.b1_pred_mode_flag == PRED_MODE_INTER) 434 { 435 s_enc_cu.b1_no_residual_syntax_flag = !ps_cu_prms->u1_is_cu_coded; 436 } 437 else /* b1_pred_mode_flag == PRED_MODE_INTRA */ 438 { 439 /* copy prev_mode_flag, mpm_idx and rem_intra_pred_mode for each PU */ 440 memcpy( 441 &s_enc_cu.as_prev_rem[0], 442 &ps_cu_prms->as_intra_prev_rem[0], 443 ps_cu_prms->u2_num_tus_in_cu * sizeof(intra_prev_rem_flags_t)); 444 445 s_enc_cu.b3_chroma_intra_pred_mode = ps_cu_prms->u1_chroma_intra_pred_mode; 446 } 447 } 448 449 /* reset the total bits in cabac engine to zero */ 450 ps_cur_cu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0; 451 ps_cur_cu_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 = 0; 452 ps_cur_cu_entropy->s_cabac_ctxt.u4_cbf_bits_q12 = 0; 453 ps_cur_cu_entropy->i1_encode_qp_delta = 0; 454 455 /* Call the cabac encode function of current cu to compute bits */ 456 ihevce_cabac_encode_coding_unit(ps_cur_cu_entropy, &s_enc_cu, cu_depth, top_avail, left_avail); 457 458 /* return total bits after rounding the fractional bits */ 459 total_bits = 460 (ps_cur_cu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >> 461 CABAC_FRAC_BITS_Q; 462 #if RDOPT_ZERO_CBF_ENABLE 463 ASSERT(ps_cur_cu_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 == 0); 464 #endif 465 /* return total texture bits rounding the fractional bits */ 466 *pi4_cu_rdopt_tex_bits = 467 (ps_cur_cu_entropy->s_cabac_ctxt.u4_cbf_bits_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >> 468 CABAC_FRAC_BITS_Q; 469 470 /* ( ps_cur_cu_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 + 471 (1 << (CABAC_FRAC_BITS_Q - 1)) 472 ) >> CABAC_FRAC_BITS_Q;*/ 473 474 return (total_bits); 475 } 476 477 /** 478 ****************************************************************************** 479 * 480 * @brief Cabac rdo encode sao function to compute bits required for a given 481 * ctb to be encoded with any sao type or no SAO. 482 * 483 * @par Description 484 * use a scratch CU entropy context (indicated by rdopt_buf_idx) and init cabac 485 * states are reset (to CU init state) and calls the cabac encode sao 486 * function to compute the total bits for current CTB 487 * 488 * @param[inout] ps_rdopt_entropy_ctxt 489 * pointer to rdopt entropy context (handle) 490 * 491 * @param[in] ps_ctb_enc_loop_out 492 * pointer to current enc loop CTB output structure 493 * 494 * @return total bits required to encode the current CTB 495 * 496 ****************************************************************************** 497 */ 498 WORD32 ihevce_cabac_rdo_encode_sao( 499 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, ctb_enc_loop_out_t *ps_ctb_enc_loop_out) 500 { 501 /* index to curr buf*/ 502 WORD32 rdopt_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx; 503 WORD32 total_bits = 0; 504 entropy_context_t *ps_cur_ctb_entropy = 505 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[rdopt_buf_idx]; 506 507 /* copy the intial entropy states from backuped buf to curr buf */ 508 memcpy( 509 &ps_cur_ctb_entropy->s_cabac_ctxt.au1_ctxt_models[0], 510 &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0], 511 sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states)); 512 513 /* reset the total bits in cabac engine to zero */ 514 ps_cur_ctb_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0; 515 ps_cur_ctb_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 = 0; 516 ps_cur_ctb_entropy->s_cabac_ctxt.u4_cbf_bits_q12 = 0; 517 ps_cur_ctb_entropy->i1_encode_qp_delta = 0; 518 //ps_cur_ctb_entropy->s_cabac_ctxt.u4_range = 0; 519 520 ASSERT(ps_cur_ctb_entropy->s_cabac_ctxt.u4_range == 0); 521 ihevce_cabac_encode_sao(ps_cur_ctb_entropy, ps_ctb_enc_loop_out); 522 523 /* return total bits after rounding the fractional bits */ 524 total_bits = 525 (ps_cur_ctb_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >> 526 CABAC_FRAC_BITS_Q; 527 528 return (total_bits); 529 } 530 531 /** 532 ****************************************************************************** 533 * 534 * @brief Updates best sao cabac state. 535 * 536 * @par Description 537 * Copies the cabac states of best cand to init states buf for next ctb. 538 * 539 * @param[inout] ps_rdopt_entropy_ctxt 540 * pointer to rdopt entropy context (handle) 541 * 542 * @param[in] i4_best_buf_idx 543 * Index to the buffer having the cabac states of best candidate 544 * 545 * @return Success/failure 546 * 547 ****************************************************************************** 548 */ 549 WORD32 ihevce_update_best_sao_cabac_state( 550 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, WORD32 i4_best_buf_idx) 551 { 552 /* local cu structure for passing to entrop encode cu module */ 553 WORD32 rdopt_buf_idx = i4_best_buf_idx; 554 entropy_context_t *ps_cur_ctb_entropy = 555 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[rdopt_buf_idx]; 556 557 /* copy the intial entropy states from best buf to intial states buf */ 558 memcpy( 559 &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0], 560 &ps_cur_ctb_entropy->s_cabac_ctxt.au1_ctxt_models[0], 561 sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states)); 562 563 /* reset the total bits in cabac engine to zero */ 564 ps_cur_ctb_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0; 565 ps_cur_ctb_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 = 0; 566 ps_cur_ctb_entropy->s_cabac_ctxt.u4_cbf_bits_q12 = 0; 567 ps_cur_ctb_entropy->i1_encode_qp_delta = 0; 568 569 return (1); 570 } 571 572 /** 573 ****************************************************************************** 574 * 575 * @brief Cabac rdopt cu encode function to compute luma bits for a given cu 576 * only luma bits are used for rd optimization currently 577 * 578 * @par Description 579 * use a scratch CU entropy context (indicated by rdopt_buf_idx) whose cabac 580 * states are reset (to CU init state) and calls the cabac entropy coding 581 * unit function to compute the total bits for current CU 582 * 583 * A local CU structutre is prepared (in stack) as the structures that entropy 584 * encode expects and the rdopt gets are different 585 * 586 * @param[inout] ps_rdopt_entropy_ctxt 587 * pointer to rdopt entropy context (handle) 588 * 589 * @param[in] cu_pos_x 590 * current CU x position w.r.t ctb (in 8x8 units) 591 * 592 * @param[in] cu_pos_y 593 * current CU y position w.r.t ctb (in 8x8 units) 594 * 595 * @param[in] cu_size 596 * current cu size (in pel units) 597 * 598 * @param[in] rdopt_best_cu_idx 599 * id of the best CU entropy ctxt (rdopt winner candidate) 600 * 601 * @return total bits required to encode the current CU 602 * 603 ****************************************************************************** 604 */ 605 void ihevce_entropy_update_best_cu_states( 606 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, 607 WORD32 cu_pos_x, 608 WORD32 cu_pos_y, 609 WORD32 cu_size, 610 WORD32 cu_skip_flag, 611 WORD32 rdopt_best_cu_idx) 612 { 613 entropy_context_t *ps_best_cu_entropy = 614 &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[rdopt_best_cu_idx]; 615 616 /* CTB x co-ordinate w.r.t frame start */ 617 WORD32 ctb_x0_frm = (ps_best_cu_entropy->i4_ctb_x << ps_best_cu_entropy->i1_log2_ctb_size); 618 619 /* CU x co-ordinate w.r.t frame start */ 620 WORD32 cu_x0_frm = cu_pos_x + ctb_x0_frm; 621 622 /* bit postion from where top skip flag is extracted; 1bit per 8 pel */ 623 WORD32 x_pos = ((cu_x0_frm >> 3) & 0x7); 624 625 /* bit postion from where left skip flag is extracted; 1bit per 8 pel */ 626 WORD32 y_pos = ((cu_pos_y >> 3) & 0x7); 627 628 /* top and left skip flags computed based on nbr availability */ 629 UWORD8 *pu1_top_skip_flags = ps_best_cu_entropy->pu1_skip_cu_top + (cu_x0_frm >> 6); 630 631 UWORD32 u4_skip_left_flags = ps_best_cu_entropy->u4_skip_cu_left; 632 633 ps_best_cu_entropy = &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[rdopt_best_cu_idx]; 634 635 /* copy the entropy states from best rdopt cu states to init states */ 636 COPY_CABAC_STATES( 637 &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0], 638 &ps_best_cu_entropy->s_cabac_ctxt.au1_ctxt_models[0], 639 sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states)); 640 641 /* replicate skip flag in left and top row cu skip flags */ 642 if(cu_skip_flag) 643 { 644 SET_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3)); 645 SET_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3)); 646 } 647 else 648 { 649 CLEAR_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3)); 650 CLEAR_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3)); 651 } 652 653 /* copy the left skip flags in both the rdopt contexts */ 654 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].u4_skip_cu_left = 655 ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].u4_skip_cu_left = u4_skip_left_flags; 656 } 657 658 /** 659 ****************************************************************************** 660 * 661 * @brief Cabac rdopt tu encode function to compute luma bits for a given tu 662 * only luma bits are used for rd optimization currently 663 * 664 * @par Description 665 * use a scratch CU entropy context (indicated by rdopt_buf_idx) whose cabac 666 * states are reset (to CU init state for first tu) and calls the cabac residue 667 * coding function to compute the total bits for current TU 668 * 669 * Note : TU includes only residual coding bits and does not include 670 * tu split, cbf and qp delta encoding bits for a TU 671 * 672 * @param[inout] ps_rdopt_entropy_ctxt 673 * pointer to rdopt entropy context (handle) 674 * 675 * @param[in] pv_ecd_coeff 676 * Compressed coeff residue buffer (for luma) 677 * 678 * @param[in] transform_size 679 * current tu size in pel units 680 * 681 * @param[in] is_luma 682 * indicates if it is luma or chrom TU (required for residue encode) 683 * 684 * @return total bits required to encode the current TU 685 * 686 ****************************************************************************** 687 */ 688 WORD32 ihevce_entropy_rdo_encode_tu( 689 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, 690 void *pv_ecd_coeff, 691 WORD32 transform_size, 692 WORD32 is_luma, 693 WORD32 perform_sbh) 694 { 695 WORD32 log2_tfr_size; 696 WORD32 total_bits = 0; 697 WORD32 curr_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx; 698 entropy_context_t *ps_cur_tu_entropy; 699 700 ps_cur_tu_entropy = &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[curr_buf_idx]; 701 702 ASSERT((transform_size >= 4) && (transform_size <= 32)); 703 704 /* transform size to log2transform size */ 705 GETRANGE(log2_tfr_size, transform_size); 706 log2_tfr_size -= 1; 707 708 /* reset the total bits in cabac engine to zero */ 709 ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0; 710 ps_cur_tu_entropy->i1_encode_qp_delta = 0; 711 712 /* Call the cabac residue encode function to compute TU bits */ 713 ihevce_cabac_residue_encode_rdopt( 714 ps_cur_tu_entropy, pv_ecd_coeff, log2_tfr_size, is_luma, perform_sbh); 715 716 /* return total bits after rounding the fractional bits */ 717 total_bits = 718 (ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >> 719 CABAC_FRAC_BITS_Q; 720 721 return (total_bits); 722 } 723 724 /** 725 ****************************************************************************** 726 * 727 * @brief Cabac rdopt tu encode function to compute bits for a given tu. Actual 728 * RDOQ algorithm is performed by the ihevce_cabac_residue_encode_rdoq function 729 * called by this function. 730 * 731 * @par Description 732 * use a scratch CU entropy context (indicated by rdopt_buf_idx) whose cabac 733 * states are reset (to CU init state for first tu) and calls the cabac residue 734 * coding function to compute the total bits for current TU 735 * 736 * Note : TU includes only residual coding bits and does not include 737 * tu split, cbf and qp delta encoding bits for a TU 738 * 739 * @param[inout] ps_rdopt_entropy_ctxt 740 * pointer to rdopt entropy context (handle) 741 * 742 * @param[in] pv_ecd_coeff 743 * Compressed coeff residue buffer 744 * 745 * @param[in] transform_size 746 * current tu size in pel units 747 * 748 * @param[in] first_tu_of_cu 749 * indicates if the tu is the first unit of cu (required for initializing 750 * cabac ctxts) 751 * 752 * @param[in] rdopt_buf_idx 753 * corresponds to the id of the rdopt CU entropy context that needs to be 754 * used for bit estimation 755 * 756 * @param[in] is_luma 757 * indicates if it is luma or chrom TU (required for residue encode) 758 * 759 * @param[in] intra_nxn_mode 760 * indicates if it is luma or chrom TU (required for residue encode) 761 * 762 * @param[inout] ps_rdoq_ctxt 763 * pointer to rdoq context structure 764 * 765 * @param[inout] pi4_coded_tu_dist 766 * Pointer to the variable which will contain the transform domain distortion 767 * of the entire TU, when any of the coeffs in the TU are coded 768 * 769 * @param[inout] pi4_not_coded_tu_dist 770 * Pointer to the variable which will contain the transform domain distortion 771 * of the enture TU, when all the coeffs in the TU are coded 772 * 773 * @return total bits required to encode the current TU 774 * 775 ****************************************************************************** 776 */ 777 WORD32 ihevce_entropy_rdo_encode_tu_rdoq( 778 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, 779 void *pv_ecd_coeff, 780 WORD32 transform_size, 781 WORD32 is_luma, 782 rdoq_sbh_ctxt_t *ps_rdoq_ctxt, 783 LWORD64 *pi8_coded_tu_dist, 784 LWORD64 *pi8_not_coded_tu_dist, 785 WORD32 perform_sbh) 786 { 787 WORD32 log2_tfr_size; 788 WORD32 total_bits = 0; 789 WORD32 curr_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx; 790 entropy_context_t *ps_cur_tu_entropy; 791 792 ps_cur_tu_entropy = &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[curr_buf_idx]; 793 794 ASSERT((transform_size >= 4) && (transform_size <= 32)); 795 796 /* transform size to log2transform size */ 797 GETRANGE(log2_tfr_size, transform_size); 798 log2_tfr_size -= 1; 799 800 /* reset the total bits in cabac engine to zero */ 801 ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0; 802 ps_cur_tu_entropy->i1_encode_qp_delta = 0; 803 804 /* Call the cabac residue encode function to compute TU bits */ 805 ihevce_cabac_residue_encode_rdoq( 806 ps_cur_tu_entropy, 807 pv_ecd_coeff, 808 log2_tfr_size, 809 is_luma, 810 (void *)ps_rdoq_ctxt, 811 pi8_coded_tu_dist, 812 pi8_not_coded_tu_dist, 813 perform_sbh); 814 815 /* return total bits after rounding the fractional bits */ 816 total_bits = 817 (ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >> 818 CABAC_FRAC_BITS_Q; 819 820 return (total_bits); 821 } 822 823 /** 824 ****************************************************************************** 825 * 826 * @brief Cabac rdopt copy functions for copying states (which will be used later) 827 * 828 * @par Description 829 * Does the HEVC style of entropy sync by copying the state to/from rdo context 830 * from/to row level cabac states at start of row/2nd ctb of row 831 * 832 * Caller needs to make sure UPDATE_ENT_SYNC_RDO_STATE is used for first ctb of 833 * every row (leaving first row of slice) and STORE_ENT_SYNC_RDO_STATE is used for 834 * storing the cabac states at the end of 2nd ctb of a row. 835 * 836 * @param[inout] ps_rdopt_entropy_ctxt 837 * pointer to rdopt entropy context (handle) 838 * 839 * @param[in] pu1_entropy_sync_states 840 * pointer to entropy sync cabac states 841 * 842 * @param[in] copy_mode 843 * mode of copying cabac states. Shall be either UPDATE_ENT_SYNC_RDO_STATE and 844 * STORE_ENT_SYNC_RDO_STATE 845 * 846 ****************************************************************************** 847 */ 848 void ihevce_entropy_rdo_copy_states( 849 rdopt_entropy_ctxt_t *ps_rdopt_entropy_ctxt, UWORD8 *pu1_entropy_sync_states, WORD32 copy_mode) 850 { 851 /* sanity checks */ 852 ASSERT((copy_mode == STORE_ENT_SYNC_RDO_STATE) || (copy_mode == UPDATE_ENT_SYNC_RDO_STATE)); 853 854 if(STORE_ENT_SYNC_RDO_STATE == copy_mode) 855 { 856 COPY_CABAC_STATES( 857 pu1_entropy_sync_states, 858 &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0], 859 IHEVC_CAB_CTXT_END); 860 } 861 else if(UPDATE_ENT_SYNC_RDO_STATE == copy_mode) 862 { 863 COPY_CABAC_STATES( 864 &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0], 865 pu1_entropy_sync_states, 866 IHEVC_CAB_CTXT_END); 867 } 868 } 869