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 */
ihevce_sign_data_hiding(rdoq_sbh_ctxt_t * ps_rdoq_sbh_params)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