Coverage Report

Created: 2025-07-11 06:43

/src/libhevc/encoder/ihevce_cabac_rdo.c
Line
Count
Source (jump to first uncovered line)
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
177k
{
143
177k
    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
177k
    WORD32 log2_ctb_size =
147
177k
        ps_sps->i1_log2_min_coding_block_size + ps_sps->i1_log2_diff_max_min_coding_block_size;
148
149
177k
    WORD32 cabac_init_idc;
150
151
177k
    (void)ps_rc_quant_ctxt;
152
    /* sanity checks */
153
177k
    ASSERT((log2_ctb_size >= 3) && (log2_ctb_size <= 6));
154
177k
    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
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_vps = ps_vps;
158
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_sps = ps_sps;
159
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_pps = ps_pps;
160
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].ps_slice_hdr = ps_slice_hdr;
161
162
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].ps_vps = ps_vps;
163
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].ps_sps = ps_sps;
164
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].ps_pps = ps_pps;
165
177k
    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
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].pu1_skip_cu_top = pu1_cu_skip_top_row;
169
170
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].pu1_skip_cu_top = pu1_cu_skip_top_row;
171
172
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i1_log2_ctb_size = log2_ctb_size;
173
174
177k
    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
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].u4_skip_cu_left = 0;
178
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].u4_skip_cu_left = 0;
179
180
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i1_ctb_num_pcm_blks = 0;
181
177k
    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
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i4_enable_res_encode = 0;
189
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i4_enable_res_encode = 0;
190
177k
#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
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cb[0] =
198
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cb[0][1];
199
200
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cb[0] =
201
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cb[0][1];
202
203
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cr[0] =
204
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cr[0][1];
205
206
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cr[0] =
207
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cr[0][1];
208
209
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cb[1] =
210
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cb[1][1];
211
212
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cb[1] =
213
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cb[1][1];
214
215
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].apu1_cbf_cr[1] =
216
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cr[1][1];
217
218
177k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].apu1_cbf_cr[1] =
219
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cr[1][1];
220
221
177k
    memset(
222
177k
        ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cb,
223
177k
        0,
224
177k
        (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8));
225
226
177k
    memset(
227
177k
        ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cb,
228
177k
        0,
229
177k
        (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8));
230
231
177k
    memset(
232
177k
        ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].au1_cbf_cr,
233
177k
        0,
234
177k
        (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8));
235
236
177k
    memset(
237
177k
        ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].au1_cbf_cr,
238
177k
        0,
239
177k
        (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8));
240
241
    /* initialize the cabac init idc based on slice type */
242
177k
    if(ps_slice_hdr->i1_slice_type == ISLICE)
243
48.0k
    {
244
48.0k
        cabac_init_idc = 0;
245
48.0k
    }
246
129k
    else if(ps_slice_hdr->i1_slice_type == PSLICE)
247
98.7k
    {
248
98.7k
        cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 2 : 1;
249
98.7k
    }
250
30.9k
    else
251
30.9k
    {
252
30.9k
        cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 1 : 2;
253
30.9k
    }
254
255
    /* all the entropy contexts in rdo initialized in bit compute mode      */
256
177k
    ihevce_cabac_init(
257
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].s_cabac_ctxt,
258
177k
        NULL, /* bitstream buffer not required in bits compute mode */
259
177k
        CLIP3(slice_qp, 0, IHEVC_MAX_QP),
260
177k
        cabac_init_idc,
261
177k
        CABAC_MODE_COMPUTE_BITS);
262
263
177k
    ihevce_cabac_init(
264
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].s_cabac_ctxt,
265
177k
        NULL, /* bitstream buffer not required in bits compute mode */
266
177k
        CLIP3(slice_qp, 0, IHEVC_MAX_QP),
267
177k
        cabac_init_idc,
268
177k
        CABAC_MODE_COMPUTE_BITS);
269
270
    /* initialize the entropy states in rdopt struct  */
271
177k
    COPY_CABAC_STATES(
272
177k
        &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0],
273
177k
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].s_cabac_ctxt.au1_ctxt_models[0],
274
177k
        sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states));
275
177k
}
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
292k
{
301
    /* initialze the ctb x and y co-ordinates for all the rdopt entropy contexts */
302
292k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i4_ctb_x = ctb_x;
303
292k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i4_ctb_x = ctb_x;
304
305
292k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].i4_ctb_y = ctb_y;
306
292k
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].i4_ctb_y = ctb_y;
307
292k
}
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
13.9M
{
370
    /* local cu structure for passing to entrop encode cu module */
371
13.9M
    cu_enc_loop_out_t s_enc_cu;
372
13.9M
    WORD32 rdopt_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx;
373
374
13.9M
    entropy_context_t *ps_cur_cu_entropy =
375
13.9M
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[rdopt_buf_idx];
376
377
13.9M
    WORD32 total_bits = 0;
378
379
13.9M
    WORD32 log2_ctb_size = ps_cur_cu_entropy->i1_log2_ctb_size;
380
13.9M
    WORD32 log2_cu_size;
381
382
13.9M
    WORD32 cu_depth;
383
384
    /* sanity checks */
385
13.9M
    ASSERT((rdopt_buf_idx == 0) || (rdopt_buf_idx == 1));
386
13.9M
    ASSERT((cu_size >= 8) && (cu_size <= (1 << log2_ctb_size)));
387
13.9M
    ASSERT((cu_pos_x >= 0) && (cu_pos_x <= (1 << (log2_ctb_size - 3))));
388
13.9M
    ASSERT((cu_pos_y >= 0) && (cu_pos_y <= (1 << (log2_ctb_size - 3))));
389
390
13.9M
    GETRANGE(log2_cu_size, cu_size);
391
13.9M
    log2_cu_size -= 1;
392
13.9M
    cu_depth = log2_ctb_size - log2_cu_size;
393
394
13.9M
    {
395
        /**********************************************************/
396
        /* prepare local cu structure before calling cabac encode */
397
        /**********************************************************/
398
399
        /* default be canged to have orred val*/
400
13.9M
        s_enc_cu.b1_no_residual_syntax_flag = 0;
401
402
        /* initialize cu posx, posy and size */
403
13.9M
        s_enc_cu.b3_cu_pos_x = cu_pos_x;
404
13.9M
        s_enc_cu.b3_cu_pos_y = cu_pos_y;
405
13.9M
        s_enc_cu.b4_cu_size = (cu_size >> 3);
406
407
        /* PCM not supported */
408
13.9M
        s_enc_cu.b1_pcm_flag = 0;
409
13.9M
        s_enc_cu.b1_pred_mode_flag = ps_cu_prms->u1_intra_flag;
410
13.9M
        s_enc_cu.b3_part_mode = ps_cu_prms->u1_part_mode;
411
412
13.9M
        s_enc_cu.b1_skip_flag = ps_cu_prms->u1_skip_flag;
413
13.9M
        s_enc_cu.b1_tq_bypass_flag = 0;
414
13.9M
        s_enc_cu.pv_coeff = pv_ecd_coeff;
415
416
        /* store the number of TUs */
417
13.9M
        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
13.9M
        s_enc_cu.ps_pu = &ps_cu_prms->as_pu_enc_loop[0];
421
13.9M
        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
13.9M
        if((SIZE_2Nx2N == ps_cu_prms->u1_part_mode) &&
426
           /*(1 == ps_cu_prms->u2_num_tus_in_cu) &&*/
427
13.9M
           (1 == ps_cu_prms->as_pu_enc_loop[0].b1_merge_flag) && (0 == ps_cu_prms->u1_skip_flag) &&
428
13.9M
           (0 == ps_cu_prms->u1_is_cu_coded))
429
1.74M
        {
430
1.74M
            s_enc_cu.b1_skip_flag = 1;
431
1.74M
        }
432
433
13.9M
        if(s_enc_cu.b1_pred_mode_flag == PRED_MODE_INTER)
434
4.89M
        {
435
4.89M
            s_enc_cu.b1_no_residual_syntax_flag = !ps_cu_prms->u1_is_cu_coded;
436
4.89M
        }
437
9.08M
        else /* b1_pred_mode_flag == PRED_MODE_INTRA */
438
9.08M
        {
439
            /* copy prev_mode_flag, mpm_idx and rem_intra_pred_mode for each PU */
440
9.08M
            memcpy(
441
9.08M
                &s_enc_cu.as_prev_rem[0],
442
9.08M
                &ps_cu_prms->as_intra_prev_rem[0],
443
9.08M
                ps_cu_prms->u2_num_tus_in_cu * sizeof(intra_prev_rem_flags_t));
444
445
9.08M
            s_enc_cu.b3_chroma_intra_pred_mode = ps_cu_prms->u1_chroma_intra_pred_mode;
446
9.08M
        }
447
13.9M
    }
448
449
    /* reset the total bits in cabac engine to zero */
450
13.9M
    ps_cur_cu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0;
451
13.9M
    ps_cur_cu_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 = 0;
452
13.9M
    ps_cur_cu_entropy->s_cabac_ctxt.u4_cbf_bits_q12 = 0;
453
13.9M
    ps_cur_cu_entropy->i1_encode_qp_delta = 0;
454
455
    /* Call the cabac encode function of current cu to compute bits */
456
13.9M
    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
13.9M
    total_bits =
460
13.9M
        (ps_cur_cu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >>
461
13.9M
        CABAC_FRAC_BITS_Q;
462
13.9M
#if RDOPT_ZERO_CBF_ENABLE
463
13.9M
    ASSERT(ps_cur_cu_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 == 0);
464
13.9M
#endif
465
    /* return total texture bits rounding the fractional bits */
466
13.9M
    *pi4_cu_rdopt_tex_bits =
467
13.9M
        (ps_cur_cu_entropy->s_cabac_ctxt.u4_cbf_bits_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >>
468
13.9M
        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
13.9M
    return (total_bits);
475
13.9M
}
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
1.07M
{
501
    /* index to curr buf*/
502
1.07M
    WORD32 rdopt_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx;
503
1.07M
    WORD32 total_bits = 0;
504
1.07M
    entropy_context_t *ps_cur_ctb_entropy =
505
1.07M
        &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
1.07M
    memcpy(
509
1.07M
        &ps_cur_ctb_entropy->s_cabac_ctxt.au1_ctxt_models[0],
510
1.07M
        &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0],
511
1.07M
        sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states));
512
513
    /* reset the total bits in cabac engine to zero */
514
1.07M
    ps_cur_ctb_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0;
515
1.07M
    ps_cur_ctb_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 = 0;
516
1.07M
    ps_cur_ctb_entropy->s_cabac_ctxt.u4_cbf_bits_q12 = 0;
517
1.07M
    ps_cur_ctb_entropy->i1_encode_qp_delta = 0;
518
    //ps_cur_ctb_entropy->s_cabac_ctxt.u4_range = 0;
519
520
1.07M
    ASSERT(ps_cur_ctb_entropy->s_cabac_ctxt.u4_range == 0);
521
1.07M
    ihevce_cabac_encode_sao(ps_cur_ctb_entropy, ps_ctb_enc_loop_out);
522
523
    /* return total bits after rounding the fractional bits */
524
1.07M
    total_bits =
525
1.07M
        (ps_cur_ctb_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >>
526
1.07M
        CABAC_FRAC_BITS_Q;
527
528
1.07M
    return (total_bits);
529
1.07M
}
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
158k
{
552
    /* local cu structure for passing to entrop encode cu module */
553
158k
    WORD32 rdopt_buf_idx = i4_best_buf_idx;
554
158k
    entropy_context_t *ps_cur_ctb_entropy =
555
158k
        &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
158k
    memcpy(
559
158k
        &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0],
560
158k
        &ps_cur_ctb_entropy->s_cabac_ctxt.au1_ctxt_models[0],
561
158k
        sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states));
562
563
    /* reset the total bits in cabac engine to zero */
564
158k
    ps_cur_ctb_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0;
565
158k
    ps_cur_ctb_entropy->s_cabac_ctxt.u4_texture_bits_estimated_q12 = 0;
566
158k
    ps_cur_ctb_entropy->s_cabac_ctxt.u4_cbf_bits_q12 = 0;
567
158k
    ps_cur_ctb_entropy->i1_encode_qp_delta = 0;
568
569
158k
    return (1);
570
158k
}
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
3.18M
{
613
3.18M
    entropy_context_t *ps_best_cu_entropy =
614
3.18M
        &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[rdopt_best_cu_idx];
615
616
    /* CTB x co-ordinate w.r.t frame start           */
617
3.18M
    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
3.18M
    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
3.18M
    WORD32 x_pos = ((cu_x0_frm >> 3) & 0x7);
624
625
    /* bit postion from where left skip flag is extracted; 1bit per 8 pel  */
626
3.18M
    WORD32 y_pos = ((cu_pos_y >> 3) & 0x7);
627
628
    /* top and left skip flags computed based on nbr availability */
629
3.18M
    UWORD8 *pu1_top_skip_flags = ps_best_cu_entropy->pu1_skip_cu_top + (cu_x0_frm >> 6);
630
631
3.18M
    UWORD32 u4_skip_left_flags = ps_best_cu_entropy->u4_skip_cu_left;
632
633
3.18M
    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
3.18M
    COPY_CABAC_STATES(
637
3.18M
        &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0],
638
3.18M
        &ps_best_cu_entropy->s_cabac_ctxt.au1_ctxt_models[0],
639
3.18M
        sizeof(ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states));
640
641
    /* replicate skip flag in left and top row cu skip flags */
642
3.18M
    if(cu_skip_flag)
643
0
    {
644
0
        SET_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3));
645
0
        SET_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3));
646
0
    }
647
3.18M
    else
648
3.18M
    {
649
3.18M
        CLEAR_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3));
650
3.18M
        CLEAR_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3));
651
3.18M
    }
652
653
    /* copy the left skip flags in both the rdopt contexts */
654
3.18M
    ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[0].u4_skip_cu_left =
655
3.18M
        ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[1].u4_skip_cu_left = u4_skip_left_flags;
656
3.18M
}
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
9.40M
{
695
9.40M
    WORD32 log2_tfr_size;
696
9.40M
    WORD32 total_bits = 0;
697
9.40M
    WORD32 curr_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx;
698
9.40M
    entropy_context_t *ps_cur_tu_entropy;
699
700
9.40M
    ps_cur_tu_entropy = &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[curr_buf_idx];
701
702
9.40M
    ASSERT((transform_size >= 4) && (transform_size <= 32));
703
704
    /* transform size to log2transform size */
705
9.40M
    GETRANGE(log2_tfr_size, transform_size);
706
9.40M
    log2_tfr_size -= 1;
707
708
    /* reset the total bits in cabac engine to zero */
709
9.40M
    ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0;
710
9.40M
    ps_cur_tu_entropy->i1_encode_qp_delta = 0;
711
712
    /* Call the cabac residue encode function to compute TU bits */
713
9.40M
    ihevce_cabac_residue_encode_rdopt(
714
9.40M
        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
9.40M
    total_bits =
718
9.40M
        (ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >>
719
9.40M
        CABAC_FRAC_BITS_Q;
720
721
9.40M
    return (total_bits);
722
9.40M
}
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
6.85M
{
787
6.85M
    WORD32 log2_tfr_size;
788
6.85M
    WORD32 total_bits = 0;
789
6.85M
    WORD32 curr_buf_idx = ps_rdopt_entropy_ctxt->i4_curr_buf_idx;
790
6.85M
    entropy_context_t *ps_cur_tu_entropy;
791
792
6.85M
    ps_cur_tu_entropy = &ps_rdopt_entropy_ctxt->as_cu_entropy_ctxt[curr_buf_idx];
793
794
6.85M
    ASSERT((transform_size >= 4) && (transform_size <= 32));
795
796
    /* transform size to log2transform size */
797
6.85M
    GETRANGE(log2_tfr_size, transform_size);
798
6.85M
    log2_tfr_size -= 1;
799
800
    /* reset the total bits in cabac engine to zero */
801
6.85M
    ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 = 0;
802
6.85M
    ps_cur_tu_entropy->i1_encode_qp_delta = 0;
803
804
    /* Call the cabac residue encode function to compute TU bits */
805
6.85M
    ihevce_cabac_residue_encode_rdoq(
806
6.85M
        ps_cur_tu_entropy,
807
6.85M
        pv_ecd_coeff,
808
6.85M
        log2_tfr_size,
809
6.85M
        is_luma,
810
6.85M
        (void *)ps_rdoq_ctxt,
811
6.85M
        pi8_coded_tu_dist,
812
6.85M
        pi8_not_coded_tu_dist,
813
6.85M
        perform_sbh);
814
815
    /* return total bits after rounding the fractional bits */
816
6.85M
    total_bits =
817
6.85M
        (ps_cur_tu_entropy->s_cabac_ctxt.u4_bits_estimated_q12 + (1 << (CABAC_FRAC_BITS_Q - 1))) >>
818
6.85M
        CABAC_FRAC_BITS_Q;
819
820
6.85M
    return (total_bits);
821
6.85M
}
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
24.8k
{
851
    /* sanity checks */
852
24.8k
    ASSERT((copy_mode == STORE_ENT_SYNC_RDO_STATE) || (copy_mode == UPDATE_ENT_SYNC_RDO_STATE));
853
854
24.8k
    if(STORE_ENT_SYNC_RDO_STATE == copy_mode)
855
0
    {
856
0
        COPY_CABAC_STATES(
857
0
            pu1_entropy_sync_states,
858
0
            &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0],
859
0
            IHEVC_CAB_CTXT_END);
860
0
    }
861
24.8k
    else if(UPDATE_ENT_SYNC_RDO_STATE == copy_mode)
862
24.8k
    {
863
24.8k
        COPY_CABAC_STATES(
864
24.8k
            &ps_rdopt_entropy_ctxt->au1_init_cabac_ctxt_states[0],
865
24.8k
            pu1_entropy_sync_states,
866
24.8k
            IHEVC_CAB_CTXT_END);
867
24.8k
    }
868
24.8k
}