Coverage Report

Created: 2025-10-13 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}