Coverage Report

Created: 2026-01-17 06:25

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
5.27M
{
186
5.27M
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
187
5.27M
    WORD32 transform_skip_flag;
188
5.27M
    WORD32 value;
189
5.27M
    pps_t *ps_pps;
190
5.27M
    WORD32 last_scan_pos, last_sub_blk;
191
5.27M
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
192
5.27M
    WORD32 last_significant_coeff_x_prefix, last_significant_coeff_y_prefix;
193
5.27M
    WORD32 last_significant_coeff_x, last_significant_coeff_y;
194
5.27M
    const UWORD8 *pu1_scan_blk = NULL, *pu1_scan_coeff;
195
5.27M
    WORD32 scan_idx;
196
5.27M
    WORD32 i;
197
5.27M
    WORD32 sign_data_hiding_flag;
198
5.27M
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
199
5.27M
    WORD32 gt1_ctxt = 1;
200
5.27M
    WORD32 c_max;
201
5.27M
    UWORD16 au2_csbf[9];
202
5.27M
    tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data;
203
5.27M
    WORD8 *pi1_num_coded_subblks;
204
5.27M
    WORD32 num_subblks;
205
5.27M
    WORD32 sig_coeff_base_ctxt, abs_gt1_base_ctxt;
206
5.27M
    UNUSED(x0);
207
5.27M
    UNUSED(y0);
208
5.27M
    ps_pps = ps_codec->s_parse.ps_pps;
209
210
5.27M
    sign_data_hiding_flag = ps_pps->i1_sign_data_hiding_flag;
211
5.27M
    transform_skip_flag = 0;
212
5.27M
    if(ps_pps->i1_transform_skip_enabled_flag &&
213
5.08M
       !ps_codec->s_parse.s_cu.i4_cu_transquant_bypass &&
214
5.05M
       (log2_trafo_size == 2))
215
684k
    {
216
684k
        WORD32 ctxt_idx;
217
218
684k
        if(!c_idx)
219
449k
        {
220
449k
            ctxt_idx = IHEVC_CAB_TFM_SKIP0;
221
449k
        }
222
234k
        else
223
234k
        {
224
234k
            ctxt_idx = IHEVC_CAB_TFM_SKIP12;
225
234k
        }
226
684k
        TRACE_CABAC_CTXT("transform_skip_flag", ps_cabac->u4_range, ctxt_idx);
227
684k
        value = ihevcd_cabac_decode_bin(ps_cabac,
228
684k
                                        ps_bitstrm,
229
684k
                                        ctxt_idx);
230
684k
        AEV_TRACE("transform_skip_flag", value, ps_cabac->u4_range);
231
684k
        transform_skip_flag = value;
232
684k
    }
233
234
    /* code the last_coeff_x_prefix as tunary binarized code */
235
5.27M
    {
236
5.27M
        WORD32 ctxt_idx_x, ctxt_idx_y, ctx_shift;
237
5.27M
        WORD32 ctx_offset;
238
5.27M
        c_max = (log2_trafo_size << 1) - 1;
239
240
5.27M
        if(!c_idx)
241
3.67M
        {
242
3.67M
            ctx_offset = (3 * (log2_trafo_size - 2)) + ((log2_trafo_size - 1) >> 2);
243
3.67M
            ctxt_idx_x = IHEVC_CAB_COEFFX_PREFIX + ctx_offset;
244
3.67M
            ctxt_idx_y = IHEVC_CAB_COEFFY_PREFIX + ctx_offset;
245
3.67M
            ctx_shift  = (log2_trafo_size + 1) >> 2;
246
3.67M
        }
247
1.59M
        else
248
1.59M
        {
249
1.59M
            ctxt_idx_x = IHEVC_CAB_COEFFX_PREFIX + 15;
250
1.59M
            ctxt_idx_y = IHEVC_CAB_COEFFY_PREFIX + 15;
251
1.59M
            ctx_shift  = log2_trafo_size  - 2;
252
1.59M
        }
253
254
5.27M
        TRACE_CABAC_CTXT("last_coeff_x_prefix", ps_cabac->u4_range, ctxt_idx_x);
255
5.27M
        last_significant_coeff_x_prefix = ihevcd_cabac_decode_bins_tunary(ps_cabac,
256
5.27M
                                                                          ps_bitstrm,
257
5.27M
                                                                          c_max,
258
5.27M
                                                                          ctxt_idx_x,
259
5.27M
                                                                          ctx_shift,
260
5.27M
                                                                          c_max);
261
262
5.27M
        AEV_TRACE("last_coeff_x_prefix", last_significant_coeff_x_prefix, ps_cabac->u4_range);
263
264
5.27M
        TRACE_CABAC_CTXT("last_coeff_y_prefix", ps_cabac->u4_range, ctxt_idx_y);
265
5.27M
        last_significant_coeff_y_prefix = ihevcd_cabac_decode_bins_tunary(ps_cabac,
266
5.27M
                                                                          ps_bitstrm,
267
5.27M
                                                                          c_max,
268
5.27M
                                                                          ctxt_idx_y,
269
5.27M
                                                                          ctx_shift,
270
5.27M
                                                                          c_max);
271
272
5.27M
        AEV_TRACE("last_coeff_y_prefix", last_significant_coeff_y_prefix, ps_cabac->u4_range);
273
274
275
5.27M
        last_significant_coeff_x = last_significant_coeff_x_prefix;
276
5.27M
        if(last_significant_coeff_x_prefix > 3)
277
1.29M
        {
278
1.29M
            WORD32 suf_length = ((last_significant_coeff_x_prefix - 2) >> 1);
279
280
1.29M
            value = ihevcd_cabac_decode_bypass_bins(ps_cabac,
281
1.29M
                                                    ps_bitstrm,
282
1.29M
                                                    suf_length);
283
284
1.29M
            AEV_TRACE("last_coeff_x_suffix", value, ps_cabac->u4_range);
285
286
287
1.29M
            last_significant_coeff_x =
288
1.29M
                            (1 << ((last_significant_coeff_x_prefix >> 1) - 1)) *
289
1.29M
                            (2 + (last_significant_coeff_x_prefix & 1)) + value;
290
1.29M
        }
291
292
293
5.27M
        last_significant_coeff_y = last_significant_coeff_y_prefix;
294
5.27M
        if(last_significant_coeff_y_prefix > 3)
295
1.52M
        {
296
1.52M
            WORD32 suf_length = ((last_significant_coeff_y_prefix - 2) >> 1);
297
1.52M
            value = ihevcd_cabac_decode_bypass_bins(ps_cabac,
298
1.52M
                                                    ps_bitstrm,
299
1.52M
                                                    suf_length);
300
301
1.52M
            AEV_TRACE("last_coeff_y_suffix", value, ps_cabac->u4_range);
302
1.52M
            last_significant_coeff_y =
303
1.52M
                            (1 << ((last_significant_coeff_y_prefix >> 1) - 1)) *
304
1.52M
                            (2 + (last_significant_coeff_y_prefix & 1)) + value;
305
1.52M
        }
306
307
5.27M
    }
308
309
    /* Choose a scan matrix based on intra flag, intra pred mode, transform size
310
     and luma/chroma */
311
5.27M
    scan_idx = SCAN_DIAG_UPRIGHT;
312
5.27M
    if(PRED_MODE_INTRA == ps_codec->s_parse.s_cu.i4_pred_mode)
313
4.92M
    {
314
4.92M
        if((2 == log2_trafo_size) || ((3 == log2_trafo_size) && (0 == c_idx)))
315
1.15M
        {
316
1.15M
            if((6 <= intra_pred_mode) &&
317
697k
               (14 >= intra_pred_mode))
318
182k
            {
319
182k
                scan_idx = SCAN_VERT;
320
182k
            }
321
976k
            else if((22 <= intra_pred_mode) &&
322
369k
                    (30 >= intra_pred_mode))
323
293k
            {
324
293k
                scan_idx = SCAN_HORZ;
325
293k
            }
326
1.15M
        }
327
4.92M
    }
328
329
    /* In case the scan is vertical, then swap  X and Y positions */
330
5.27M
    if(SCAN_VERT == scan_idx)
331
182k
    {
332
182k
        SWAP(last_significant_coeff_x, last_significant_coeff_y);
333
182k
    }
334
335
5.27M
    {
336
5.27M
        WORD8 *pi1_scan_idx;
337
5.27M
        WORD8 *pi1_buf = (WORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
338
339
        /* First WORD8 gives number of coded subblocks */
340
5.27M
        pi1_num_coded_subblks = pi1_buf++;
341
342
        /* Set number of coded subblocks in the current TU to zero */
343
        /* This will be updated later */
344
5.27M
        *pi1_num_coded_subblks = 0;
345
346
        /* Second WORD8 gives (scan idx << 1) | trans_skip */
347
5.27M
        pi1_scan_idx = pi1_buf++;
348
5.27M
        *pi1_scan_idx = (scan_idx << 1) | transform_skip_flag;
349
350
        /* Store the incremented pointer in pv_tu_coeff_data */
351
5.27M
        ps_codec->s_parse.pv_tu_coeff_data = pi1_buf;
352
353
5.27M
    }
354
    /**
355
     * Given last_significant_coeff_y and last_significant_coeff_x find last sub block
356
     * This is done by ignoring lower two bits of last_significant_coeff_y and last_significant_coeff_x
357
     * and using scan matrix for lookup
358
     */
359
360
    /* If transform is 4x4, last_sub_blk is zero */
361
5.27M
    last_sub_blk = 0;
362
363
    /* If transform is larger than 4x4, then based on scan_idx and transform size, choose a scan table */
364
365
5.27M
    if(log2_trafo_size > 2)
366
4.50M
    {
367
4.50M
        WORD32 scan_pos;
368
4.50M
        WORD32 scan_mat_size;
369
4.50M
        pu1_scan_blk = (UWORD8 *)gapv_ihevc_scan[scan_idx * 3 + (log2_trafo_size - 2 - 1)];
370
371
372
        /* Divide the current transform to 4x4 subblocks and count number of 4x4 in the first row */
373
        /* This will be size of scan matrix to be used for subblock scanning */
374
4.50M
        scan_mat_size = 1 << (log2_trafo_size - 2);
375
4.50M
        scan_pos = ((last_significant_coeff_y >> 2) * scan_mat_size) +
376
4.50M
                        (last_significant_coeff_x >> 2);
377
378
4.50M
        last_sub_blk = pu1_scan_blk[scan_pos];
379
4.50M
    }
380
5.27M
    pu1_scan_coeff  = &gau1_ihevc_scan4x4[scan_idx][0];
381
382
5.27M
    {
383
5.27M
        WORD32 scan_pos;
384
385
5.27M
        scan_pos = ((last_significant_coeff_y & 3) << 2) +
386
5.27M
                        (last_significant_coeff_x & 3);
387
388
5.27M
        last_scan_pos = pu1_scan_coeff[scan_pos];
389
5.27M
    }
390
5.27M
    if(log2_trafo_size > 2)
391
4.50M
        pu1_scan_blk = (UWORD8 *)gapv_ihevc_invscan[scan_idx * 3 + (log2_trafo_size - 2 - 1)];
392
5.27M
    pu1_scan_coeff  = &gau1_ihevc_invscan4x4[scan_idx][0];
393
394
    /* Set CSBF array to zero */
395
5.27M
    {
396
5.27M
        UWORD32 *pu4_csbf;
397
5.27M
        pu4_csbf = (void *)au2_csbf;
398
5.27M
        *pu4_csbf++ = 0;
399
5.27M
        *pu4_csbf++ = 0;
400
5.27M
        *pu4_csbf++ = 0;
401
5.27M
        *pu4_csbf = 0;
402
        /* To avoid a check for y pos, 9th WORD16 in the array is set to zero */
403
5.27M
        au2_csbf[8] = 0;
404
5.27M
    }
405
406
    /*************************************************************************/
407
    /* derive base context index for sig coeff as per section 9.3.3.1.4      */
408
    /* TODO; convert to look up based on luma/chroma, scan type and tfr size */
409
    /*************************************************************************/
410
5.27M
    if(!c_idx)
411
3.67M
    {
412
3.67M
        sig_coeff_base_ctxt = IHEVC_CAB_COEFF_FLAG;
413
3.67M
        abs_gt1_base_ctxt = IHEVC_CAB_COEFABS_GRTR1_FLAG;
414
415
3.67M
        if(3 == log2_trafo_size)
416
643k
        {
417
            /* 8x8 transform size */
418
643k
            sig_coeff_base_ctxt += (scan_idx == SCAN_DIAG_UPRIGHT) ? 9 : 15;
419
643k
        }
420
3.02M
        else  if(3 < log2_trafo_size)
421
2.54M
        {
422
            /* larger transform sizes */
423
2.54M
            sig_coeff_base_ctxt += 21;
424
2.54M
        }
425
3.67M
    }
426
1.59M
    else
427
1.59M
    {
428
        /* chroma context initializations */
429
1.59M
        sig_coeff_base_ctxt = IHEVC_CAB_COEFF_FLAG + 27;
430
1.59M
        abs_gt1_base_ctxt = IHEVC_CAB_COEFABS_GRTR1_FLAG + 16;
431
432
1.59M
        if(3 == log2_trafo_size)
433
660k
        {
434
            /* 8x8 transform size */
435
660k
            sig_coeff_base_ctxt += 9;
436
660k
        }
437
937k
        else  if(3 < log2_trafo_size)
438
651k
        {
439
            /* larger transform sizes */
440
651k
            sig_coeff_base_ctxt += 12;
441
651k
        }
442
1.59M
    }
443
5.27M
    num_subblks = 0;
444
    /* Parse each 4x4 subblocks */
445
19.8M
    for(i = last_sub_blk; i >= 0; i--)
446
14.6M
    {
447
14.6M
        WORD32 sub_blk_pos;
448
14.6M
        WORD32 infer_sig_coeff_flag;
449
14.6M
        WORD32 cur_csbf;
450
451
14.6M
        WORD32 n;
452
14.6M
        WORD32 num_coeff;
453
        /* Sig coeff map for 16 entries in raster scan order. Upper 16 bits are used.
454
         * MSB gives sig coeff flag for 0th coeff and so on
455
         * UWORD16 would have been enough but kept as UWORD32 for code optimizations
456
         * In arm unnecessary masking operations are saved
457
         */
458
14.6M
        UWORD32 u4_sig_coeff_map_raster;
459
14.6M
        WORD32 sign_hidden;
460
461
        /* Sig coeff map in scan order */
462
14.6M
        UWORD32 u4_sig_coeff_map;
463
14.6M
        WORD32 coeff_abs_level_greater2_flag;
464
14.6M
        UWORD32 u4_coeff_abs_level_greater1_map;
465
14.6M
        UWORD32 u4_coeff_abs_level_greater2_map;
466
14.6M
        UWORD32 u4_coeff_sign_map;
467
14.6M
        WORD32 first_sig_scan_pos, last_sig_scan_pos, num_greater1_flag, first_greater1_scan_pos;
468
14.6M
        WORD32  num_sig_coeff, sum_abs_level;
469
14.6M
        WORD32 nbr_csbf;
470
471
472
14.6M
        WORD32 ctxt_set;
473
14.6M
        WORD32 rice_param;
474
14.6M
        WORD32 xs, ys;
475
476
477
14.6M
        sub_blk_pos  = 0;
478
14.6M
        if(i && (log2_trafo_size > 2))
479
9.34M
            sub_blk_pos = pu1_scan_blk[i];
480
481
        /* Get xs and ys from scan position */
482
        /* This is needed for context modelling of significant coeff flag */
483
14.6M
        xs = sub_blk_pos & ((1 << (log2_trafo_size - 2)) - 1);
484
14.6M
        ys = sub_blk_pos >> (log2_trafo_size - 2);
485
486
487
        /* Check if neighbor subblocks are coded */
488
14.6M
        {
489
490
14.6M
            nbr_csbf = 0;
491
492
            /* Get Bottom sub blocks CSBF */
493
14.6M
            nbr_csbf |= (au2_csbf[ys + 1] >> xs) & 1;
494
14.6M
            nbr_csbf <<= 1;
495
496
            /* Get Right sub blocks CSBF */
497
            /* Even if xs is equal to (1 << (log2_trafo_size - 2 )) - 1,
498
               since au2_csbf is set to zero at the beginning, csbf for
499
               neighbor will be read as 0 */
500
501
14.6M
            nbr_csbf |= (au2_csbf[ys] >> (xs + 1)) & 1;
502
503
504
14.6M
        }
505
14.6M
        cur_csbf = 0;
506
507
        /* DC coeff is inferred, only if coded_sub_block is explicitly parsed as 1 */
508
        /* i.e. it is not inferred for first and last subblock */
509
14.6M
        infer_sig_coeff_flag = 0;
510
14.6M
        if((i < last_sub_blk) && (i > 0))
511
7.31M
        {
512
7.31M
            WORD32 ctxt_idx  = IHEVC_CAB_CODED_SUBLK_IDX;
513
514
            /* ctxt based on right / bottom avail csbf, section 9.3.3.1.3 */
515
7.31M
            ctxt_idx += (nbr_csbf) ? 1 : 0;
516
517
            /* Ctxt based on luma or chroma */
518
7.31M
            ctxt_idx += c_idx  ? 2 : 0;
519
7.31M
            TRACE_CABAC_CTXT("coded_sub_block_flag", ps_cabac->u4_range, ctxt_idx);
520
29.2M
            IHEVCD_CABAC_DECODE_BIN(cur_csbf, ps_cabac, ps_bitstrm, ctxt_idx);
521
29.2M
            AEV_TRACE("coded_sub_block_flag", cur_csbf, ps_cabac->u4_range);
522
523
29.2M
            infer_sig_coeff_flag = 1;
524
29.2M
        }
525
7.30M
        else /* if((i == last_sub_blk) || (sub_blk_pos == 0)) */
526
7.30M
        {
527
            /* CSBF is set to 1 for first and last subblock */
528
            /* Note for these subblocks sig_coeff_map is not inferred but instead parsed */
529
7.30M
            cur_csbf = 1;
530
7.30M
        }
531
532
        /* Set current sub blocks CSBF */
533
14.6M
        {
534
14.6M
            UWORD32 u4_mask = 1 << xs;
535
14.6M
            if(cur_csbf)
536
8.18M
                au2_csbf[ys] |= u4_mask;
537
6.42M
            else
538
6.42M
                au2_csbf[ys] &= ~u4_mask;
539
540
14.6M
        }
541
542
        /* If current subblock is not coded, proceed to the next subblock */
543
14.6M
        if(0 == cur_csbf)
544
6.42M
            continue;
545
546
8.18M
        n = 15;
547
8.18M
        u4_sig_coeff_map_raster = 0;
548
8.18M
        u4_sig_coeff_map = 0;
549
8.18M
        num_coeff = 0;
550
8.18M
        if(i == last_sub_blk)
551
5.27M
        {
552
5.27M
            WORD32 pos = ((last_significant_coeff_y & 3) << 2) +
553
5.27M
                            (last_significant_coeff_x & 3);
554
5.27M
            n = (last_scan_pos - 1);
555
            /* Set Significant coeff map for last significant coeff flag as 1 */
556
5.27M
            u4_sig_coeff_map_raster = 1 << pos;
557
5.27M
            u4_sig_coeff_map = 1 << last_scan_pos;
558
5.27M
            num_coeff = 1;
559
5.27M
        }
560
561
66.3M
        for(; n >= 0; n--)
562
58.2M
        {
563
58.2M
            WORD32 significant_coeff_flag;
564
565
58.2M
            if((n > 0 || !infer_sig_coeff_flag))
566
58.0M
            {
567
                //WORD32 coeff_pos;
568
58.0M
                WORD32 sig_ctxinc;
569
58.0M
                WORD32 ctxt_idx;
570
571
                /* Coefficient position is needed for deriving context index for significant_coeff_flag */
572
                //coeff_pos = pu1_scan_coeff[n];
573
                /* derive the context inc as per section 9.3.3.1.4 */
574
58.0M
                sig_ctxinc = 0;
575
58.0M
                if(2 == log2_trafo_size)
576
3.59M
                {
577
578
                    /* 4x4 transform size increment uses lookup */
579
3.59M
                    sig_ctxinc = gau1_ihevcd_sigcoeff_ctxtinc_tr4[scan_idx][n];
580
3.59M
                }
581
54.4M
                else if(n || i)
582
51.5M
                {
583
                    /* ctxt for AC coeff depends on curpos and neigbour csbf */
584
51.5M
                    sig_ctxinc = gau1_ihevcd_sigcoeff_ctxtinc[scan_idx][nbr_csbf][n];
585
586
                    /* based on luma subblock pos */
587
51.5M
                    sig_ctxinc += (i && (!c_idx)) ? 3 : 0;
588
589
51.5M
                }
590
2.89M
                else
591
2.89M
                {
592
                    /* DC coeff has fixed context for luma and chroma */
593
2.89M
                    sig_coeff_base_ctxt = (0 == c_idx) ? IHEVC_CAB_COEFF_FLAG :
594
2.89M
                                                         (IHEVC_CAB_COEFF_FLAG + 27);
595
2.89M
                }
596
597
58.0M
                ctxt_idx = sig_ctxinc + sig_coeff_base_ctxt;
598
58.0M
                TRACE_CABAC_CTXT("significant_coeff_flag", ps_cabac->u4_range, ctxt_idx);
599
232M
                IHEVCD_CABAC_DECODE_BIN(significant_coeff_flag, ps_cabac,
600
232M
                                        ps_bitstrm,
601
232M
                                        ctxt_idx);
602
232M
                AEV_TRACE("significant_coeff_flag", significant_coeff_flag, ps_cabac->u4_range);
603
604
605
                /* If at least one non-zero coeff is signalled then do not infer sig coeff map */
606
                /* for (0,0) coeff in the current sub block */
607
232M
                if(significant_coeff_flag)
608
14.4M
                    infer_sig_coeff_flag = 0;
609
610
//                u4_sig_coeff_map_raster |= significant_coeff_flag
611
//                              << coeff_pos;
612
232M
                u4_sig_coeff_map |= significant_coeff_flag << n;
613
232M
                num_coeff += significant_coeff_flag;
614
232M
            }
615
616
617
58.2M
        }
618
        /*********************************************************************/
619
        /* If infer_sig_coeff_flag is 1 then treat the 0th coeff as non zero */
620
        /* If infer_sig_coeff_flag is zero, then last significant_coeff_flag */
621
        /* is parsed in the above loop                                       */
622
        /*********************************************************************/
623
8.18M
        if(infer_sig_coeff_flag)
624
181k
        {
625
181k
            u4_sig_coeff_map_raster |= 1;
626
181k
            u4_sig_coeff_map |= 1;
627
181k
            num_coeff++;
628
181k
        }
629
630
        /*********************************************************************/
631
        /* First subblock does not get an explicit csbf. It is assumed to    */
632
        /* be 1. For this subblock there is chance of getting all            */
633
        /* sig_coeff_flags to be zero. In such a case proceed to the next    */
634
        /* subblock(which is end of parsing for the current transform block) */
635
        /*********************************************************************/
636
637
8.18M
        if(0 == num_coeff)
638
579k
            continue;
639
640
        /* Increment number of coded subblocks for the current TU */
641
7.60M
        num_subblks++;
642
643
        /* Set sig coeff map and subblock position */
644
7.60M
        ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)ps_codec->s_parse.pv_tu_coeff_data;
645
7.60M
        ps_tu_sblk_coeff_data->u2_sig_coeff_map = u4_sig_coeff_map;
646
7.60M
        ps_tu_sblk_coeff_data->u2_subblk_pos = (ys << 8) | xs;
647
648
7.60M
        first_sig_scan_pos = 16;
649
7.60M
        last_sig_scan_pos = -1;
650
7.60M
        num_greater1_flag = 0;
651
7.60M
        first_greater1_scan_pos = -1;
652
7.60M
        u4_coeff_abs_level_greater1_map = 0;
653
654
655
        /* context set based on luma subblock pos */
656
7.60M
        ctxt_set = (i && (!c_idx)) ? 2 : 0;
657
658
        /* See section 9.3.3.1.5           */
659
7.60M
        ctxt_set += (0 == gt1_ctxt) ? 1 : 0;
660
661
7.60M
        gt1_ctxt = 1;
662
        /* Instead of initializing n to 15, set it to 31-CLZ(sig coeff map) */
663
7.60M
        {
664
7.60M
            UWORD32 u4_sig_coeff_map_shift;
665
7.60M
            UWORD32 clz;
666
7.60M
            clz = CLZ(u4_sig_coeff_map);
667
7.60M
            n = 31 - clz;
668
7.60M
            u4_sig_coeff_map_shift = u4_sig_coeff_map << clz;
669
            /* For loop for n changed to do while to break early if sig_coeff_map_shift becomes zero */
670
7.60M
            do
671
18.9M
            {
672
                //WORD32 coeff_pos;
673
18.9M
                WORD32 ctxt_idx;
674
675
                //TODO: Scan lookup will be removed later and instead u4_sig_coeff_map will be used
676
                //coeff_pos = pu1_scan_coeff[n];
677
678
18.9M
                if((u4_sig_coeff_map_shift >> 31) & 1)
679
18.9M
                {
680
681
                    /* abs_level_greater1_flag is sent for only first 8 non-zero levels in a subblock */
682
18.9M
                    if(num_greater1_flag < 8)
683
18.5M
                    {
684
18.5M
                        WORD32 coeff_abs_level_greater1_flag;
685
686
18.5M
                        ctxt_idx = (ctxt_set * 4) + abs_gt1_base_ctxt + gt1_ctxt;
687
688
18.5M
                        TRACE_CABAC_CTXT("coeff_abs_level_greater1_flag", ps_cabac->u4_range, ctxt_idx);
689
74.2M
                        IHEVCD_CABAC_DECODE_BIN(coeff_abs_level_greater1_flag, ps_cabac, ps_bitstrm, ctxt_idx);
690
74.2M
                        AEV_TRACE("coeff_abs_level_greater1_flag", coeff_abs_level_greater1_flag, ps_cabac->u4_range);
691
692
74.2M
                        u4_coeff_abs_level_greater1_map |= coeff_abs_level_greater1_flag << n;
693
74.2M
                        num_greater1_flag++;
694
695
                        /* first_greater1_scan_pos is obtained using CLZ on u4_coeff_abs_level_greater1_map*/
696
                        /*  outside the loop instead of the following check inside the loop                */
697
                        /* if( coeff_abs_level_greater1_flag && first_greater1_scan_pos == -1) */
698
                        /*    first_greater1_scan_pos = n;                                     */
699
700
74.2M
                        if(coeff_abs_level_greater1_flag)
701
4.03M
                        {
702
4.03M
                            gt1_ctxt = 0;
703
4.03M
                        }
704
14.5M
                        else if(gt1_ctxt && (gt1_ctxt < 3))
705
8.59M
                        {
706
8.59M
                            gt1_ctxt++;
707
8.59M
                        }
708
709
74.2M
                    }
710
360k
                    else
711
360k
                        break;
712
713
                    /* instead of computing last and first significan scan position using checks below */
714
                    /* They are computed outside the loop using CLZ and CTZ on sig_coeff_map */
715
                    /* if(last_sig_scan_pos == -1)                          */
716
                    /*    last_sig_scan_pos = n;                            */
717
                    /*  first_sig_scan_pos = n;                             */
718
18.9M
                }
719
18.5M
                u4_sig_coeff_map_shift <<= 1;
720
18.5M
                n--;
721
                /* If there are zero coeffs, then shift by as many zero coeffs and decrement n */
722
18.5M
                clz = CLZ(u4_sig_coeff_map_shift);
723
18.5M
                u4_sig_coeff_map_shift <<= clz;
724
18.5M
                n -= (WORD32)clz;
725
18.5M
            }while(u4_sig_coeff_map_shift);
726
7.60M
        }
727
        /* At this level u4_sig_coeff_map is non-zero i.e. has atleast one non-zero coeff */
728
7.60M
        last_sig_scan_pos = (31 - CLZ(u4_sig_coeff_map));
729
7.60M
        first_sig_scan_pos = CTZ(u4_sig_coeff_map);
730
7.60M
        sign_hidden = (((last_sig_scan_pos - first_sig_scan_pos) > 3) && !ps_codec->s_parse.s_cu.i4_cu_transquant_bypass);
731
732
7.60M
        u4_coeff_abs_level_greater2_map = 0;
733
734
7.60M
        if(u4_coeff_abs_level_greater1_map)
735
2.38M
        {
736
            /* Check if the first level > 1 is greater than 2 */
737
2.38M
            WORD32 ctxt_idx;
738
2.38M
            first_greater1_scan_pos = (31 - CLZ(u4_coeff_abs_level_greater1_map));
739
740
741
2.38M
            ctxt_idx = IHEVC_CAB_COEFABS_GRTR2_FLAG;
742
743
2.38M
            ctxt_idx += (!c_idx) ? ctxt_set : (ctxt_set + 4);
744
2.38M
            TRACE_CABAC_CTXT("coeff_abs_level_greater2_flag", ps_cabac->u4_range, ctxt_idx);
745
9.53M
            IHEVCD_CABAC_DECODE_BIN(coeff_abs_level_greater2_flag, ps_cabac, ps_bitstrm, ctxt_idx);
746
9.53M
            AEV_TRACE("coeff_abs_level_greater2_flag", coeff_abs_level_greater2_flag, ps_cabac->u4_range);
747
9.53M
            u4_coeff_abs_level_greater2_map = coeff_abs_level_greater2_flag << first_greater1_scan_pos;
748
9.53M
        }
749
750
751
7.60M
        u4_coeff_sign_map = 0;
752
753
        /* Parse sign flags */
754
7.60M
        if(!sign_data_hiding_flag || !sign_hidden)
755
7.12M
        {
756
28.5M
            IHEVCD_CABAC_DECODE_BYPASS_BINS(value, ps_cabac, ps_bitstrm, num_coeff);
757
28.5M
            AEV_TRACE("sign_flags", value, ps_cabac->u4_range);
758
28.5M
            u4_coeff_sign_map = value << (32 - num_coeff);
759
28.5M
        }
760
481k
        else
761
481k
        {
762
1.92M
            IHEVCD_CABAC_DECODE_BYPASS_BINS(value, ps_cabac, ps_bitstrm, (num_coeff - 1));
763
1.92M
            AEV_TRACE("sign_flags", value, ps_cabac->u4_range);
764
1.92M
            u4_coeff_sign_map = value << (32 - (num_coeff - 1));
765
1.92M
        }
766
767
7.60M
        num_sig_coeff = 0;
768
7.60M
        sum_abs_level = 0;
769
7.60M
        rice_param = 0;
770
7.60M
        {
771
7.60M
            UWORD32 clz;
772
7.60M
            UWORD32 u4_sig_coeff_map_shift;
773
7.60M
            clz = CLZ(u4_sig_coeff_map);
774
7.60M
            n = 31 - clz;
775
7.60M
            u4_sig_coeff_map_shift = u4_sig_coeff_map << clz;
776
            /* For loop for n changed to do while to break early if sig_coeff_map_shift becomes zero */
777
7.60M
            do
778
19.8M
            {
779
780
19.8M
                if((u4_sig_coeff_map_shift >> 31) & 1)
781
19.8M
                {
782
19.8M
                    WORD32 base_lvl;
783
19.8M
                    WORD32 coeff_abs_level_remaining;
784
19.8M
                    WORD32 level;
785
19.8M
                    base_lvl = 1;
786
787
                    /* Update base_lvl if it is greater than 1 */
788
19.8M
                    if((u4_coeff_abs_level_greater1_map >> n) & 1)
789
4.03M
                        base_lvl++;
790
791
                    /* Update base_lvl if it is greater than 2 */
792
19.8M
                    if((u4_coeff_abs_level_greater2_map >> n) & 1)
793
503k
                        base_lvl++;
794
795
                    /* If level is greater than 3/2/1 based on the greater1 and greater2 maps,
796
                     * decode remaining level (level - base_lvl) will be signalled as bypass bins
797
                     */
798
19.8M
                    coeff_abs_level_remaining = 0;
799
19.8M
                    if(base_lvl == ((num_sig_coeff < 8) ? ((n == first_greater1_scan_pos) ? 3 : 2) : 1))
800
3.47M
                    {
801
3.47M
                        UWORD32 u4_prefix;
802
3.47M
                        WORD32 bin;
803
804
3.47M
                        u4_prefix = 0;
805
806
3.47M
                        do
807
6.18M
                        {
808
12.3M
                            IHEVCD_CABAC_DECODE_BYPASS_BIN(bin, ps_cabac, ps_bitstrm);
809
12.3M
                            u4_prefix++;
810
811
12.3M
                            if((WORD32)u4_prefix == 19 - rice_param)
812
3.91k
                            {
813
3.91k
                                bin = 1;
814
3.91k
                                break;
815
3.91k
                            }
816
817
12.3M
                        }while(bin);
818
819
3.47M
                        u4_prefix = u4_prefix - 1;
820
3.47M
                        if(u4_prefix < 3)
821
3.14M
                        {
822
3.14M
                            UWORD32 u4_suffix;
823
824
3.14M
                            coeff_abs_level_remaining = (u4_prefix << rice_param);
825
3.14M
                            if(rice_param)
826
781k
                            {
827
3.12M
                                IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, rice_param);
828
829
3.12M
                                coeff_abs_level_remaining |= u4_suffix;
830
3.12M
                            }
831
3.14M
                        }
832
330k
                        else
833
330k
                        {
834
330k
                            UWORD32 u4_suffix;
835
330k
                            UWORD32 u4_numbins;
836
837
                            //u4_prefix = CLIP3(u4_prefix, 0, 19 - rice_param);
838
839
330k
                            u4_numbins = (u4_prefix - 3 + rice_param);
840
330k
                            coeff_abs_level_remaining = (((1 << (u4_prefix - 3)) + 3 - 1) << rice_param);
841
330k
                            if(u4_numbins)
842
216k
                            {
843
864k
                                IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, u4_numbins);
844
864k
                                coeff_abs_level_remaining += u4_suffix;
845
864k
                            }
846
330k
                        }
847
848
849
3.47M
                        AEV_TRACE("coeff_abs_level_remaining", coeff_abs_level_remaining, ps_cabac->u4_range);
850
3.47M
                        base_lvl += coeff_abs_level_remaining;
851
852
3.47M
                    }
853
854
                    /* update the rice param based on coeff level */
855
19.8M
                    if((base_lvl > (3 << rice_param)) && (rice_param < 4))
856
624k
                    {
857
624k
                        rice_param++;
858
624k
                    }
859
860
                    /* Compute absolute level */
861
19.8M
                    level = base_lvl;
862
863
                    /* Update level with the sign */
864
19.8M
                    if((u4_coeff_sign_map >> 31) & 1)
865
6.89M
                        level = -level;
866
867
19.8M
                    u4_coeff_sign_map <<= 1;
868
                    /* Update sign in case sign is hidden */
869
19.8M
                    if(sign_data_hiding_flag && sign_hidden)
870
2.85M
                    {
871
2.85M
                        sum_abs_level += base_lvl;
872
873
2.85M
                        if(n == first_sig_scan_pos && ((sum_abs_level % 2) == 1))
874
224k
                            level = -level;
875
2.85M
                    }
876
877
                    /* Store the resulting level in non-zero level array */
878
19.8M
                    ps_tu_sblk_coeff_data->ai2_level[num_sig_coeff++] = level;
879
                    //AEV_TRACE("level", level, 0);
880
19.8M
                }
881
19.8M
                u4_sig_coeff_map_shift <<= 1;
882
19.8M
                n--;
883
                /* If there are zero coeffs, then shift by as many zero coeffs and decrement n */
884
19.8M
                clz = CLZ(u4_sig_coeff_map_shift);
885
19.8M
                u4_sig_coeff_map_shift <<= clz;
886
19.8M
                n -= (WORD32)clz;
887
888
889
19.8M
            }while(u4_sig_coeff_map_shift);
890
7.60M
        }
891
892
        /* Increment the pv_tu_sblk_coeff_data */
893
7.60M
        {
894
7.60M
            UWORD8 *pu1_buf = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
895
7.60M
            pu1_buf += sizeof(tu_sblk_coeff_data_t) - SUBBLK_COEFF_CNT * sizeof(WORD16);
896
7.60M
            pu1_buf += num_coeff * sizeof(WORD16);
897
7.60M
            ps_codec->s_parse.pv_tu_coeff_data = pu1_buf;
898
899
7.60M
        }
900
901
7.60M
    }
902
    /* Set number of coded sub blocks in the current TU */
903
5.27M
    *pi1_num_coded_subblks = num_subblks;
904
905
5.27M
    return ret;
906
5.27M
}