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_enc_sbh_funcs.c 24 * 25 * \brief 26 * This file contains utility functions for sbh 27 * 28 * \date 29 * 31/08/2012 30 * 31 * \author 32 * Ittiam 33 * 34 * List of Functions 35 * ihevce_sign_data_hiding() 36 * 37 ****************************************************************************** 38 */ 39 40 /*****************************************************************************/ 41 /* File Includes */ 42 /*****************************************************************************/ 43 /* System include files */ 44 #include <stdio.h> 45 #include <string.h> 46 #include <stdlib.h> 47 #include <assert.h> 48 #include <stdarg.h> 49 #include <math.h> 50 51 /* User include files */ 52 #include "ihevc_typedefs.h" 53 #include "itt_video_api.h" 54 #include "ihevce_api.h" 55 56 #include "rc_cntrl_param.h" 57 #include "rc_frame_info_collector.h" 58 #include "rc_look_ahead_params.h" 59 60 #include "ihevc_defs.h" 61 #include "ihevc_structs.h" 62 #include "ihevc_platform_macros.h" 63 #include "ihevc_deblk.h" 64 #include "ihevc_itrans_recon.h" 65 #include "ihevc_chroma_itrans_recon.h" 66 #include "ihevc_chroma_intra_pred.h" 67 #include "ihevc_intra_pred.h" 68 #include "ihevc_inter_pred.h" 69 #include "ihevc_mem_fns.h" 70 #include "ihevc_padding.h" 71 #include "ihevc_weighted_pred.h" 72 #include "ihevc_sao.h" 73 #include "ihevc_resi_trans.h" 74 #include "ihevc_quant_iquant_ssd.h" 75 #include "ihevc_cabac_tables.h" 76 #include "ihevc_trans_tables.h" 77 #include "ihevc_trans_macros.h" 78 79 #include "ihevce_defs.h" 80 #include "ihevce_lap_enc_structs.h" 81 #include "ihevce_multi_thrd_structs.h" 82 #include "ihevce_multi_thrd_funcs.h" 83 #include "ihevce_me_common_defs.h" 84 #include "ihevce_had_satd.h" 85 #include "ihevce_error_codes.h" 86 #include "ihevce_bitstream.h" 87 #include "ihevce_cabac.h" 88 #include "ihevce_rdoq_macros.h" 89 #include "ihevce_function_selector.h" 90 #include "ihevce_enc_structs.h" 91 #include "ihevce_global_tables.h" 92 #include "ihevce_enc_sbh_utils.h" 93 94 /*****************************************************************************/ 95 /* Function Definitions */ 96 /*****************************************************************************/ 97 98 /** 99 ******************************************************************************* 100 * 101 * @brief 102 * This function find the coefficient that needs to be modified for SBH 103 * for each sub block, if required 104 * 105 * @par Description: 106 * Checks the validity for applying SBH 107 * 108 * @param[inout] ps_rdoq_sbh_params 109 * All the necessary parameters for SBH 110 * 111 * @returns None 112 * 113 * @remarks None 114 * 115 ******************************************************************************** 116 */ 117 void ihevce_sign_data_hiding(rdoq_sbh_ctxt_t *ps_rdoq_sbh_params) 118 { 119 WORD32 i, trans_unit_idx; 120 UWORD8 *pu1_trans_table = NULL; 121 UWORD8 *pu1_csb_table; 122 WORD32 shift_value, mask_value; 123 WORD32 blk_row, blk_col; 124 125 WORD32 x_pos, y_pos; 126 WORD16 i2_quant_coeff; 127 WORD32 best_pos = -1; 128 129 WORD16 *pi2_quant_coeffs = ps_rdoq_sbh_params->pi2_quant_coeffs; 130 WORD16 *pi2_iquant_data = ps_rdoq_sbh_params->pi2_iquant_coeffs; 131 WORD16 *pi2_tr_coeffs = ps_rdoq_sbh_params->pi2_trans_values; 132 WORD32 *pi4_subBlock2csbfId_map = ps_rdoq_sbh_params->pi4_subBlock2csbfId_map; 133 WORD16 *pi2_dequant_coeff = ps_rdoq_sbh_params->pi2_dequant_coeff; 134 UWORD8 *pu1_csbf_buf = ps_rdoq_sbh_params->pu1_csbf_buf; 135 WORD32 dst_iq_strd = ps_rdoq_sbh_params->i4_iq_data_strd; 136 WORD32 dst_q_strd = ps_rdoq_sbh_params->i4_q_data_strd; 137 138 WORD32 scan_idx = ps_rdoq_sbh_params->i4_scan_idx; 139 WORD32 qp_div = ps_rdoq_sbh_params->i4_qp_div; 140 WORD32 trans_size = ps_rdoq_sbh_params->i4_trans_size; 141 WORD32 qp_rem = ps_rdoq_sbh_params->i2_qp_rem; 142 LWORD64 ssd_cost = ps_rdoq_sbh_params->i8_ssd_cost; 143 144 WORD32 last_cg = -1; 145 146 WORD32 log2_size, bit_depth, shift_iq; 147 148 GETRANGE(log2_size, trans_size); 149 log2_size -= 1; 150 bit_depth = ps_rdoq_sbh_params->i4_bit_depth; 151 shift_iq = bit_depth + log2_size - 5; 152 153 /* Select proper order for your transform unit and csb based on scan_idx*/ 154 /* and the trans_size */ 155 156 /* scan order inside a csb */ 157 pu1_csb_table = (UWORD8 *)&(g_u1_scan_table_4x4[scan_idx][0]); 158 159 /* GETRANGE will give the log_2 of trans_size to shift_value */ 160 GETRANGE(shift_value, trans_size); 161 shift_value = shift_value - 3; /* for finding. row no. from scan index */ 162 mask_value = (trans_size / 4) - 1; /*for finding the col. no. from scan index*/ 163 switch(trans_size) 164 { 165 case 32: 166 pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_8x8[scan_idx][0]); 167 break; 168 case 16: 169 pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_4x4[scan_idx][0]); 170 break; 171 case 8: 172 pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_2x2[scan_idx][0]); 173 break; 174 case 4: 175 pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_1x1[0]); 176 break; 177 default: 178 ASSERT(0); 179 break; 180 } 181 for(trans_unit_idx = (trans_size * trans_size / 16) - 1; trans_unit_idx >= 0; trans_unit_idx--) 182 { 183 WORD32 last_scan_pos = -1, first_scan_pos = 16, sign_first_coeff, sum_abs_level = 0, 184 quant_coeff_first; 185 186 if(pu1_csbf_buf[pi4_subBlock2csbfId_map[pu1_trans_table[trans_unit_idx]]]) 187 { 188 /* row of csb */ 189 blk_row = (pu1_trans_table[trans_unit_idx] >> shift_value) * 4; 190 /* col of csb */ 191 blk_col = (pu1_trans_table[trans_unit_idx] & mask_value) * 4; 192 193 if(last_cg == -1) 194 { 195 last_cg = 1; 196 } 197 198 for(i = 15; i >= 0; i--) 199 { 200 x_pos = (pu1_csb_table[i] & 0x3) + blk_col; 201 y_pos = (pu1_csb_table[i] >> 2) + blk_row; 202 203 i2_quant_coeff = pi2_quant_coeffs[x_pos + (y_pos * trans_size)]; 204 205 if(i2_quant_coeff) 206 { 207 first_scan_pos = i; 208 if(-1 == last_scan_pos) 209 { 210 last_scan_pos = i; 211 } 212 213 sum_abs_level += abs(i2_quant_coeff); 214 } 215 } 216 217 if((last_scan_pos - first_scan_pos) >= 4) 218 { 219 x_pos = (pu1_csb_table[first_scan_pos] & 0x3) + blk_col; 220 y_pos = (pu1_csb_table[first_scan_pos] >> 2) + blk_row; 221 222 quant_coeff_first = pi2_quant_coeffs[x_pos + (y_pos * trans_size)]; 223 224 sign_first_coeff = (quant_coeff_first > 0) ? 0 : 1; 225 226 if(sign_first_coeff != (sum_abs_level & 0x1)) 227 { 228 WORD32 q_err; 229 WORD32 min_cost = MAX_INT; 230 WORD32 final_change = 0, cur_cost = 0, cur_change = 0; 231 WORD16 i2_tr_coeff; 232 WORD16 i2_iquant_coeff; 233 234 for(i = (last_cg == 1) ? last_scan_pos : 15; i >= 0; i--) 235 { 236 x_pos = (pu1_csb_table[i] & 0x3) + blk_col; 237 y_pos = (pu1_csb_table[i] >> 2) + blk_row; 238 239 i2_quant_coeff = pi2_quant_coeffs[x_pos + (y_pos * trans_size)]; 240 i2_tr_coeff = pi2_tr_coeffs[x_pos + (y_pos * trans_size)]; 241 i2_iquant_coeff = pi2_iquant_data[x_pos + (y_pos * dst_iq_strd)]; 242 243 q_err = abs(i2_tr_coeff) - abs(i2_iquant_coeff); 244 245 if(i2_quant_coeff != 0) 246 { 247 cur_cost = -1 * SIGN(q_err) * q_err; 248 249 if(q_err <= 0) 250 { 251 if(i == first_scan_pos && abs(i2_quant_coeff) == 1) 252 { 253 cur_cost = MAX_INT; 254 } 255 } 256 } 257 else 258 { 259 cur_cost = -q_err; 260 if(i < first_scan_pos) 261 { 262 WORD32 sign_bit = (i2_tr_coeff >= 0 ? 0 : 1); 263 264 if(sign_first_coeff != sign_bit) 265 { 266 cur_cost = MAX_INT; 267 } 268 } 269 } 270 271 cur_change = (i2_quant_coeff == 0) ? 1 : (q_err > 0 ? 1 : -1); 272 273 if(cur_cost < min_cost) 274 { 275 min_cost = cur_cost; 276 final_change = cur_change; 277 best_pos = i; 278 } 279 } 280 if((i2_quant_coeff == 32767) || (i2_quant_coeff == -32768)) 281 { 282 final_change = -1; 283 } 284 285 x_pos = (pu1_csb_table[best_pos] & 0x3) + blk_col; 286 y_pos = (pu1_csb_table[best_pos] >> 2) + blk_row; 287 i2_iquant_coeff = pi2_iquant_data[x_pos + (y_pos * dst_iq_strd)]; 288 i2_tr_coeff = pi2_tr_coeffs[x_pos + (y_pos * trans_size)]; 289 290 if(i2_tr_coeff >= 0) 291 { 292 pi2_quant_coeffs[x_pos + (y_pos * trans_size)] += final_change; 293 } 294 else 295 { 296 pi2_quant_coeffs[x_pos + (y_pos * trans_size)] -= final_change; 297 } 298 299 { 300 WORD32 i4_err1, i4_err2; 301 302 /* Inverse Quantization */ 303 IQUANT( 304 pi2_iquant_data[y_pos * dst_iq_strd + x_pos], 305 pi2_quant_coeffs[y_pos * dst_q_strd + x_pos], 306 pi2_dequant_coeff[y_pos * trans_size + x_pos] * 307 g_ihevc_iquant_scales[qp_rem], 308 shift_iq, 309 qp_div); 310 311 i4_err1 = (i2_tr_coeff - i2_iquant_coeff); 312 i4_err1 = i4_err1 * i4_err1; 313 ssd_cost = ssd_cost - i4_err1; 314 i4_err2 = (i2_tr_coeff - pi2_iquant_data[y_pos * dst_iq_strd + x_pos]); 315 i4_err2 = i4_err2 * i4_err2; 316 ssd_cost = ssd_cost + i4_err2; 317 } 318 } 319 } 320 if(last_cg == 1) 321 { 322 last_cg = 0; 323 } 324 } 325 } 326 327 ps_rdoq_sbh_params->i8_ssd_cost = ssd_cost; 328 } 329