/src/libhevc/encoder/ihevce_enc_sbh_funcs.c
Line | Count | Source |
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 | 10.1M | { |
119 | 10.1M | WORD32 i, trans_unit_idx; |
120 | 10.1M | UWORD8 *pu1_trans_table = NULL; |
121 | 10.1M | UWORD8 *pu1_csb_table; |
122 | 10.1M | WORD32 shift_value, mask_value; |
123 | 10.1M | WORD32 blk_row, blk_col; |
124 | | |
125 | 10.1M | WORD32 x_pos, y_pos; |
126 | 10.1M | WORD16 i2_quant_coeff; |
127 | 10.1M | WORD32 best_pos = -1; |
128 | | |
129 | 10.1M | WORD16 *pi2_quant_coeffs = ps_rdoq_sbh_params->pi2_quant_coeffs; |
130 | 10.1M | WORD16 *pi2_iquant_data = ps_rdoq_sbh_params->pi2_iquant_coeffs; |
131 | 10.1M | WORD16 *pi2_tr_coeffs = ps_rdoq_sbh_params->pi2_trans_values; |
132 | 10.1M | WORD32 *pi4_subBlock2csbfId_map = ps_rdoq_sbh_params->pi4_subBlock2csbfId_map; |
133 | 10.1M | WORD16 *pi2_dequant_coeff = ps_rdoq_sbh_params->pi2_dequant_coeff; |
134 | 10.1M | UWORD8 *pu1_csbf_buf = ps_rdoq_sbh_params->pu1_csbf_buf; |
135 | 10.1M | WORD32 dst_iq_strd = ps_rdoq_sbh_params->i4_iq_data_strd; |
136 | 10.1M | WORD32 dst_q_strd = ps_rdoq_sbh_params->i4_q_data_strd; |
137 | | |
138 | 10.1M | WORD32 scan_idx = ps_rdoq_sbh_params->i4_scan_idx; |
139 | 10.1M | WORD32 qp_div = ps_rdoq_sbh_params->i4_qp_div; |
140 | 10.1M | WORD32 trans_size = ps_rdoq_sbh_params->i4_trans_size; |
141 | 10.1M | WORD32 qp_rem = ps_rdoq_sbh_params->i2_qp_rem; |
142 | 10.1M | LWORD64 ssd_cost = ps_rdoq_sbh_params->i8_ssd_cost; |
143 | | |
144 | 10.1M | WORD32 last_cg = -1; |
145 | | |
146 | 10.1M | WORD32 log2_size, bit_depth, shift_iq; |
147 | | |
148 | 10.1M | GETRANGE(log2_size, trans_size); |
149 | 10.1M | log2_size -= 1; |
150 | 10.1M | bit_depth = ps_rdoq_sbh_params->i4_bit_depth; |
151 | 10.1M | 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 | 10.1M | 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 | 10.1M | GETRANGE(shift_value, trans_size); |
161 | 10.1M | shift_value = shift_value - 3; /* for finding. row no. from scan index */ |
162 | 10.1M | mask_value = (trans_size / 4) - 1; /*for finding the col. no. from scan index*/ |
163 | 10.1M | switch(trans_size) |
164 | 10.1M | { |
165 | 251k | case 32: |
166 | 251k | pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_8x8[scan_idx][0]); |
167 | 251k | break; |
168 | 850k | case 16: |
169 | 850k | pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_4x4[scan_idx][0]); |
170 | 850k | break; |
171 | 1.88M | case 8: |
172 | 1.88M | pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_2x2[scan_idx][0]); |
173 | 1.88M | break; |
174 | 7.12M | case 4: |
175 | 7.12M | pu1_trans_table = (UWORD8 *)&(g_u1_scan_table_1x1[0]); |
176 | 7.12M | break; |
177 | 0 | default: |
178 | 0 | ASSERT(0); |
179 | 0 | break; |
180 | 10.1M | } |
181 | 54.4M | for(trans_unit_idx = (trans_size * trans_size / 16) - 1; trans_unit_idx >= 0; trans_unit_idx--) |
182 | 44.3M | { |
183 | 44.3M | WORD32 last_scan_pos = -1, first_scan_pos = 16, sign_first_coeff, sum_abs_level = 0, |
184 | 44.3M | quant_coeff_first; |
185 | | |
186 | 44.3M | if(pu1_csbf_buf[pi4_subBlock2csbfId_map[pu1_trans_table[trans_unit_idx]]]) |
187 | 29.4M | { |
188 | | /* row of csb */ |
189 | 29.4M | blk_row = (pu1_trans_table[trans_unit_idx] >> shift_value) * 4; |
190 | | /* col of csb */ |
191 | 29.4M | blk_col = (pu1_trans_table[trans_unit_idx] & mask_value) * 4; |
192 | | |
193 | 29.4M | if(last_cg == -1) |
194 | 10.1M | { |
195 | 10.1M | last_cg = 1; |
196 | 10.1M | } |
197 | | |
198 | 499M | for(i = 15; i >= 0; i--) |
199 | 470M | { |
200 | 470M | x_pos = (pu1_csb_table[i] & 0x3) + blk_col; |
201 | 470M | y_pos = (pu1_csb_table[i] >> 2) + blk_row; |
202 | | |
203 | 470M | i2_quant_coeff = pi2_quant_coeffs[x_pos + (y_pos * trans_size)]; |
204 | | |
205 | 470M | if(i2_quant_coeff) |
206 | 348M | { |
207 | 348M | first_scan_pos = i; |
208 | 348M | if(-1 == last_scan_pos) |
209 | 29.3M | { |
210 | 29.3M | last_scan_pos = i; |
211 | 29.3M | } |
212 | | |
213 | 348M | sum_abs_level += abs(i2_quant_coeff); |
214 | 348M | } |
215 | 470M | } |
216 | | |
217 | 29.4M | if((last_scan_pos - first_scan_pos) >= 4) |
218 | 27.5M | { |
219 | 27.5M | x_pos = (pu1_csb_table[first_scan_pos] & 0x3) + blk_col; |
220 | 27.5M | y_pos = (pu1_csb_table[first_scan_pos] >> 2) + blk_row; |
221 | | |
222 | 27.5M | quant_coeff_first = pi2_quant_coeffs[x_pos + (y_pos * trans_size)]; |
223 | | |
224 | 27.5M | sign_first_coeff = (quant_coeff_first > 0) ? 0 : 1; |
225 | | |
226 | 27.5M | if(sign_first_coeff != (sum_abs_level & 0x1)) |
227 | 13.7M | { |
228 | 13.7M | WORD32 q_err; |
229 | 13.7M | WORD32 min_cost = MAX_INT; |
230 | 13.7M | WORD32 final_change = 0, cur_cost = 0, cur_change = 0; |
231 | 13.7M | WORD16 i2_tr_coeff; |
232 | 13.7M | WORD16 i2_iquant_coeff; |
233 | | |
234 | 228M | for(i = (last_cg == 1) ? last_scan_pos : 15; i >= 0; i--) |
235 | 214M | { |
236 | 214M | x_pos = (pu1_csb_table[i] & 0x3) + blk_col; |
237 | 214M | y_pos = (pu1_csb_table[i] >> 2) + blk_row; |
238 | | |
239 | 214M | i2_quant_coeff = pi2_quant_coeffs[x_pos + (y_pos * trans_size)]; |
240 | 214M | i2_tr_coeff = pi2_tr_coeffs[x_pos + (y_pos * trans_size)]; |
241 | 214M | i2_iquant_coeff = pi2_iquant_data[x_pos + (y_pos * dst_iq_strd)]; |
242 | | |
243 | 214M | q_err = abs(i2_tr_coeff) - abs(i2_iquant_coeff); |
244 | | |
245 | 214M | if(i2_quant_coeff != 0) |
246 | 172M | { |
247 | 172M | cur_cost = -1 * SIGN(q_err) * q_err; |
248 | | |
249 | 172M | if(q_err <= 0) |
250 | 95.3M | { |
251 | 95.3M | if(i == first_scan_pos && abs(i2_quant_coeff) == 1) |
252 | 1.76M | { |
253 | 1.76M | cur_cost = MAX_INT; |
254 | 1.76M | } |
255 | 95.3M | } |
256 | 172M | } |
257 | 41.5M | else |
258 | 41.5M | { |
259 | 41.5M | cur_cost = -q_err; |
260 | 41.5M | if(i < first_scan_pos) |
261 | 4.25M | { |
262 | 4.25M | WORD32 sign_bit = (i2_tr_coeff >= 0 ? 0 : 1); |
263 | | |
264 | 4.25M | if(sign_first_coeff != sign_bit) |
265 | 1.88M | { |
266 | 1.88M | cur_cost = MAX_INT; |
267 | 1.88M | } |
268 | 4.25M | } |
269 | 41.5M | } |
270 | | |
271 | 214M | cur_change = (i2_quant_coeff == 0) ? 1 : (q_err > 0 ? 1 : -1); |
272 | | |
273 | 214M | if(cur_cost < min_cost) |
274 | 38.6M | { |
275 | 38.6M | min_cost = cur_cost; |
276 | 38.6M | final_change = cur_change; |
277 | 38.6M | best_pos = i; |
278 | 38.6M | } |
279 | 214M | } |
280 | 13.7M | if((i2_quant_coeff == 32767) || (i2_quant_coeff == -32768)) |
281 | 0 | { |
282 | 0 | final_change = -1; |
283 | 0 | } |
284 | | |
285 | 13.7M | x_pos = (pu1_csb_table[best_pos] & 0x3) + blk_col; |
286 | 13.7M | y_pos = (pu1_csb_table[best_pos] >> 2) + blk_row; |
287 | 13.7M | i2_iquant_coeff = pi2_iquant_data[x_pos + (y_pos * dst_iq_strd)]; |
288 | 13.7M | i2_tr_coeff = pi2_tr_coeffs[x_pos + (y_pos * trans_size)]; |
289 | | |
290 | 13.7M | if(i2_tr_coeff >= 0) |
291 | 6.64M | { |
292 | 6.64M | pi2_quant_coeffs[x_pos + (y_pos * trans_size)] += final_change; |
293 | 6.64M | } |
294 | 7.11M | else |
295 | 7.11M | { |
296 | 7.11M | pi2_quant_coeffs[x_pos + (y_pos * trans_size)] -= final_change; |
297 | 7.11M | } |
298 | | |
299 | 13.7M | { |
300 | 13.7M | WORD32 i4_err1, i4_err2; |
301 | | |
302 | | /* Inverse Quantization */ |
303 | 13.7M | IQUANT( |
304 | 13.7M | pi2_iquant_data[y_pos * dst_iq_strd + x_pos], |
305 | 13.7M | pi2_quant_coeffs[y_pos * dst_q_strd + x_pos], |
306 | 13.7M | pi2_dequant_coeff[y_pos * trans_size + x_pos] * |
307 | 13.7M | g_ihevc_iquant_scales[qp_rem], |
308 | 13.7M | shift_iq, |
309 | 13.7M | qp_div); |
310 | | |
311 | 13.7M | i4_err1 = (i2_tr_coeff - i2_iquant_coeff); |
312 | 13.7M | i4_err1 = i4_err1 * i4_err1; |
313 | 13.7M | ssd_cost = ssd_cost - i4_err1; |
314 | 13.7M | i4_err2 = (i2_tr_coeff - pi2_iquant_data[y_pos * dst_iq_strd + x_pos]); |
315 | 13.7M | i4_err2 = i4_err2 * i4_err2; |
316 | 13.7M | ssd_cost = ssd_cost + i4_err2; |
317 | 13.7M | } |
318 | 13.7M | } |
319 | 27.5M | } |
320 | 29.4M | if(last_cg == 1) |
321 | 10.1M | { |
322 | 10.1M | last_cg = 0; |
323 | 10.1M | } |
324 | 29.4M | } |
325 | 44.3M | } |
326 | | |
327 | 10.1M | ps_rdoq_sbh_params->i8_ssd_cost = ssd_cost; |
328 | 10.1M | } |