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 
ihevcd_parse_residual_coding(codec_t * ps_codec,WORD32 x0,WORD32 y0,WORD32 log2_trafo_size,WORD32 c_idx,WORD32 intra_pred_mode)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 {
186     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
187     WORD32 transform_skip_flag;
188     WORD32 value;
189     pps_t *ps_pps;
190     WORD32 last_scan_pos, last_sub_blk;
191     bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
192     WORD32 last_significant_coeff_x_prefix, last_significant_coeff_y_prefix;
193     WORD32 last_significant_coeff_x, last_significant_coeff_y;
194     const UWORD8 *pu1_scan_blk = NULL, *pu1_scan_coeff;
195     WORD32 scan_idx;
196     WORD32 i;
197     WORD32 sign_data_hiding_flag;
198     cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
199     WORD32 gt1_ctxt = 1;
200     WORD32 c_max;
201     UWORD16 au2_csbf[9];
202     tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data;
203     WORD8 *pi1_num_coded_subblks;
204     WORD32 num_subblks;
205     WORD32 sig_coeff_base_ctxt, abs_gt1_base_ctxt;
206     UNUSED(x0);
207     UNUSED(y0);
208     ps_pps = ps_codec->s_parse.ps_pps;
209 
210     sign_data_hiding_flag = ps_pps->i1_sign_data_hiding_flag;
211     transform_skip_flag = 0;
212     if(ps_pps->i1_transform_skip_enabled_flag &&
213        !ps_codec->s_parse.s_cu.i4_cu_transquant_bypass &&
214        (log2_trafo_size == 2))
215     {
216         WORD32 ctxt_idx;
217 
218         if(!c_idx)
219         {
220             ctxt_idx = IHEVC_CAB_TFM_SKIP0;
221         }
222         else
223         {
224             ctxt_idx = IHEVC_CAB_TFM_SKIP12;
225         }
226         TRACE_CABAC_CTXT("transform_skip_flag", ps_cabac->u4_range, ctxt_idx);
227         value = ihevcd_cabac_decode_bin(ps_cabac,
228                                         ps_bitstrm,
229                                         ctxt_idx);
230         AEV_TRACE("transform_skip_flag", value, ps_cabac->u4_range);
231         transform_skip_flag = value;
232     }
233 
234     /* code the last_coeff_x_prefix as tunary binarized code */
235     {
236         WORD32 ctxt_idx_x, ctxt_idx_y, ctx_shift;
237         WORD32 ctx_offset;
238         c_max = (log2_trafo_size << 1) - 1;
239 
240         if(!c_idx)
241         {
242             ctx_offset = (3 * (log2_trafo_size - 2)) + ((log2_trafo_size - 1) >> 2);
243             ctxt_idx_x = IHEVC_CAB_COEFFX_PREFIX + ctx_offset;
244             ctxt_idx_y = IHEVC_CAB_COEFFY_PREFIX + ctx_offset;
245             ctx_shift  = (log2_trafo_size + 1) >> 2;
246         }
247         else
248         {
249             ctxt_idx_x = IHEVC_CAB_COEFFX_PREFIX + 15;
250             ctxt_idx_y = IHEVC_CAB_COEFFY_PREFIX + 15;
251             ctx_shift  = log2_trafo_size  - 2;
252         }
253 
254         TRACE_CABAC_CTXT("last_coeff_x_prefix", ps_cabac->u4_range, ctxt_idx_x);
255         last_significant_coeff_x_prefix = ihevcd_cabac_decode_bins_tunary(ps_cabac,
256                                                                           ps_bitstrm,
257                                                                           c_max,
258                                                                           ctxt_idx_x,
259                                                                           ctx_shift,
260                                                                           c_max);
261 
262         AEV_TRACE("last_coeff_x_prefix", last_significant_coeff_x_prefix, ps_cabac->u4_range);
263 
264         TRACE_CABAC_CTXT("last_coeff_y_prefix", ps_cabac->u4_range, ctxt_idx_y);
265         last_significant_coeff_y_prefix = ihevcd_cabac_decode_bins_tunary(ps_cabac,
266                                                                           ps_bitstrm,
267                                                                           c_max,
268                                                                           ctxt_idx_y,
269                                                                           ctx_shift,
270                                                                           c_max);
271 
272         AEV_TRACE("last_coeff_y_prefix", last_significant_coeff_y_prefix, ps_cabac->u4_range);
273 
274 
275         last_significant_coeff_x = last_significant_coeff_x_prefix;
276         if(last_significant_coeff_x_prefix > 3)
277         {
278             WORD32 suf_length = ((last_significant_coeff_x_prefix - 2) >> 1);
279 
280             value = ihevcd_cabac_decode_bypass_bins(ps_cabac,
281                                                     ps_bitstrm,
282                                                     suf_length);
283 
284             AEV_TRACE("last_coeff_x_suffix", value, ps_cabac->u4_range);
285 
286 
287             last_significant_coeff_x =
288                             (1 << ((last_significant_coeff_x_prefix >> 1) - 1)) *
289                             (2 + (last_significant_coeff_x_prefix & 1)) + value;
290         }
291 
292 
293         last_significant_coeff_y = last_significant_coeff_y_prefix;
294         if(last_significant_coeff_y_prefix > 3)
295         {
296             WORD32 suf_length = ((last_significant_coeff_y_prefix - 2) >> 1);
297             value = ihevcd_cabac_decode_bypass_bins(ps_cabac,
298                                                     ps_bitstrm,
299                                                     suf_length);
300 
301             AEV_TRACE("last_coeff_y_suffix", value, ps_cabac->u4_range);
302             last_significant_coeff_y =
303                             (1 << ((last_significant_coeff_y_prefix >> 1) - 1)) *
304                             (2 + (last_significant_coeff_y_prefix & 1)) + value;
305         }
306 
307     }
308 
309     /* Choose a scan matrix based on intra flag, intra pred mode, transform size
310      and luma/chroma */
311     scan_idx = SCAN_DIAG_UPRIGHT;
312     if(PRED_MODE_INTRA == ps_codec->s_parse.s_cu.i4_pred_mode)
313     {
314         if((2 == log2_trafo_size) || ((3 == log2_trafo_size) && (0 == c_idx)))
315         {
316             if((6 <= intra_pred_mode) &&
317                (14 >= intra_pred_mode))
318             {
319                 scan_idx = SCAN_VERT;
320             }
321             else if((22 <= intra_pred_mode) &&
322                     (30 >= intra_pred_mode))
323             {
324                 scan_idx = SCAN_HORZ;
325             }
326         }
327     }
328 
329     /* In case the scan is vertical, then swap  X and Y positions */
330     if(SCAN_VERT == scan_idx)
331     {
332         SWAP(last_significant_coeff_x, last_significant_coeff_y);
333     }
334 
335     {
336         WORD8 *pi1_scan_idx;
337         WORD8 *pi1_buf = (WORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
338 
339         /* First WORD8 gives number of coded subblocks */
340         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         *pi1_num_coded_subblks = 0;
345 
346         /* Second WORD8 gives (scan idx << 1) | trans_skip */
347         pi1_scan_idx = pi1_buf++;
348         *pi1_scan_idx = (scan_idx << 1) | transform_skip_flag;
349 
350         /* Store the incremented pointer in pv_tu_coeff_data */
351         ps_codec->s_parse.pv_tu_coeff_data = pi1_buf;
352 
353     }
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     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     if(log2_trafo_size > 2)
366     {
367         WORD32 scan_pos;
368         WORD32 scan_mat_size;
369         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         scan_mat_size = 1 << (log2_trafo_size - 2);
375         scan_pos = ((last_significant_coeff_y >> 2) * scan_mat_size) +
376                         (last_significant_coeff_x >> 2);
377 
378         last_sub_blk = pu1_scan_blk[scan_pos];
379     }
380     pu1_scan_coeff  = &gau1_ihevc_scan4x4[scan_idx][0];
381 
382     {
383         WORD32 scan_pos;
384 
385         scan_pos = ((last_significant_coeff_y & 3) << 2) +
386                         (last_significant_coeff_x & 3);
387 
388         last_scan_pos = pu1_scan_coeff[scan_pos];
389     }
390     if(log2_trafo_size > 2)
391         pu1_scan_blk = (UWORD8 *)gapv_ihevc_invscan[scan_idx * 3 + (log2_trafo_size - 2 - 1)];
392     pu1_scan_coeff  = &gau1_ihevc_invscan4x4[scan_idx][0];
393 
394     /* Set CSBF array to zero */
395     {
396         UWORD32 *pu4_csbf;
397         pu4_csbf = (void *)au2_csbf;
398         *pu4_csbf++ = 0;
399         *pu4_csbf++ = 0;
400         *pu4_csbf++ = 0;
401         *pu4_csbf = 0;
402         /* To avoid a check for y pos, 9th WORD16 in the array is set to zero */
403         au2_csbf[8] = 0;
404     }
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     if(!c_idx)
411     {
412         sig_coeff_base_ctxt = IHEVC_CAB_COEFF_FLAG;
413         abs_gt1_base_ctxt = IHEVC_CAB_COEFABS_GRTR1_FLAG;
414 
415         if(3 == log2_trafo_size)
416         {
417             /* 8x8 transform size */
418             sig_coeff_base_ctxt += (scan_idx == SCAN_DIAG_UPRIGHT) ? 9 : 15;
419         }
420         else  if(3 < log2_trafo_size)
421         {
422             /* larger transform sizes */
423             sig_coeff_base_ctxt += 21;
424         }
425     }
426     else
427     {
428         /* chroma context initializations */
429         sig_coeff_base_ctxt = IHEVC_CAB_COEFF_FLAG + 27;
430         abs_gt1_base_ctxt = IHEVC_CAB_COEFABS_GRTR1_FLAG + 16;
431 
432         if(3 == log2_trafo_size)
433         {
434             /* 8x8 transform size */
435             sig_coeff_base_ctxt += 9;
436         }
437         else  if(3 < log2_trafo_size)
438         {
439             /* larger transform sizes */
440             sig_coeff_base_ctxt += 12;
441         }
442     }
443     num_subblks = 0;
444     /* Parse each 4x4 subblocks */
445     for(i = last_sub_blk; i >= 0; i--)
446     {
447         WORD32 sub_blk_pos;
448         WORD32 infer_sig_coeff_flag;
449         WORD32 cur_csbf;
450 
451         WORD32 n;
452         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         UWORD32 u4_sig_coeff_map_raster;
459         WORD32 sign_hidden;
460 
461         /* Sig coeff map in scan order */
462         UWORD32 u4_sig_coeff_map;
463         WORD32 coeff_abs_level_greater2_flag;
464         UWORD32 u4_coeff_abs_level_greater1_map;
465         UWORD32 u4_coeff_abs_level_greater2_map;
466         UWORD32 u4_coeff_sign_map;
467         WORD32 first_sig_scan_pos, last_sig_scan_pos, num_greater1_flag, first_greater1_scan_pos;
468         WORD32  num_sig_coeff, sum_abs_level;
469         WORD32 nbr_csbf;
470 
471 
472         WORD32 ctxt_set;
473         WORD32 rice_param;
474         WORD32 xs, ys;
475 
476 
477         sub_blk_pos  = 0;
478         if(i && (log2_trafo_size > 2))
479             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         xs = sub_blk_pos & ((1 << (log2_trafo_size - 2)) - 1);
484         ys = sub_blk_pos >> (log2_trafo_size - 2);
485 
486 
487         /* Check if neighbor subblocks are coded */
488         {
489 
490             nbr_csbf = 0;
491 
492             /* Get Bottom sub blocks CSBF */
493             nbr_csbf |= (au2_csbf[ys + 1] >> xs) & 1;
494             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             nbr_csbf |= (au2_csbf[ys] >> (xs + 1)) & 1;
502 
503 
504         }
505         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         infer_sig_coeff_flag = 0;
510         if((i < last_sub_blk) && (i > 0))
511         {
512             WORD32 ctxt_idx  = IHEVC_CAB_CODED_SUBLK_IDX;
513 
514             /* ctxt based on right / bottom avail csbf, section 9.3.3.1.3 */
515             ctxt_idx += (nbr_csbf) ? 1 : 0;
516 
517             /* Ctxt based on luma or chroma */
518             ctxt_idx += c_idx  ? 2 : 0;
519             TRACE_CABAC_CTXT("coded_sub_block_flag", ps_cabac->u4_range, ctxt_idx);
520             IHEVCD_CABAC_DECODE_BIN(cur_csbf, ps_cabac, ps_bitstrm, ctxt_idx);
521             AEV_TRACE("coded_sub_block_flag", cur_csbf, ps_cabac->u4_range);
522 
523             infer_sig_coeff_flag = 1;
524         }
525         else /* if((i == last_sub_blk) || (sub_blk_pos == 0)) */
526         {
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             cur_csbf = 1;
530         }
531 
532         /* Set current sub blocks CSBF */
533         {
534             UWORD32 u4_mask = 1 << xs;
535             if(cur_csbf)
536                 au2_csbf[ys] |= u4_mask;
537             else
538                 au2_csbf[ys] &= ~u4_mask;
539 
540         }
541 
542         /* If current subblock is not coded, proceed to the next subblock */
543         if(0 == cur_csbf)
544             continue;
545 
546         n = 15;
547         u4_sig_coeff_map_raster = 0;
548         u4_sig_coeff_map = 0;
549         num_coeff = 0;
550         if(i == last_sub_blk)
551         {
552             WORD32 pos = ((last_significant_coeff_y & 3) << 2) +
553                             (last_significant_coeff_x & 3);
554             n = (last_scan_pos - 1);
555             /* Set Significant coeff map for last significant coeff flag as 1 */
556             u4_sig_coeff_map_raster = 1 << pos;
557             u4_sig_coeff_map = 1 << last_scan_pos;
558             num_coeff = 1;
559         }
560 
561         for(; n >= 0; n--)
562         {
563             WORD32 significant_coeff_flag;
564 
565             if((n > 0 || !infer_sig_coeff_flag))
566             {
567                 //WORD32 coeff_pos;
568                 WORD32 sig_ctxinc;
569                 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                 sig_ctxinc = 0;
575                 if(2 == log2_trafo_size)
576                 {
577 
578                     /* 4x4 transform size increment uses lookup */
579                     sig_ctxinc = gau1_ihevcd_sigcoeff_ctxtinc_tr4[scan_idx][n];
580                 }
581                 else if(n || i)
582                 {
583                     /* ctxt for AC coeff depends on curpos and neigbour csbf */
584                     sig_ctxinc = gau1_ihevcd_sigcoeff_ctxtinc[scan_idx][nbr_csbf][n];
585 
586                     /* based on luma subblock pos */
587                     sig_ctxinc += (i && (!c_idx)) ? 3 : 0;
588 
589                 }
590                 else
591                 {
592                     /* DC coeff has fixed context for luma and chroma */
593                     sig_coeff_base_ctxt = (0 == c_idx) ? IHEVC_CAB_COEFF_FLAG :
594                                                          (IHEVC_CAB_COEFF_FLAG + 27);
595                 }
596 
597                 ctxt_idx = sig_ctxinc + sig_coeff_base_ctxt;
598                 TRACE_CABAC_CTXT("significant_coeff_flag", ps_cabac->u4_range, ctxt_idx);
599                 IHEVCD_CABAC_DECODE_BIN(significant_coeff_flag, ps_cabac,
600                                         ps_bitstrm,
601                                         ctxt_idx);
602                 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                 if(significant_coeff_flag)
608                     infer_sig_coeff_flag = 0;
609 
610 //                u4_sig_coeff_map_raster |= significant_coeff_flag
611 //                              << coeff_pos;
612                 u4_sig_coeff_map |= significant_coeff_flag << n;
613                 num_coeff += significant_coeff_flag;
614             }
615 
616 
617         }
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         if(infer_sig_coeff_flag)
624         {
625             u4_sig_coeff_map_raster |= 1;
626             u4_sig_coeff_map |= 1;
627             num_coeff++;
628         }
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         if(0 == num_coeff)
638             continue;
639 
640         /* Increment number of coded subblocks for the current TU */
641         num_subblks++;
642 
643         /* Set sig coeff map and subblock position */
644         ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)ps_codec->s_parse.pv_tu_coeff_data;
645         ps_tu_sblk_coeff_data->u2_sig_coeff_map = u4_sig_coeff_map;
646         ps_tu_sblk_coeff_data->u2_subblk_pos = (ys << 8) | xs;
647 
648         first_sig_scan_pos = 16;
649         last_sig_scan_pos = -1;
650         num_greater1_flag = 0;
651         first_greater1_scan_pos = -1;
652         u4_coeff_abs_level_greater1_map = 0;
653 
654 
655         /* context set based on luma subblock pos */
656         ctxt_set = (i && (!c_idx)) ? 2 : 0;
657 
658         /* See section 9.3.3.1.5           */
659         ctxt_set += (0 == gt1_ctxt) ? 1 : 0;
660 
661         gt1_ctxt = 1;
662         /* Instead of initializing n to 15, set it to 31-CLZ(sig coeff map) */
663         {
664             UWORD32 u4_sig_coeff_map_shift;
665             UWORD32 clz;
666             clz = CLZ(u4_sig_coeff_map);
667             n = 31 - clz;
668             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             do
671             {
672                 //WORD32 coeff_pos;
673                 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                 if((u4_sig_coeff_map_shift >> 31) & 1)
679                 {
680 
681                     /* abs_level_greater1_flag is sent for only first 8 non-zero levels in a subblock */
682                     if(num_greater1_flag < 8)
683                     {
684                         WORD32 coeff_abs_level_greater1_flag;
685 
686                         ctxt_idx = (ctxt_set * 4) + abs_gt1_base_ctxt + gt1_ctxt;
687 
688                         TRACE_CABAC_CTXT("coeff_abs_level_greater1_flag", ps_cabac->u4_range, ctxt_idx);
689                         IHEVCD_CABAC_DECODE_BIN(coeff_abs_level_greater1_flag, ps_cabac, ps_bitstrm, ctxt_idx);
690                         AEV_TRACE("coeff_abs_level_greater1_flag", coeff_abs_level_greater1_flag, ps_cabac->u4_range);
691 
692                         u4_coeff_abs_level_greater1_map |= coeff_abs_level_greater1_flag << n;
693                         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                         if(coeff_abs_level_greater1_flag)
701                         {
702                             gt1_ctxt = 0;
703                         }
704                         else if(gt1_ctxt && (gt1_ctxt < 3))
705                         {
706                             gt1_ctxt++;
707                         }
708 
709                     }
710                     else
711                         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                 }
719                 u4_sig_coeff_map_shift <<= 1;
720                 n--;
721                 /* If there are zero coeffs, then shift by as many zero coeffs and decrement n */
722                 clz = CLZ(u4_sig_coeff_map_shift);
723                 u4_sig_coeff_map_shift <<= clz;
724                 n -= clz;
725             }while(u4_sig_coeff_map_shift);
726         }
727         /* At this level u4_sig_coeff_map is non-zero i.e. has atleast one non-zero coeff */
728         last_sig_scan_pos = (31 - CLZ(u4_sig_coeff_map));
729         first_sig_scan_pos = CTZ(u4_sig_coeff_map);
730         sign_hidden = (((last_sig_scan_pos - first_sig_scan_pos) > 3) && !ps_codec->s_parse.s_cu.i4_cu_transquant_bypass);
731 
732         u4_coeff_abs_level_greater2_map = 0;
733 
734         if(u4_coeff_abs_level_greater1_map)
735         {
736             /* Check if the first level > 1 is greater than 2 */
737             WORD32 ctxt_idx;
738             first_greater1_scan_pos = (31 - CLZ(u4_coeff_abs_level_greater1_map));
739 
740 
741             ctxt_idx = IHEVC_CAB_COEFABS_GRTR2_FLAG;
742 
743             ctxt_idx += (!c_idx) ? ctxt_set : (ctxt_set + 4);
744             TRACE_CABAC_CTXT("coeff_abs_level_greater2_flag", ps_cabac->u4_range, ctxt_idx);
745             IHEVCD_CABAC_DECODE_BIN(coeff_abs_level_greater2_flag, ps_cabac, ps_bitstrm, ctxt_idx);
746             AEV_TRACE("coeff_abs_level_greater2_flag", coeff_abs_level_greater2_flag, ps_cabac->u4_range);
747             u4_coeff_abs_level_greater2_map = coeff_abs_level_greater2_flag << first_greater1_scan_pos;
748         }
749 
750 
751         u4_coeff_sign_map = 0;
752 
753         /* Parse sign flags */
754         if(!sign_data_hiding_flag || !sign_hidden)
755         {
756             IHEVCD_CABAC_DECODE_BYPASS_BINS(value, ps_cabac, ps_bitstrm, num_coeff);
757             AEV_TRACE("sign_flags", value, ps_cabac->u4_range);
758             u4_coeff_sign_map = value << (32 - num_coeff);
759         }
760         else
761         {
762             IHEVCD_CABAC_DECODE_BYPASS_BINS(value, ps_cabac, ps_bitstrm, (num_coeff - 1));
763             AEV_TRACE("sign_flags", value, ps_cabac->u4_range);
764             u4_coeff_sign_map = value << (32 - (num_coeff - 1));
765         }
766 
767         num_sig_coeff = 0;
768         sum_abs_level = 0;
769         rice_param = 0;
770         {
771             UWORD32 clz;
772             UWORD32 u4_sig_coeff_map_shift;
773             clz = CLZ(u4_sig_coeff_map);
774             n = 31 - clz;
775             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             do
778             {
779 
780                 if((u4_sig_coeff_map_shift >> 31) & 1)
781                 {
782                     WORD32 base_lvl;
783                     WORD32 coeff_abs_level_remaining;
784                     WORD32 level;
785                     base_lvl = 1;
786 
787                     /* Update base_lvl if it is greater than 1 */
788                     if((u4_coeff_abs_level_greater1_map >> n) & 1)
789                         base_lvl++;
790 
791                     /* Update base_lvl if it is greater than 2 */
792                     if((u4_coeff_abs_level_greater2_map >> n) & 1)
793                         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                     coeff_abs_level_remaining = 0;
799                     if(base_lvl == ((num_sig_coeff < 8) ? ((n == first_greater1_scan_pos) ? 3 : 2) : 1))
800                     {
801                         UWORD32 u4_prefix;
802                         WORD32 bin;
803 
804                         u4_prefix = 0;
805 
806                         do
807                         {
808                             IHEVCD_CABAC_DECODE_BYPASS_BIN(bin, ps_cabac, ps_bitstrm);
809                             u4_prefix++;
810 
811                             if((WORD32)u4_prefix == 19 - rice_param)
812                             {
813                                 bin = 1;
814                                 break;
815                             }
816 
817                         }while(bin);
818 
819                         u4_prefix = u4_prefix - 1;
820                         if(u4_prefix < 3)
821                         {
822                             UWORD32 u4_suffix;
823 
824                             coeff_abs_level_remaining = (u4_prefix << rice_param);
825                             if(rice_param)
826                             {
827                                 IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, rice_param);
828 
829                                 coeff_abs_level_remaining |= u4_suffix;
830                             }
831                         }
832                         else
833                         {
834                             UWORD32 u4_suffix;
835                             UWORD32 u4_numbins;
836 
837                             //u4_prefix = CLIP3(u4_prefix, 0, 19 - rice_param);
838 
839                             u4_numbins = (u4_prefix - 3 + rice_param);
840                             coeff_abs_level_remaining = (((1 << (u4_prefix - 3)) + 3 - 1) << rice_param);
841                             if(u4_numbins)
842                             {
843                                 IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, u4_numbins);
844                                 coeff_abs_level_remaining += u4_suffix;
845                             }
846                         }
847 
848 
849                         AEV_TRACE("coeff_abs_level_remaining", coeff_abs_level_remaining, ps_cabac->u4_range);
850                         base_lvl += coeff_abs_level_remaining;
851 
852                     }
853 
854                     /* update the rice param based on coeff level */
855                     if((base_lvl > (3 << rice_param)) && (rice_param < 4))
856                     {
857                         rice_param++;
858                     }
859 
860                     /* Compute absolute level */
861                     level = base_lvl;
862 
863                     /* Update level with the sign */
864                     if((u4_coeff_sign_map >> 31) & 1)
865                         level = -level;
866 
867                     u4_coeff_sign_map <<= 1;
868                     /* Update sign in case sign is hidden */
869                     if(sign_data_hiding_flag && sign_hidden)
870                     {
871                         sum_abs_level += base_lvl;
872 
873                         if(n == first_sig_scan_pos && ((sum_abs_level % 2) == 1))
874                             level = -level;
875                     }
876 
877                     /* Store the resulting level in non-zero level array */
878                     ps_tu_sblk_coeff_data->ai2_level[num_sig_coeff++] = level;
879                     //AEV_TRACE("level", level, 0);
880                 }
881                 u4_sig_coeff_map_shift <<= 1;
882                 n--;
883                 /* If there are zero coeffs, then shift by as many zero coeffs and decrement n */
884                 clz = CLZ(u4_sig_coeff_map_shift);
885                 u4_sig_coeff_map_shift <<= clz;
886                 n -= clz;
887 
888 
889             }while(u4_sig_coeff_map_shift);
890         }
891 
892         /* Increment the pv_tu_sblk_coeff_data */
893         {
894             UWORD8 *pu1_buf = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
895             pu1_buf += sizeof(tu_sblk_coeff_data_t) - SUBBLK_COEFF_CNT * sizeof(WORD16);
896             pu1_buf += num_coeff * sizeof(WORD16);
897             ps_codec->s_parse.pv_tu_coeff_data = pu1_buf;
898 
899         }
900 
901     }
902     /* Set number of coded sub blocks in the current TU */
903     *pi1_num_coded_subblks = num_subblks;
904 
905     return ret;
906 }
907