Coverage Report

Created: 2026-07-16 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_parse_residual.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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
/**
19
*******************************************************************************
20
* @file
21
*  ihevcd_parse_residual.c
22
*
23
* @brief
24
*  Contains functions for parsing residual data at TU level
25
*
26
* @author
27
*  Harish
28
*
29
* @par List of Functions:
30
*
31
* @remarks
32
*  None
33
*
34
*******************************************************************************
35
*/
36
/*****************************************************************************/
37
/* File Includes                                                             */
38
/*****************************************************************************/
39
#include <stdio.h>
40
#include <stddef.h>
41
#include <stdlib.h>
42
#include <string.h>
43
#include <assert.h>
44
45
#include "ihevc_typedefs.h"
46
#include "iv.h"
47
#include "ivd.h"
48
#include "ihevcd_cxa.h"
49
50
#include "ihevc_defs.h"
51
#include "ihevc_debug.h"
52
#include "ihevc_structs.h"
53
#include "ihevc_macros.h"
54
#include "ihevc_platform_macros.h"
55
56
#include "ihevc_common_tables.h"
57
#include "ihevc_error.h"
58
#include "ihevc_cabac_tables.h"
59
60
#include "ihevcd_trace.h"
61
#include "ihevcd_defs.h"
62
#include "ihevcd_function_selector.h"
63
#include "ihevcd_structs.h"
64
#include "ihevcd_error.h"
65
#include "ihevcd_nal.h"
66
#include "ihevcd_bitstream.h"
67
#include "ihevcd_utils.h"
68
#include "ihevcd_parse_residual.h"
69
#include "ihevcd_cabac.h"
70
71
/**
72
  *****************************************************************************
73
  * @brief  returns context increment for sig coeff based on csbf neigbour
74
  *         flags (bottom and right) and current coeff postion in 4x4 block
75
  *         See section 9.3.3.1.4 for details on this context increment
76
  *
77
  * input   : neigbour csbf flags(bit0:rightcsbf, bit1:bottom csbf)
78
  *           coeff idx in raster order (0-15)
79
  *
80
  * output  : context increment for sig coeff flag
81
  *
82
  *****************************************************************************
83
  */
84
const UWORD8 gau1_ihevcd_sigcoeff_ctxtinc[3][4][16] =
85
{
86
87
    {
88
        /* nbr csbf = 0:  sigCtx = (xP+yP == 0) ? 2 : (xP+yP < 3) ? 1: 0 */
89
        { 2,    1,    1,    1,    1,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
90
        /* nbr csbf = 1:  sigCtx = (yP == 0) ? 2 : (yP == 1) ? 1: 0      */
91
        { 2,    1,    2,    0,    1,    2,    0,    0,    1,    2,    0,    0,    1,    0,    0,    0 },
92
        /* nbr csbf = 2:  sigCtx = (xP == 0) ? 2 : (xP == 1) ? 1: 0      */
93
        { 2,    2,    1,    2,    1,    0,    2,    1,    0,    0,    1,    0,    0,    0,    0,    0 },
94
        /* nbr csbf = 3:  sigCtx = 2                                     */
95
        { 2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2 },
96
    },
97
    {
98
        /* nbr csbf = 0:  sigCtx = (xP+yP == 0) ? 2 : (xP+yP < 3) ? 1: 0 */
99
        { 2,    1,    1,    0,    1,    1,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0 },
100
        /* nbr csbf = 1:  sigCtx = (yP == 0) ? 2 : (yP == 1) ? 1: 0      */
101
        { 2,    2,    2,    2,    1,    1,    1,    1,    0,    0,    0,    0,    0,    0,    0,    0 },
102
        /* nbr csbf = 2:  sigCtx = (xP == 0) ? 2 : (xP == 1) ? 1: 0      */
103
        { 2,    1,    0,    0,    2,    1,    0,    0,    2,    1,    0,    0,    2,    1,    0,    0 },
104
        /* nbr csbf = 3:  sigCtx = 2                                     */
105
        { 2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2 },
106
    },
107
    {
108
        /* nbr csbf = 0:  sigCtx = (xP+yP == 0) ? 2 : (xP+yP < 3) ? 1: 0 */
109
        { 2,    1,    1,    0,    1,    1,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0 },
110
        /* nbr csbf = 1:  sigCtx = (yP == 0) ? 2 : (yP == 1) ? 1: 0      */
111
        { 2,    1,    0,    0,    2,    1,    0,    0,    2,    1,    0,    0,    2,    1,    0,    0 },
112
        /* nbr csbf = 2:  sigCtx = (xP == 0) ? 2 : (xP == 1) ? 1: 0      */
113
        { 2,    2,    2,    2,    1,    1,    1,    1,    0,    0,    0,    0,    0,    0,    0,    0 },
114
        /* nbr csbf = 3:  sigCtx = 2                                     */
115
        { 2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2 },
116
    },
117
118
119
};
120
121
122
123
/**
124
  *****************************************************************************
125
  * @brief  returns context increment for sig coeff for 4x4 tranform size as
126
  *         per Table 9-39 in section 9.3.3.1.4
127
  *
128
  * input   : coeff idx in raster order (0-15)
129
  *
130
  * output  : context increment for sig coeff flag
131
  *
132
  *****************************************************************************
133
  */
134
const UWORD8 gau1_ihevcd_sigcoeff_ctxtinc_tr4[3][16] =
135
{
136
    /* Upright diagonal scan */
137
    {
138
        0,    2,    1,    6,
139
        3,    4,    7,    6,
140
        4,    5,    7,    8,
141
        5,    8,    8,    8,
142
    },
143
    /* Horizontal scan */
144
    {
145
        0,    1,    4,    5,
146
        2,    3,    4,    5,
147
        6,    6,    8,    8,
148
        7,    7,    8,    8,
149
    },
150
    /* Vertical scan */
151
    {
152
        0,    2,    6,    7,
153
        1,    3,    6,    7,
154
        4,    4,    8,    8,
155
        5,    5,    8,    8,
156
    },
157
};
158
159
160
/**
161
*******************************************************************************
162
*
163
* @brief
164
*  Parses Residual coding
165
*
166
* @par Description:
167
*  Parses Residual coding as per  Section:7.3.13
168
*
169
* @param[in] ps_codec
170
*  Pointer to codec context
171
*
172
* @returns  error code from IHEVCD_ERROR_T
173
*
174
* @remarks
175
*
176
*
177
*******************************************************************************
178
*/
179
180
WORD32 ihevcd_parse_residual_coding(codec_t *ps_codec,
181
                                    WORD32 x0, WORD32 y0,
182
                                    WORD32 log2_trafo_size,
183
                                    WORD32 c_idx,
184
                                    WORD32 intra_pred_mode)
185
0
{
186
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
187
0
    WORD32 transform_skip_flag;
188
0
#ifdef ENABLE_MAIN_REXT_PROFILE
189
0
    WORD32 explicit_rdpcm_flag, explicit_rdpcm_dir;
190
0
#endif
191
0
    WORD32 value;
192
0
    sps_t *ps_sps;
193
0
    pps_t *ps_pps;
194
0
    WORD32 last_scan_pos, last_sub_blk;
195
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
196
0
    WORD32 last_significant_coeff_x_prefix, last_significant_coeff_y_prefix;
197
0
    WORD32 last_significant_coeff_x, last_significant_coeff_y;
198
0
    const UWORD8 *pu1_scan_blk = NULL, *pu1_scan_coeff;
199
0
    WORD32 scan_idx;
200
0
    WORD32 i;
201
0
    WORD32 sign_data_hiding_flag;
202
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
203
0
    WORD32 gt1_ctxt = 1;
204
0
    WORD32 c_max;
205
0
    UWORD16 au2_csbf[9];
206
0
    tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data;
207
0
    WORD8 *pi1_num_coded_subblks;
208
0
    WORD32 num_subblks;
209
0
    WORD32 sig_coeff_base_ctxt, abs_gt1_base_ctxt;
210
0
    UNUSED(x0);
211
0
    UNUSED(y0);
212
0
    ps_sps = ps_codec->s_parse.ps_sps;
213
0
    ps_pps = ps_codec->s_parse.ps_pps;
214
215
0
    sign_data_hiding_flag = ps_pps->i1_sign_data_hiding_flag;
216
0
    transform_skip_flag = 0;
217
0
#ifdef ENABLE_MAIN_REXT_PROFILE
218
0
    explicit_rdpcm_flag = 0;
219
0
    explicit_rdpcm_dir = 0;
220
0
#endif
221
0
    if(ps_pps->i1_transform_skip_enabled_flag &&
222
0
       !ps_codec->s_parse.s_cu.i4_cu_transquant_bypass &&
223
0
#ifdef ENABLE_MAIN_REXT_PROFILE
224
0
       (log2_trafo_size <= ps_pps->i1_log2_max_transform_skip_block_size_minus2 + 2)
225
#else
226
       (log2_trafo_size == 2)
227
#endif
228
0
       )
229
0
    {
230
0
        WORD32 ctxt_idx;
231
232
0
        if(!c_idx)
233
0
        {
234
0
            ctxt_idx = IHEVC_CAB_TFM_SKIP0;
235
0
        }
236
0
        else
237
0
        {
238
0
            ctxt_idx = IHEVC_CAB_TFM_SKIP12;
239
0
        }
240
0
        TRACE_CABAC_CTXT("transform_skip_flag", ps_cabac->u4_range, ctxt_idx);
241
0
        value = ihevcd_cabac_decode_bin(ps_cabac,
242
0
                                        ps_bitstrm,
243
0
                                        ctxt_idx);
244
0
        AEV_TRACE("transform_skip_flag", value, ps_cabac->u4_range);
245
0
        transform_skip_flag = value;
246
0
    }
247
248
0
#ifdef ENABLE_MAIN_REXT_PROFILE
249
0
    if(PRED_MODE_INTER == ps_codec->s_parse.s_cu.i4_pred_mode
250
0
                    && ps_sps->i1_explicit_rdpcm_enabled_flag
251
0
                    && (transform_skip_flag || ps_codec->s_parse.s_cu.i4_cu_transquant_bypass))
252
253
0
    {
254
0
        WORD32 ctxt_idx = IHEVC_CAB_EXPLICIT_RDPCM_FLAG + (c_idx != 0);
255
0
        TRACE_CABAC_CTXT("explicit_rdpcm_flag", ps_cabac->u4_range, ctxt_idx);
256
0
        value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
257
0
        AEV_TRACE("explicit_rdpcm_flag", value, ps_cabac->u4_range);
258
0
        explicit_rdpcm_flag = value;
259
260
0
        if(explicit_rdpcm_flag)
261
0
        {
262
0
            ctxt_idx = IHEVC_CAB_EXPLICIT_RDPCM_DIR + (c_idx != 0);
263
0
            TRACE_CABAC_CTXT("explicit_rdpcm_dir_flag", ps_cabac->u4_range, ctxt_idx);
264
0
            value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
265
0
            AEV_TRACE("explicit_rdpcm_dir_flag", value, ps_cabac->u4_range);
266
0
            explicit_rdpcm_dir = value;
267
0
        }
268
0
    }
269
0
#endif
270
271
    /* code the last_coeff_x_prefix as tunary binarized code */
272
0
    {
273
0
        WORD32 ctxt_idx_x, ctxt_idx_y, ctx_shift;
274
0
        WORD32 ctx_offset;
275
0
        c_max = (log2_trafo_size << 1) - 1;
276
277
0
        if(!c_idx)
278
0
        {
279
0
            ctx_offset = (3 * (log2_trafo_size - 2)) + ((log2_trafo_size - 1) >> 2);
280
0
            ctxt_idx_x = IHEVC_CAB_COEFFX_PREFIX + ctx_offset;
281
0
            ctxt_idx_y = IHEVC_CAB_COEFFY_PREFIX + ctx_offset;
282
0
            ctx_shift  = (log2_trafo_size + 1) >> 2;
283
0
        }
284
0
        else
285
0
        {
286
0
            ctxt_idx_x = IHEVC_CAB_COEFFX_PREFIX + 15;
287
0
            ctxt_idx_y = IHEVC_CAB_COEFFY_PREFIX + 15;
288
0
            ctx_shift  = log2_trafo_size  - 2;
289
0
        }
290
291
0
        TRACE_CABAC_CTXT("last_coeff_x_prefix", ps_cabac->u4_range, ctxt_idx_x);
292
0
        last_significant_coeff_x_prefix = ihevcd_cabac_decode_bins_tunary(ps_cabac,
293
0
                                                                          ps_bitstrm,
294
0
                                                                          c_max,
295
0
                                                                          ctxt_idx_x,
296
0
                                                                          ctx_shift,
297
0
                                                                          c_max);
298
299
0
        AEV_TRACE("last_coeff_x_prefix", last_significant_coeff_x_prefix, ps_cabac->u4_range);
300
301
0
        TRACE_CABAC_CTXT("last_coeff_y_prefix", ps_cabac->u4_range, ctxt_idx_y);
302
0
        last_significant_coeff_y_prefix = ihevcd_cabac_decode_bins_tunary(ps_cabac,
303
0
                                                                          ps_bitstrm,
304
0
                                                                          c_max,
305
0
                                                                          ctxt_idx_y,
306
0
                                                                          ctx_shift,
307
0
                                                                          c_max);
308
309
0
        AEV_TRACE("last_coeff_y_prefix", last_significant_coeff_y_prefix, ps_cabac->u4_range);
310
311
312
0
        last_significant_coeff_x = last_significant_coeff_x_prefix;
313
0
        if(last_significant_coeff_x_prefix > 3)
314
0
        {
315
0
            WORD32 suf_length = ((last_significant_coeff_x_prefix - 2) >> 1);
316
317
0
            value = ihevcd_cabac_decode_bypass_bins(ps_cabac,
318
0
                                                    ps_bitstrm,
319
0
                                                    suf_length);
320
321
0
            AEV_TRACE("last_coeff_x_suffix", value, ps_cabac->u4_range);
322
323
324
0
            last_significant_coeff_x =
325
0
                            (1 << ((last_significant_coeff_x_prefix >> 1) - 1)) *
326
0
                            (2 + (last_significant_coeff_x_prefix & 1)) + value;
327
0
        }
328
329
330
0
        last_significant_coeff_y = last_significant_coeff_y_prefix;
331
0
        if(last_significant_coeff_y_prefix > 3)
332
0
        {
333
0
            WORD32 suf_length = ((last_significant_coeff_y_prefix - 2) >> 1);
334
0
            value = ihevcd_cabac_decode_bypass_bins(ps_cabac,
335
0
                                                    ps_bitstrm,
336
0
                                                    suf_length);
337
338
0
            AEV_TRACE("last_coeff_y_suffix", value, ps_cabac->u4_range);
339
0
            last_significant_coeff_y =
340
0
                            (1 << ((last_significant_coeff_y_prefix >> 1) - 1)) *
341
0
                            (2 + (last_significant_coeff_y_prefix & 1)) + value;
342
0
        }
343
344
0
    }
345
346
    /* Choose a scan matrix based on intra flag, intra pred mode, transform size
347
     and luma/chroma */
348
0
    scan_idx = SCAN_DIAG_UPRIGHT;
349
0
    if(PRED_MODE_INTRA == ps_codec->s_parse.s_cu.i4_pred_mode)
350
0
    {
351
0
        int is_YUV444 = ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444;
352
0
        if((2 == log2_trafo_size) || ((3 == log2_trafo_size) && (0 == c_idx || is_YUV444)))
353
0
        {
354
0
            if((6 <= intra_pred_mode) &&
355
0
               (14 >= intra_pred_mode))
356
0
            {
357
0
                scan_idx = SCAN_VERT;
358
0
            }
359
0
            else if((22 <= intra_pred_mode) &&
360
0
                    (30 >= intra_pred_mode))
361
0
            {
362
0
                scan_idx = SCAN_HORZ;
363
0
            }
364
0
        }
365
0
    }
366
367
    /* In case the scan is vertical, then swap  X and Y positions */
368
0
    if(SCAN_VERT == scan_idx)
369
0
    {
370
0
        SWAP(last_significant_coeff_x, last_significant_coeff_y);
371
0
    }
372
373
0
    {
374
0
        WORD8 *pi1_scan_idx;
375
0
        WORD8 *pi1_buf = (WORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
376
377
        /* First WORD8 gives number of coded subblocks */
378
0
        pi1_num_coded_subblks = pi1_buf++;
379
380
        /* Set number of coded subblocks in the current TU to zero */
381
        /* This will be updated later */
382
0
        *pi1_num_coded_subblks = 0;
383
384
0
        pi1_scan_idx = pi1_buf++;
385
0
#ifdef ENABLE_MAIN_REXT_PROFILE
386
        /* Second WORD8 gives (explicit_rdpcm_dir << 5) | (explicit_rdpcm_flag << 4) | (scan idx << 1) | trans_skip */
387
0
        *pi1_scan_idx = (explicit_rdpcm_dir << 5) | (explicit_rdpcm_flag << 4) | (scan_idx << 1)
388
0
                        | transform_skip_flag;
389
#else
390
        /* Second WORD8 gives (scan idx << 1) | trans_skip */
391
        *pi1_scan_idx = (scan_idx << 1) | transform_skip_flag;
392
#endif
393
394
        /* Store the incremented pointer in pv_tu_coeff_data */
395
0
        ps_codec->s_parse.pv_tu_coeff_data = pi1_buf;
396
397
0
    }
398
    /**
399
     * Given last_significant_coeff_y and last_significant_coeff_x find last sub block
400
     * This is done by ignoring lower two bits of last_significant_coeff_y and last_significant_coeff_x
401
     * and using scan matrix for lookup
402
     */
403
404
    /* If transform is 4x4, last_sub_blk is zero */
405
0
    last_sub_blk = 0;
406
407
    /* If transform is larger than 4x4, then based on scan_idx and transform size, choose a scan table */
408
409
0
    if(log2_trafo_size > 2)
410
0
    {
411
0
        WORD32 scan_pos;
412
0
        WORD32 scan_mat_size;
413
0
        pu1_scan_blk = (UWORD8 *)gapv_ihevc_scan[scan_idx * 3 + (log2_trafo_size - 2 - 1)];
414
415
416
        /* Divide the current transform to 4x4 subblocks and count number of 4x4 in the first row */
417
        /* This will be size of scan matrix to be used for subblock scanning */
418
0
        scan_mat_size = 1 << (log2_trafo_size - 2);
419
0
        scan_pos = ((last_significant_coeff_y >> 2) * scan_mat_size) +
420
0
                        (last_significant_coeff_x >> 2);
421
422
0
        last_sub_blk = pu1_scan_blk[scan_pos];
423
0
    }
424
0
    pu1_scan_coeff  = &gau1_ihevc_scan4x4[scan_idx][0];
425
426
0
    {
427
0
        WORD32 scan_pos;
428
429
0
        scan_pos = ((last_significant_coeff_y & 3) << 2) +
430
0
                        (last_significant_coeff_x & 3);
431
432
0
        last_scan_pos = pu1_scan_coeff[scan_pos];
433
0
    }
434
0
    if(log2_trafo_size > 2)
435
0
        pu1_scan_blk = (UWORD8 *)gapv_ihevc_invscan[scan_idx * 3 + (log2_trafo_size - 2 - 1)];
436
0
    pu1_scan_coeff  = &gau1_ihevc_invscan4x4[scan_idx][0];
437
438
    /* Set CSBF array to zero */
439
0
    {
440
0
        UWORD32 *pu4_csbf;
441
0
        pu4_csbf = (void *)au2_csbf;
442
0
        *pu4_csbf++ = 0;
443
0
        *pu4_csbf++ = 0;
444
0
        *pu4_csbf++ = 0;
445
0
        *pu4_csbf = 0;
446
        /* To avoid a check for y pos, 9th WORD16 in the array is set to zero */
447
0
        au2_csbf[8] = 0;
448
0
    }
449
450
    /*************************************************************************/
451
    /* derive base context index for sig coeff as per section 9.3.3.1.4      */
452
    /* TODO; convert to look up based on luma/chroma, scan type and tfr size */
453
    /*************************************************************************/
454
0
    if(!c_idx)
455
0
    {
456
0
        sig_coeff_base_ctxt = IHEVC_CAB_COEFF_FLAG;
457
0
        abs_gt1_base_ctxt = IHEVC_CAB_COEFABS_GRTR1_FLAG;
458
459
0
        if(3 == log2_trafo_size)
460
0
        {
461
            /* 8x8 transform size */
462
0
            sig_coeff_base_ctxt += (scan_idx == SCAN_DIAG_UPRIGHT) ? 9 : 15;
463
0
        }
464
0
        else  if(3 < log2_trafo_size)
465
0
        {
466
            /* larger transform sizes */
467
0
            sig_coeff_base_ctxt += 21;
468
0
        }
469
0
    }
470
0
    else
471
0
    {
472
        /* chroma context initializations */
473
0
        sig_coeff_base_ctxt = IHEVC_CAB_COEFF_FLAG + 27;
474
0
        abs_gt1_base_ctxt = IHEVC_CAB_COEFABS_GRTR1_FLAG + 16;
475
476
0
        if(3 == log2_trafo_size)
477
0
        {
478
            /* 8x8 transform size */
479
0
            sig_coeff_base_ctxt += 9;
480
0
        }
481
0
        else  if(3 < log2_trafo_size)
482
0
        {
483
            /* larger transform sizes */
484
0
            sig_coeff_base_ctxt += 12;
485
0
        }
486
0
    }
487
0
    num_subblks = 0;
488
    /* Parse each 4x4 subblocks */
489
0
    for(i = last_sub_blk; i >= 0; i--)
490
0
    {
491
0
        WORD32 sub_blk_pos;
492
0
        WORD32 infer_sig_coeff_flag;
493
0
        WORD32 cur_csbf;
494
495
0
        WORD32 n;
496
0
        WORD32 num_coeff;
497
        /* Sig coeff map for 16 entries in raster scan order. Upper 16 bits are used.
498
         * MSB gives sig coeff flag for 0th coeff and so on
499
         * UWORD16 would have been enough but kept as UWORD32 for code optimizations
500
         * In arm unnecessary masking operations are saved
501
         */
502
0
        UWORD32 u4_sig_coeff_map_raster;
503
0
        WORD32 sign_hidden;
504
505
        /* Sig coeff map in scan order */
506
0
        UWORD32 u4_sig_coeff_map;
507
0
        WORD32 coeff_abs_level_greater2_flag;
508
0
        UWORD32 u4_coeff_abs_level_greater1_map;
509
0
        UWORD32 u4_coeff_abs_level_greater2_map;
510
0
        UWORD32 u4_coeff_sign_map;
511
0
        WORD32 first_sig_scan_pos, last_sig_scan_pos, num_greater1_flag, first_greater1_scan_pos;
512
0
        WORD32  num_sig_coeff, sum_abs_level;
513
0
        WORD32 nbr_csbf;
514
515
516
0
        WORD32 ctxt_set;
517
0
        WORD32 rice_param;
518
0
        WORD32 xs, ys;
519
520
0
#ifdef ENABLE_MAIN_REXT_PROFILE
521
0
        WORD8 i1_update_stats = ps_sps->i1_persistent_rice_adaptation_enabled_flag;
522
0
#endif
523
524
0
        sub_blk_pos  = 0;
525
0
        if(i && (log2_trafo_size > 2))
526
0
            sub_blk_pos = pu1_scan_blk[i];
527
528
        /* Get xs and ys from scan position */
529
        /* This is needed for context modelling of significant coeff flag */
530
0
        xs = sub_blk_pos & ((1 << (log2_trafo_size - 2)) - 1);
531
0
        ys = sub_blk_pos >> (log2_trafo_size - 2);
532
533
534
        /* Check if neighbor subblocks are coded */
535
0
        {
536
537
0
            nbr_csbf = 0;
538
539
            /* Get Bottom sub blocks CSBF */
540
0
            nbr_csbf |= (au2_csbf[ys + 1] >> xs) & 1;
541
0
            nbr_csbf <<= 1;
542
543
            /* Get Right sub blocks CSBF */
544
            /* Even if xs is equal to (1 << (log2_trafo_size - 2 )) - 1,
545
               since au2_csbf is set to zero at the beginning, csbf for
546
               neighbor will be read as 0 */
547
548
0
            nbr_csbf |= (au2_csbf[ys] >> (xs + 1)) & 1;
549
550
551
0
        }
552
0
        cur_csbf = 0;
553
554
        /* DC coeff is inferred, only if coded_sub_block is explicitly parsed as 1 */
555
        /* i.e. it is not inferred for first and last subblock */
556
0
        infer_sig_coeff_flag = 0;
557
0
        if((i < last_sub_blk) && (i > 0))
558
0
        {
559
0
            WORD32 ctxt_idx  = IHEVC_CAB_CODED_SUBLK_IDX;
560
561
            /* ctxt based on right / bottom avail csbf, section 9.3.3.1.3 */
562
0
            ctxt_idx += (nbr_csbf) ? 1 : 0;
563
564
            /* Ctxt based on luma or chroma */
565
0
            ctxt_idx += c_idx  ? 2 : 0;
566
0
            TRACE_CABAC_CTXT("coded_sub_block_flag", ps_cabac->u4_range, ctxt_idx);
567
0
            IHEVCD_CABAC_DECODE_BIN(cur_csbf, ps_cabac, ps_bitstrm, ctxt_idx);
568
0
            AEV_TRACE("coded_sub_block_flag", cur_csbf, ps_cabac->u4_range);
569
570
0
            infer_sig_coeff_flag = 1;
571
0
        }
572
0
        else /* if((i == last_sub_blk) || (sub_blk_pos == 0)) */
573
0
        {
574
            /* CSBF is set to 1 for first and last subblock */
575
            /* Note for these subblocks sig_coeff_map is not inferred but instead parsed */
576
0
            cur_csbf = 1;
577
0
        }
578
579
        /* Set current sub blocks CSBF */
580
0
        {
581
0
            UWORD32 u4_mask = 1 << xs;
582
0
            if(cur_csbf)
583
0
                au2_csbf[ys] |= u4_mask;
584
0
            else
585
0
                au2_csbf[ys] &= ~u4_mask;
586
587
0
        }
588
589
        /* If current subblock is not coded, proceed to the next subblock */
590
0
        if(0 == cur_csbf)
591
0
            continue;
592
593
0
        n = 15;
594
0
        u4_sig_coeff_map_raster = 0;
595
0
        u4_sig_coeff_map = 0;
596
0
        num_coeff = 0;
597
0
        if(i == last_sub_blk)
598
0
        {
599
0
            WORD32 pos = ((last_significant_coeff_y & 3) << 2) +
600
0
                            (last_significant_coeff_x & 3);
601
0
            n = (last_scan_pos - 1);
602
            /* Set Significant coeff map for last significant coeff flag as 1 */
603
0
            u4_sig_coeff_map_raster = 1 << pos;
604
0
            u4_sig_coeff_map = 1 << last_scan_pos;
605
0
            num_coeff = 1;
606
0
        }
607
608
0
        for(; n >= 0; n--)
609
0
        {
610
0
            WORD32 significant_coeff_flag;
611
612
0
            if((n > 0 || !infer_sig_coeff_flag))
613
0
            {
614
                //WORD32 coeff_pos;
615
0
                WORD32 sig_ctxinc;
616
0
                WORD32 ctxt_idx;
617
618
                /* Coefficient position is needed for deriving context index for significant_coeff_flag */
619
                //coeff_pos = pu1_scan_coeff[n];
620
                /* derive the context inc as per section 9.3.3.1.4 */
621
0
                sig_ctxinc = 0;
622
0
#ifdef ENABLE_MAIN_REXT_PROFILE
623
0
                if(ps_sps->i1_transform_skip_context_enabled_flag
624
0
                                && (ps_codec->s_parse.s_cu.i4_cu_transquant_bypass
625
0
                                                || transform_skip_flag))
626
0
                {
627
0
                    sig_coeff_base_ctxt = IHEVC_CAB_COEFF_FLAG;
628
0
                    sig_coeff_base_ctxt += (0 == c_idx) ? 42 : 43;
629
0
                }
630
0
                else if(2 == log2_trafo_size)
631
#else
632
                if(2 == log2_trafo_size)
633
#endif
634
0
                {
635
636
                    /* 4x4 transform size increment uses lookup */
637
0
                    sig_ctxinc = gau1_ihevcd_sigcoeff_ctxtinc_tr4[scan_idx][n];
638
0
                }
639
0
                else if(n || i)
640
0
                {
641
                    /* ctxt for AC coeff depends on curpos and neigbour csbf */
642
0
                    sig_ctxinc = gau1_ihevcd_sigcoeff_ctxtinc[scan_idx][nbr_csbf][n];
643
644
                    /* based on luma subblock pos */
645
0
                    sig_ctxinc += (i && (!c_idx)) ? 3 : 0;
646
647
0
                }
648
0
                else
649
0
                {
650
                    /* DC coeff has fixed context for luma and chroma */
651
0
                    sig_coeff_base_ctxt = (0 == c_idx) ? IHEVC_CAB_COEFF_FLAG :
652
0
                                                         (IHEVC_CAB_COEFF_FLAG + 27);
653
0
                }
654
655
0
                ctxt_idx = sig_ctxinc + sig_coeff_base_ctxt;
656
0
                TRACE_CABAC_CTXT("significant_coeff_flag", ps_cabac->u4_range, ctxt_idx);
657
0
                IHEVCD_CABAC_DECODE_BIN(significant_coeff_flag, ps_cabac,
658
0
                                        ps_bitstrm,
659
0
                                        ctxt_idx);
660
0
                AEV_TRACE("significant_coeff_flag", significant_coeff_flag, ps_cabac->u4_range);
661
662
663
                /* If at least one non-zero coeff is signalled then do not infer sig coeff map */
664
                /* for (0,0) coeff in the current sub block */
665
0
                if(significant_coeff_flag)
666
0
                    infer_sig_coeff_flag = 0;
667
668
//                u4_sig_coeff_map_raster |= significant_coeff_flag
669
//                              << coeff_pos;
670
0
                u4_sig_coeff_map |= significant_coeff_flag << n;
671
0
                num_coeff += significant_coeff_flag;
672
0
            }
673
674
675
0
        }
676
        /*********************************************************************/
677
        /* If infer_sig_coeff_flag is 1 then treat the 0th coeff as non zero */
678
        /* If infer_sig_coeff_flag is zero, then last significant_coeff_flag */
679
        /* is parsed in the above loop                                       */
680
        /*********************************************************************/
681
0
        if(infer_sig_coeff_flag)
682
0
        {
683
0
            u4_sig_coeff_map_raster |= 1;
684
0
            u4_sig_coeff_map |= 1;
685
0
            num_coeff++;
686
0
        }
687
688
        /*********************************************************************/
689
        /* First subblock does not get an explicit csbf. It is assumed to    */
690
        /* be 1. For this subblock there is chance of getting all            */
691
        /* sig_coeff_flags to be zero. In such a case proceed to the next    */
692
        /* subblock(which is end of parsing for the current transform block) */
693
        /*********************************************************************/
694
695
0
        if(0 == num_coeff)
696
0
            continue;
697
698
        /* Increment number of coded subblocks for the current TU */
699
0
        num_subblks++;
700
701
        /* Set sig coeff map and subblock position */
702
0
        ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)ps_codec->s_parse.pv_tu_coeff_data;
703
0
        ps_tu_sblk_coeff_data->u2_sig_coeff_map = u4_sig_coeff_map;
704
0
        ps_tu_sblk_coeff_data->u2_subblk_pos = (ys << 8) | xs;
705
706
0
        first_sig_scan_pos = 16;
707
0
        last_sig_scan_pos = -1;
708
0
        num_greater1_flag = 0;
709
0
        first_greater1_scan_pos = -1;
710
0
        u4_coeff_abs_level_greater1_map = 0;
711
712
713
        /* context set based on luma subblock pos */
714
0
        ctxt_set = (i && (!c_idx)) ? 2 : 0;
715
716
        /* See section 9.3.3.1.5           */
717
0
        ctxt_set += (0 == gt1_ctxt) ? 1 : 0;
718
719
0
        gt1_ctxt = 1;
720
        /* Instead of initializing n to 15, set it to 31-CLZ(sig coeff map) */
721
0
        {
722
0
            UWORD32 u4_sig_coeff_map_shift;
723
0
            UWORD32 clz;
724
0
            clz = CLZ(u4_sig_coeff_map);
725
0
            n = 31 - clz;
726
0
            u4_sig_coeff_map_shift = u4_sig_coeff_map << clz;
727
            /* For loop for n changed to do while to break early if sig_coeff_map_shift becomes zero */
728
0
            do
729
0
            {
730
                //WORD32 coeff_pos;
731
0
                WORD32 ctxt_idx;
732
733
                //TODO: Scan lookup will be removed later and instead u4_sig_coeff_map will be used
734
                //coeff_pos = pu1_scan_coeff[n];
735
736
0
                if((u4_sig_coeff_map_shift >> 31) & 1)
737
0
                {
738
739
                    /* abs_level_greater1_flag is sent for only first 8 non-zero levels in a subblock */
740
0
                    if(num_greater1_flag < 8)
741
0
                    {
742
0
                        WORD32 coeff_abs_level_greater1_flag;
743
744
0
                        ctxt_idx = (ctxt_set * 4) + abs_gt1_base_ctxt + gt1_ctxt;
745
746
0
                        TRACE_CABAC_CTXT("coeff_abs_level_greater1_flag", ps_cabac->u4_range, ctxt_idx);
747
0
                        IHEVCD_CABAC_DECODE_BIN(coeff_abs_level_greater1_flag, ps_cabac, ps_bitstrm, ctxt_idx);
748
0
                        AEV_TRACE("coeff_abs_level_greater1_flag", coeff_abs_level_greater1_flag, ps_cabac->u4_range);
749
750
0
                        u4_coeff_abs_level_greater1_map |= coeff_abs_level_greater1_flag << n;
751
0
                        num_greater1_flag++;
752
753
                        /* first_greater1_scan_pos is obtained using CLZ on u4_coeff_abs_level_greater1_map*/
754
                        /*  outside the loop instead of the following check inside the loop                */
755
                        /* if( coeff_abs_level_greater1_flag && first_greater1_scan_pos == -1) */
756
                        /*    first_greater1_scan_pos = n;                                     */
757
758
0
                        if(coeff_abs_level_greater1_flag)
759
0
                        {
760
0
                            gt1_ctxt = 0;
761
0
                        }
762
0
                        else if(gt1_ctxt && (gt1_ctxt < 3))
763
0
                        {
764
0
                            gt1_ctxt++;
765
0
                        }
766
767
0
                    }
768
0
                    else
769
0
                        break;
770
771
                    /* instead of computing last and first significan scan position using checks below */
772
                    /* They are computed outside the loop using CLZ and CTZ on sig_coeff_map */
773
                    /* if(last_sig_scan_pos == -1)                          */
774
                    /*    last_sig_scan_pos = n;                            */
775
                    /*  first_sig_scan_pos = n;                             */
776
0
                }
777
0
                u4_sig_coeff_map_shift <<= 1;
778
0
                n--;
779
                /* If there are zero coeffs, then shift by as many zero coeffs and decrement n */
780
0
                clz = CLZ(u4_sig_coeff_map_shift);
781
0
                u4_sig_coeff_map_shift <<= clz;
782
0
                n -= (WORD32)clz;
783
0
            }while(u4_sig_coeff_map_shift);
784
0
        }
785
        /* At this level u4_sig_coeff_map is non-zero i.e. has atleast one non-zero coeff */
786
0
        last_sig_scan_pos = (31 - CLZ(u4_sig_coeff_map));
787
0
        first_sig_scan_pos = CTZ(u4_sig_coeff_map);
788
789
0
        if(ps_codec->s_parse.s_cu.i4_cu_transquant_bypass
790
0
#ifdef ENABLE_MAIN_REXT_PROFILE
791
0
                        || explicit_rdpcm_flag
792
0
#endif
793
0
                        || (PRED_MODE_INTRA == ps_codec->s_parse.s_cu.i4_pred_mode
794
0
#ifdef ENABLE_MAIN_REXT_PROFILE
795
0
                                        && ps_sps->i1_implicit_rdpcm_enabled_flag
796
#else
797
                                        && 0
798
#endif
799
0
                                        && transform_skip_flag
800
0
                                        && (intra_pred_mode == 10 || intra_pred_mode == 26)))
801
0
        {
802
0
            sign_hidden = 0;
803
0
        }
804
0
        else
805
0
        {
806
0
            sign_hidden = ((last_sig_scan_pos - first_sig_scan_pos) > 3);
807
0
        }
808
809
0
        u4_coeff_abs_level_greater2_map = 0;
810
811
0
        if(u4_coeff_abs_level_greater1_map)
812
0
        {
813
            /* Check if the first level > 1 is greater than 2 */
814
0
            WORD32 ctxt_idx;
815
0
            first_greater1_scan_pos = (31 - CLZ(u4_coeff_abs_level_greater1_map));
816
817
818
0
            ctxt_idx = IHEVC_CAB_COEFABS_GRTR2_FLAG;
819
820
0
            ctxt_idx += (!c_idx) ? ctxt_set : (ctxt_set + 4);
821
0
            TRACE_CABAC_CTXT("coeff_abs_level_greater2_flag", ps_cabac->u4_range, ctxt_idx);
822
0
            IHEVCD_CABAC_DECODE_BIN(coeff_abs_level_greater2_flag, ps_cabac, ps_bitstrm, ctxt_idx);
823
0
            AEV_TRACE("coeff_abs_level_greater2_flag", coeff_abs_level_greater2_flag, ps_cabac->u4_range);
824
0
            u4_coeff_abs_level_greater2_map = coeff_abs_level_greater2_flag << first_greater1_scan_pos;
825
0
        }
826
827
828
0
        u4_coeff_sign_map = 0;
829
830
        /* Parse sign flags */
831
0
        if(!sign_data_hiding_flag || !sign_hidden)
832
0
        {
833
0
            IHEVCD_CABAC_DECODE_BYPASS_BINS(value, ps_cabac, ps_bitstrm, num_coeff);
834
0
            AEV_TRACE("sign_flags", value, ps_cabac->u4_range);
835
0
            u4_coeff_sign_map = (UWORD32)value << (32 - num_coeff);
836
0
        }
837
0
        else
838
0
        {
839
0
            IHEVCD_CABAC_DECODE_BYPASS_BINS(value, ps_cabac, ps_bitstrm, (num_coeff - 1));
840
0
            AEV_TRACE("sign_flags", value, ps_cabac->u4_range);
841
0
            u4_coeff_sign_map = (UWORD32)value << (32 - (num_coeff - 1));
842
0
        }
843
844
0
        num_sig_coeff = 0;
845
0
        sum_abs_level = 0;
846
847
0
#ifdef ENABLE_MAIN_REXT_PROFILE
848
0
        WORD32 sb_type = 2 * (c_idx == 0 ? 1 : 0);
849
0
        if(ps_sps->i1_persistent_rice_adaptation_enabled_flag)
850
0
        {
851
0
            if(!(transform_skip_flag == 0 && ps_codec->s_parse.s_cu.i4_cu_transquant_bypass == 0))
852
0
            {
853
0
                sb_type += 1;
854
0
            }
855
0
            rice_param = ps_cabac->ai4_rice_stat_coeff[sb_type] / 4;
856
0
        }
857
0
        else
858
0
#endif
859
0
        {
860
0
            rice_param = 0;
861
0
        }
862
0
        {
863
0
            UWORD32 clz;
864
0
            UWORD32 u4_sig_coeff_map_shift;
865
0
            clz = CLZ(u4_sig_coeff_map);
866
0
            n = 31 - clz;
867
0
            u4_sig_coeff_map_shift = u4_sig_coeff_map << clz;
868
            /* For loop for n changed to do while to break early if sig_coeff_map_shift becomes zero */
869
0
            do
870
0
            {
871
872
0
                if((u4_sig_coeff_map_shift >> 31) & 1)
873
0
                {
874
0
                    WORD32 base_lvl;
875
0
                    WORD32 coeff_abs_level_remaining;
876
0
                    WORD32 level;
877
0
                    base_lvl = 1;
878
879
                    /* Update base_lvl if it is greater than 1 */
880
0
                    if((u4_coeff_abs_level_greater1_map >> n) & 1)
881
0
                        base_lvl++;
882
883
                    /* Update base_lvl if it is greater than 2 */
884
0
                    if((u4_coeff_abs_level_greater2_map >> n) & 1)
885
0
                        base_lvl++;
886
887
                    /* If level is greater than 3/2/1 based on the greater1 and greater2 maps,
888
                     * decode remaining level (level - base_lvl) will be signalled as bypass bins
889
                     */
890
0
                    coeff_abs_level_remaining = 0;
891
0
                    if(base_lvl == ((num_sig_coeff < 8) ? ((n == first_greater1_scan_pos) ? 3 : 2) : 1))
892
0
                    {
893
0
                        UWORD32 u4_prefix;
894
0
                        WORD32 bin;
895
896
0
                        u4_prefix = 0;
897
898
0
                        do
899
0
                        {
900
0
                            IHEVCD_CABAC_DECODE_BYPASS_BIN(bin, ps_cabac, ps_bitstrm);
901
0
                            u4_prefix++;
902
903
0
                            if((WORD32)u4_prefix == 19 - rice_param)
904
0
                            {
905
0
                                bin = 1;
906
0
                                break;
907
0
                            }
908
909
0
                        }while(bin);
910
911
0
                        u4_prefix = u4_prefix - 1;
912
0
                        if(u4_prefix < 3)
913
0
                        {
914
0
                            UWORD32 u4_suffix;
915
916
0
                            coeff_abs_level_remaining = (u4_prefix << rice_param);
917
0
                            if(rice_param)
918
0
                            {
919
0
                                IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, rice_param);
920
921
0
                                coeff_abs_level_remaining |= u4_suffix;
922
0
                            }
923
0
                        }
924
0
                        else
925
0
                        {
926
0
                            UWORD32 u4_suffix;
927
0
                            UWORD32 u4_numbins;
928
929
                            //u4_prefix = CLIP3(u4_prefix, 0, 19 - rice_param);
930
931
0
                            u4_numbins = (u4_prefix - 3 + rice_param);
932
0
                            coeff_abs_level_remaining = (((1 << (u4_prefix - 3)) + 3 - 1) << rice_param);
933
0
                            if(u4_numbins)
934
0
                            {
935
0
                                IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, u4_numbins);
936
0
                                coeff_abs_level_remaining += u4_suffix;
937
0
                            }
938
0
                        }
939
940
941
0
                        AEV_TRACE("coeff_abs_level_remaining", coeff_abs_level_remaining, ps_cabac->u4_range);
942
0
                        base_lvl += coeff_abs_level_remaining;
943
944
0
#ifdef ENABLE_MAIN_REXT_PROFILE
945
0
                        if(i1_update_stats)
946
0
                        {
947
0
                            if(coeff_abs_level_remaining
948
0
                                            >= (3 << (ps_cabac->ai4_rice_stat_coeff[sb_type] / 4)))
949
0
                            {
950
0
                                ps_cabac->ai4_rice_stat_coeff[sb_type]++;
951
0
                            }
952
0
                            else if((2 * coeff_abs_level_remaining
953
0
                                            < (1 << (ps_cabac->ai4_rice_stat_coeff[sb_type] / 4)))
954
0
                                            && ps_cabac->ai4_rice_stat_coeff[sb_type] > 0)
955
0
                            {
956
0
                                ps_cabac->ai4_rice_stat_coeff[sb_type]--;
957
0
                            }
958
0
                            i1_update_stats = 0;
959
0
                        }
960
0
#endif
961
0
                    }
962
963
                    /* update the rice param based on coeff level */
964
0
                    if(base_lvl > (3 << rice_param))
965
0
                    {
966
0
#ifdef ENABLE_MAIN_REXT_PROFILE
967
0
                        if(ps_sps->i1_persistent_rice_adaptation_enabled_flag)
968
0
                        {
969
0
                            rice_param += 1;
970
0
                        }
971
0
                        else
972
0
#endif
973
0
                        {
974
0
                            rice_param = MIN((rice_param + 1), 4);
975
0
                        }
976
0
                    }
977
978
                    /* Compute absolute level */
979
0
                    level = base_lvl;
980
981
                    /* Update level with the sign */
982
0
                    if((u4_coeff_sign_map >> 31) & 1)
983
0
                        level = -level;
984
985
0
                    u4_coeff_sign_map <<= 1;
986
                    /* Update sign in case sign is hidden */
987
0
                    if(sign_data_hiding_flag && sign_hidden)
988
0
                    {
989
0
                        sum_abs_level += base_lvl;
990
991
0
                        if(n == first_sig_scan_pos && ((sum_abs_level % 2) == 1))
992
0
                            level = -level;
993
0
                    }
994
995
                    /* Store the resulting level in non-zero level array */
996
0
                    ps_tu_sblk_coeff_data->ai2_level[num_sig_coeff++] = level;
997
                    //AEV_TRACE("level", level, 0);
998
0
                }
999
0
                u4_sig_coeff_map_shift <<= 1;
1000
0
                n--;
1001
                /* If there are zero coeffs, then shift by as many zero coeffs and decrement n */
1002
0
                clz = CLZ(u4_sig_coeff_map_shift);
1003
0
                u4_sig_coeff_map_shift <<= clz;
1004
0
                n -= (WORD32)clz;
1005
1006
1007
0
            }while(u4_sig_coeff_map_shift);
1008
0
        }
1009
1010
        /* Increment the pv_tu_sblk_coeff_data */
1011
0
        {
1012
0
            UWORD8 *pu1_buf = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
1013
0
            pu1_buf += sizeof(tu_sblk_coeff_data_t) - SUBBLK_COEFF_CNT * sizeof(WORD16);
1014
0
            pu1_buf += num_coeff * sizeof(WORD16);
1015
0
            ps_codec->s_parse.pv_tu_coeff_data = pu1_buf;
1016
1017
0
        }
1018
1019
0
    }
1020
    /* Set number of coded sub blocks in the current TU */
1021
0
    *pi1_num_coded_subblks = num_subblks;
1022
1023
0
    return ret;
1024
0
}