Coverage Report

Created: 2026-08-31 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_iquant_itrans_recon_ctb.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_iquant_itrans_recon_ctb.c
22
 *
23
 * @brief
24
 *  Contains functions for inverse quantization, inverse transform and recon
25
 *
26
 * @author
27
 *  Ittiam
28
 *
29
 * @par List of Functions:
30
 * - ihevcd_iquant_itrans_recon_ctb()
31
 *
32
 * @remarks
33
 *  None
34
 *
35
 *******************************************************************************
36
 */
37
/*****************************************************************************/
38
/* File Includes                                                             */
39
/*****************************************************************************/
40
#include <stdio.h>
41
#include <stddef.h>
42
#include <stdlib.h>
43
#include <string.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_cabac_tables.h"
54
#include "ihevc_macros.h"
55
#include "ihevc_platform_macros.h"
56
57
#include "ihevcd_defs.h"
58
#include "ihevcd_function_selector.h"
59
#include "ihevcd_structs.h"
60
#include "ihevcd_error.h"
61
#include "ihevcd_bitstream.h"
62
#include "ihevc_common_tables.h"
63
64
/* Intra pred includes */
65
#include "ihevc_intra_pred.h"
66
67
/* Inverse transform common module includes */
68
#include "ihevc_trans_tables.h"
69
#include "ihevc_trans_macros.h"
70
#include "ihevc_itrans_recon.h"
71
#include "ihevc_recon.h"
72
#include "ihevc_chroma_itrans_recon.h"
73
#include "ihevc_chroma_recon.h"
74
75
/* Decoder includes */
76
#include "ihevcd_common_tables.h"
77
#include "ihevcd_iquant_itrans_recon_ctb.h"
78
#include "ihevcd_debug.h"
79
#include "ihevcd_profile.h"
80
#include "ihevcd_statistics.h"
81
#include "ihevcd_itrans_recon_dc.h"
82
83
84
/* Globals */
85
static const WORD32 g_i4_ip_funcs[MAX_NUM_IP_MODES] =
86
  { IP_FUNC_MODE_0, /* Mode 0 */
87
    IP_FUNC_MODE_1, /* Mode 1 */
88
    IP_FUNC_MODE_2, /* Mode 2 */
89
    IP_FUNC_MODE_3TO9, /* Mode 3 */
90
    IP_FUNC_MODE_3TO9, /* Mode 4 */
91
    IP_FUNC_MODE_3TO9, /* Mode 5 */
92
    IP_FUNC_MODE_3TO9, /* Mode 6 */
93
    IP_FUNC_MODE_3TO9, /* Mode 7 */
94
    IP_FUNC_MODE_3TO9, /* Mode 8 */
95
    IP_FUNC_MODE_3TO9, /* Mode 9 */
96
    IP_FUNC_MODE_10, /* Mode 10 */
97
    IP_FUNC_MODE_11TO17, /* Mode 11 */
98
    IP_FUNC_MODE_11TO17, /* Mode 12 */
99
    IP_FUNC_MODE_11TO17, /* Mode 13 */
100
    IP_FUNC_MODE_11TO17, /* Mode 14 */
101
    IP_FUNC_MODE_11TO17, /* Mode 15 */
102
    IP_FUNC_MODE_11TO17, /* Mode 16 */
103
    IP_FUNC_MODE_11TO17, /* Mode 17 */
104
    IP_FUNC_MODE_18_34, /* Mode 18 */
105
    IP_FUNC_MODE_19TO25, /* Mode 19 */
106
    IP_FUNC_MODE_19TO25, /* Mode 20 */
107
    IP_FUNC_MODE_19TO25, /* Mode 21 */
108
    IP_FUNC_MODE_19TO25, /* Mode 22 */
109
    IP_FUNC_MODE_19TO25, /* Mode 23 */
110
    IP_FUNC_MODE_19TO25, /* Mode 24 */
111
    IP_FUNC_MODE_19TO25, /* Mode 25 */
112
    IP_FUNC_MODE_26, /* Mode 26 */
113
    IP_FUNC_MODE_27TO33, /* Mode 27 */
114
    IP_FUNC_MODE_27TO33, /* Mode 26 */
115
    IP_FUNC_MODE_27TO33, /* Mode 29 */
116
    IP_FUNC_MODE_27TO33, /* Mode 30 */
117
    IP_FUNC_MODE_27TO33, /* Mode 31 */
118
    IP_FUNC_MODE_27TO33, /* Mode 32 */
119
    IP_FUNC_MODE_27TO33, /* Mode 33 */
120
    IP_FUNC_MODE_18_34, /* Mode 34 */
121
};
122
123
124
const WORD16 *g_ai2_ihevc_trans_tables[] =
125
  { &g_ai2_ihevc_trans_dst_4[0][0],
126
    &g_ai2_ihevc_trans_4[0][0],
127
    &g_ai2_ihevc_trans_8[0][0],
128
    &g_ai2_ihevc_trans_16[0][0],
129
    &g_ai2_ihevc_trans_32[0][0]
130
};
131
132
133
/*****************************************************************************/
134
/* Structures                                                                */
135
/*****************************************************************************/
136
/**
137
 * Structure to hold fields required for iq it recon construction process
138
 */
139
typedef struct
140
{
141
    /*
142
     * parsed transform coeffs
143
     */
144
    WORD16 *pi2_tu_coeff;
145
146
    /**
147
     * pred buffer
148
     */
149
    UWORD8 *pu1_pred;
150
151
    /**
152
     * recon buffer
153
     */
154
    UWORD8 *pu1_dst;
155
156
    /**
157
     * transform coeffs buffer stride
158
     */
159
    WORD32 tu_coeff_stride;
160
161
    /**
162
     * pred buffer stride
163
     */
164
    WORD32 pred_strd;
165
166
    /**
167
     * recon buffer stride
168
     */
169
    WORD32 dst_strd;
170
171
    /**
172
     * zero cols, zero rows for optimizing itrans process
173
     */
174
    UWORD32 zero_cols;
175
    UWORD32 zero_rows;
176
177
    /**
178
     * dc only? for optimizing itrans process
179
     */
180
    UWORD32 coeff_type;
181
    WORD16 coeff_value;
182
183
    /**
184
     * cbf
185
     */
186
    UWORD8 cbf;
187
188
    /**
189
     * is transform skip
190
     */
191
    UWORD8 transform_skip_flag;
192
193
#ifdef ENABLE_MAIN_REXT_PROFILE
194
    /**
195
     * is explicit rdpcm enabled
196
     */
197
    UWORD8 explicit_rdpcm_flag;
198
199
    /**
200
     * explicit rdpcm dir
201
     */
202
    UWORD8 explicit_rdpcm_dir;
203
#endif
204
205
} tu_plane_iq_it_recon_ctxt_t;
206
207
208
/*****************************************************************************/
209
/* Function Prototypes                                                       */
210
/*****************************************************************************/
211
typedef void (*PF_IQITRECON_PLANE)(process_ctxt_t *ps_proc,
212
                                   tu_t *ps_tu,
213
                                   tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt,
214
                                   WORD32 func_idx,
215
                                   WORD32 log2_trans_size,
216
                                   CHROMA_PLANE_ID_T chroma_plane,
217
                                   WORD8 intra_flag,
218
                                   WORD8 intra_pred_mode);
219
220
/* Returns number of ai2_level read from ps_sblk_coeff */
221
UWORD8* ihevcd_unpack_coeffs(WORD16 *pi2_tu_coeff,
222
                             WORD32 log2_trans_size,
223
                             UWORD8 *pu1_tu_coeff_data,
224
                             WORD16 *pi2_dequant_matrix,
225
                             WORD32 qp_rem,
226
                             WORD32 qp_div,
227
                             TRANSFORM_TYPE e_trans_type,
228
                             WORD32 trans_quant_bypass,
229
                             UWORD32 *pu4_zero_cols,
230
                             UWORD32 *pu4_zero_rows,
231
                             UWORD32 *pu4_coeff_type,
232
                             WORD16 *pi2_coeff_value)
233
0
{
234
    /* Generating coeffs from coeff-map */
235
0
    WORD32 i;
236
0
    WORD16 *pi2_sblk_ptr;
237
0
    WORD32 subblk_pos_x, subblk_pos_y;
238
0
    WORD32 sblk_scan_idx, coeff_raster_idx;
239
0
    WORD32 sblk_non_zero_coeff_idx;
240
0
    tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data;
241
0
    UWORD8 u1_num_coded_sblks, u1_scan_type;
242
0
    UWORD8 *pu1_new_tu_coeff_data;
243
0
    WORD32 trans_size;
244
0
    WORD32 xs, ys;
245
0
    WORD32 trans_skip;
246
0
    WORD16 iquant_out;
247
0
    WORD32 shift_iq;
248
0
    WORD32 bit_depth;
249
250
0
    bit_depth = 8 + 0;
251
0
    shift_iq = bit_depth + log2_trans_size - 5;
252
0
    trans_size = (1 << log2_trans_size);
253
254
    /* First byte points to number of coded blocks */
255
0
    u1_num_coded_sblks = *pu1_tu_coeff_data++;
256
257
    /* Next byte points to scan type */
258
0
    u1_scan_type = *pu1_tu_coeff_data++;
259
    /* 0th bit has trans_skip */
260
0
    trans_skip = u1_scan_type & 1;
261
0
#ifdef ENABLE_MAIN_REXT_PROFILE
262
0
    u1_scan_type = (u1_scan_type & 0xF) >> 1;
263
#else
264
    u1_scan_type >>= 1;
265
#endif
266
267
0
    pi2_sblk_ptr = pi2_tu_coeff;
268
269
    /* Initially all columns are assumed to be zero */
270
0
    *pu4_zero_cols = 0xFFFFFFFF;
271
    /* Initially all rows are assumed to be zero */
272
0
    *pu4_zero_rows = 0xFFFFFFFF;
273
274
0
    ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)(pu1_tu_coeff_data);
275
276
0
    if(trans_skip)
277
0
        memset(pi2_tu_coeff, 0, trans_size * trans_size * sizeof(WORD16));
278
279
0
    STATS_INIT_SBLK_AND_COEFF_POS();
280
281
    /* DC only case */
282
0
    if((e_trans_type != DST_4x4) && (1 == u1_num_coded_sblks)
283
0
                    && (0 == ps_tu_sblk_coeff_data->u2_subblk_pos)
284
0
                    && (1 == ps_tu_sblk_coeff_data->u2_sig_coeff_map))
285
0
    {
286
0
        *pu4_coeff_type = 1;
287
288
0
        if(!trans_quant_bypass)
289
0
        {
290
0
            WORD32 dequant_coeff = (trans_skip && (trans_size > 4)) ? 16 : pi2_dequant_matrix[0];
291
0
            if(4 == trans_size)
292
0
            {
293
0
                IQUANT_4x4(iquant_out,
294
0
                           ps_tu_sblk_coeff_data->ai2_level[0],
295
0
                           dequant_coeff
296
0
                                           * g_ihevc_iquant_scales[qp_rem],
297
0
                           shift_iq, qp_div);
298
0
            }
299
0
            else
300
0
            {
301
0
                IQUANT(iquant_out, ps_tu_sblk_coeff_data->ai2_level[0],
302
0
                       dequant_coeff * g_ihevc_iquant_scales[qp_rem],
303
0
                       shift_iq, qp_div);
304
0
            }
305
0
            if(trans_skip)
306
0
            {
307
0
                WORD32 shift_ts = MAX_TR_DYNAMIC_RANGE - bit_depth - log2_trans_size;
308
0
                if(shift_ts > 0)
309
0
                {
310
0
                    iquant_out = (iquant_out + (1 << (shift_ts - 1))) >> shift_ts;
311
0
                }
312
0
                else if(shift_ts < 0)
313
0
                {
314
0
                    iquant_out = iquant_out << (-shift_ts);
315
0
                }
316
0
            }
317
0
        }
318
0
        else
319
0
        {
320
            /* setting the column to zero */
321
0
            for(i = 0; i < trans_size; i++)
322
0
                *(pi2_tu_coeff + i * trans_size) = 0;
323
324
0
            iquant_out = ps_tu_sblk_coeff_data->ai2_level[0];
325
0
        }
326
0
        *pi2_coeff_value = iquant_out;
327
0
        *pi2_tu_coeff = iquant_out;
328
0
        *pu4_zero_cols &= ~0x1;
329
0
        *pu4_zero_rows &= ~0x1;
330
0
        ps_tu_sblk_coeff_data =
331
0
                        (void *)&ps_tu_sblk_coeff_data->ai2_level[1];
332
333
0
        STATS_UPDATE_COEFF_COUNT();
334
0
        STATS_LAST_SBLK_POS_UPDATE(e_trans_type, (trans_skip || trans_quant_bypass),  0, 0);
335
0
        STATS_UPDATE_SBLK_AND_COEFF_HISTOGRAM(e_trans_type, (trans_quant_bypass || trans_skip));
336
0
        return ((UWORD8 *)ps_tu_sblk_coeff_data);
337
0
    }
338
0
    else
339
0
    {
340
0
        *pu4_coeff_type = 0;
341
        /* In case of trans skip, memset has already happened */
342
0
        if(!trans_skip)
343
0
            memset(pi2_tu_coeff, 0, trans_size * trans_size * sizeof(WORD16));
344
0
    }
345
346
0
    for(i = 0; i < u1_num_coded_sblks; i++)
347
0
    {
348
0
        UWORD32 u4_sig_coeff_map;
349
0
        subblk_pos_x = ps_tu_sblk_coeff_data->u2_subblk_pos & 0x00FF;
350
0
        subblk_pos_y = (ps_tu_sblk_coeff_data->u2_subblk_pos & 0xFF00) >> 8;
351
352
0
        STATS_LAST_SBLK_POS_UPDATE(e_trans_type, (trans_skip || trans_quant_bypass), subblk_pos_x, subblk_pos_y);
353
354
0
        subblk_pos_x = subblk_pos_x * MIN_TU_SIZE;
355
0
        subblk_pos_y = subblk_pos_y * MIN_TU_SIZE;
356
357
0
        pi2_sblk_ptr = pi2_tu_coeff + subblk_pos_y * trans_size
358
0
                        + subblk_pos_x;
359
360
        //*pu4_zero_cols &= ~(0xF << subblk_pos_x);
361
362
0
        sblk_non_zero_coeff_idx = 0;
363
0
        u4_sig_coeff_map = ps_tu_sblk_coeff_data->u2_sig_coeff_map;
364
        //for(sblk_scan_idx = (31 - CLZ(u4_sig_coeff_map)); sblk_scan_idx >= 0; sblk_scan_idx--)
365
0
        sblk_scan_idx = 31;
366
0
        do
367
0
        {
368
0
            WORD32 clz = CLZ(u4_sig_coeff_map);
369
370
0
            sblk_scan_idx -= clz;
371
            /* when clz is 31, u4_sig_coeff_map << (clz+1) might result in unknown behaviour in some cases */
372
            /* Hence either use SHL which takes care of handling these issues based on platform or shift in two stages */
373
0
            u4_sig_coeff_map = u4_sig_coeff_map << clz;
374
            /* Copying coeffs and storing in reverse order */
375
0
            {
376
0
                STATS_UPDATE_COEFF_COUNT();
377
0
                coeff_raster_idx =
378
0
                                gau1_ihevc_invscan4x4[u1_scan_type][sblk_scan_idx];
379
380
0
                xs = coeff_raster_idx & 0x3;
381
0
                ys = coeff_raster_idx >> 2;
382
383
0
                if(!trans_quant_bypass)
384
0
                {
385
0
                    WORD32 dequant_coeff = (trans_skip && (trans_size > 4)) ? 16 : pi2_dequant_matrix[(subblk_pos_x + xs) + (subblk_pos_y + ys) * trans_size];
386
0
                    if(4 == trans_size)
387
0
                    {
388
0
                        IQUANT_4x4(iquant_out,
389
0
                                   ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx],
390
0
                                   dequant_coeff
391
0
                                   * g_ihevc_iquant_scales[qp_rem],
392
0
                                   shift_iq, qp_div);
393
0
                        sblk_non_zero_coeff_idx++;
394
0
                    }
395
0
                    else
396
0
                    {
397
0
                        IQUANT(iquant_out,
398
0
                               ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx],
399
0
                               dequant_coeff * g_ihevc_iquant_scales[qp_rem],
400
0
                               shift_iq, qp_div);
401
0
                        sblk_non_zero_coeff_idx++;
402
0
                    }
403
404
0
                    if(trans_skip)
405
0
                    {
406
0
                        WORD32 shift_ts = MAX_TR_DYNAMIC_RANGE - bit_depth - log2_trans_size;
407
0
                        if(shift_ts > 0)
408
0
                        {
409
0
                            iquant_out = (iquant_out + (1 << (shift_ts - 1))) >> shift_ts;
410
0
                        }
411
0
                        else if(shift_ts < 0)
412
0
                        {
413
0
                            iquant_out = iquant_out << (-shift_ts);
414
0
                        }
415
0
                    }
416
0
                }
417
0
                else
418
0
                {
419
0
                    iquant_out = ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx++];
420
0
                }
421
0
                *pu4_zero_cols &= ~(0x1U << (subblk_pos_x + xs));
422
0
                *pu4_zero_rows &= ~(0x1U << (subblk_pos_y + ys));
423
0
                *(pi2_sblk_ptr + xs + ys * trans_size) = iquant_out;
424
0
            }
425
0
            sblk_scan_idx--;
426
0
            u4_sig_coeff_map <<= 1;
427
428
0
        }while(u4_sig_coeff_map);
429
        /* Updating the sblk pointer */
430
0
        ps_tu_sblk_coeff_data =
431
0
                        (void *)&ps_tu_sblk_coeff_data->ai2_level[sblk_non_zero_coeff_idx];
432
0
    }
433
434
0
    STATS_UPDATE_SBLK_AND_COEFF_HISTOGRAM(e_trans_type, (trans_quant_bypass || trans_skip));
435
436
0
    pu1_new_tu_coeff_data = (UWORD8 *)ps_tu_sblk_coeff_data;
437
438
0
    return pu1_new_tu_coeff_data;
439
0
}
440
441
WORD32 ihevcd_get_intra_nbr_flag(process_ctxt_t *ps_proc,
442
                                 tu_t *ps_tu,
443
                                 UWORD32 *pu4_intra_nbr_avail,
444
                                 WORD16 i2_pic_width_in_luma_samples,
445
                                 UWORD8 i1_constrained_intra_pred_flag,
446
                                 WORD32 trans_size,
447
                                 WORD32 ctb_size)
448
0
{
449
0
    sps_t *ps_sps;
450
0
    UWORD8 u1_bot_lt_avail, u1_left_avail, u1_top_avail, u1_top_rt_avail,
451
0
                    u1_top_lt_avail;
452
0
    WORD32 x_cur, y_cur, x_nbr, y_nbr;
453
0
    UWORD8 *pu1_nbr_intra_flag;
454
0
    UWORD8 *pu1_pic_intra_flag;
455
0
    UWORD8 top_right, top, top_left, left, bot_left;
456
0
    WORD32 intra_pos;
457
0
    WORD32 num_8_blks, num_8_blks_in_bits;
458
0
    WORD32 numbytes_row = (i2_pic_width_in_luma_samples + 63) / 64;
459
0
    WORD32 cur_x, cur_y;
460
0
    WORD32 i;
461
0
    WORD32 nbr_flags;
462
463
0
    ps_sps = ps_proc->ps_sps;
464
0
    cur_x = ps_tu->b4_pos_x;
465
0
    cur_y = ps_tu->b4_pos_y;
466
467
0
    u1_bot_lt_avail = (pu4_intra_nbr_avail[1 + cur_y + trans_size / MIN_TU_SIZE]
468
0
                    >> (31 - (1 + cur_x - 1))) & 1;
469
0
    u1_left_avail = (pu4_intra_nbr_avail[1 + cur_y] >> (31 - (1 + cur_x - 1)))
470
0
                    & 1;
471
0
    u1_top_avail = (pu4_intra_nbr_avail[1 + cur_y - 1] >> (31 - (1 + cur_x)))
472
0
                    & 1;
473
0
    u1_top_rt_avail = (pu4_intra_nbr_avail[1 + cur_y - 1]
474
0
                    >> (31 - (1 + cur_x + trans_size / MIN_TU_SIZE))) & 1;
475
0
    u1_top_lt_avail = (pu4_intra_nbr_avail[1 + cur_y - 1]
476
0
                    >> (31 - (1 + cur_x - 1))) & 1;
477
478
0
    x_cur = ps_proc->i4_ctb_x * ctb_size + cur_x * MIN_TU_SIZE;
479
0
    y_cur = ps_proc->i4_ctb_y * ctb_size + cur_y * MIN_TU_SIZE;
480
481
0
    pu1_pic_intra_flag = ps_proc->pu1_pic_intra_flag;
482
483
    /* WORD32 nbr_flags as below  MSB --> LSB */
484
    /*    Top-Left | Top-Right | Top | Left | Bottom-Left
485
     *       1         4         4     4         4
486
     */
487
0
    bot_left = 0;
488
0
    left = 0;
489
0
    top_right = 0;
490
0
    top = 0;
491
0
    top_left = 0;
492
493
0
    num_8_blks = trans_size > 4 ? trans_size / 8 : 1;
494
0
    num_8_blks_in_bits = ((1 << num_8_blks) - 1);
495
496
0
    if(i1_constrained_intra_pred_flag)
497
0
    {
498
        /* TODO: constrained intra pred not tested */
499
0
        if(u1_bot_lt_avail)
500
0
        {
501
0
            x_nbr = x_cur - 1;
502
0
            y_nbr = y_cur + trans_size;
503
504
0
            pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row
505
0
                            + x_nbr / 64;
506
0
            intra_pos = ((x_nbr / 8) % 8);
507
0
            for(i = 0; i < num_8_blks; i++)
508
0
            {
509
0
                bot_left |= ((*(pu1_nbr_intra_flag + i * numbytes_row)
510
0
                                >> intra_pos) & 1) << i;
511
0
            }
512
0
            bot_left &= num_8_blks_in_bits;
513
0
        }
514
0
        if(u1_left_avail)
515
0
        {
516
0
            x_nbr = x_cur - 1;
517
0
            y_nbr = y_cur;
518
519
0
            pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row
520
0
                            + x_nbr / 64;
521
0
            intra_pos = ((x_nbr / 8) % 8);
522
523
0
            for(i = 0; i < num_8_blks; i++)
524
0
            {
525
0
                left |= ((*(pu1_nbr_intra_flag + i * numbytes_row) >> intra_pos)
526
0
                                & 1) << i;
527
0
            }
528
0
            left &= num_8_blks_in_bits;
529
0
        }
530
0
        if(u1_top_avail)
531
0
        {
532
0
            x_nbr = x_cur;
533
0
            y_nbr = y_cur - 1;
534
535
0
            pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row
536
0
                            + x_nbr / 64;
537
0
            intra_pos = ((x_nbr / 8) % 8);
538
539
0
            top = (*pu1_nbr_intra_flag >> intra_pos);
540
0
            top &= num_8_blks_in_bits;
541
            /*
542
             for(i=0;i<num_8_blks;i++)
543
             {
544
             top |= ( (*pu1_nbr_intra_flag >> (intra_pos+i)) & 1) << i;
545
             }
546
             */
547
0
        }
548
0
        if(u1_top_rt_avail)
549
0
        {
550
0
            x_nbr = x_cur + trans_size;
551
0
            y_nbr = y_cur - 1;
552
553
0
            pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row
554
0
                            + x_nbr / 64;
555
0
            intra_pos = ((x_nbr / 8) % 8);
556
557
0
            top_right = (*pu1_nbr_intra_flag >> intra_pos);
558
0
            top_right &= num_8_blks_in_bits;
559
            /*
560
             for(i=0;i<num_8_blks;i++)
561
             {
562
             top_right |= ( (*pu1_nbr_intra_flag >> (intra_pos+i)) & 1) << i;
563
             }
564
             */
565
0
        }
566
0
        if(u1_top_lt_avail)
567
0
        {
568
0
            x_nbr = x_cur - 1;
569
0
            y_nbr = y_cur - 1;
570
571
0
            pu1_nbr_intra_flag = pu1_pic_intra_flag + y_nbr / 8 * numbytes_row
572
0
                            + x_nbr / 64;
573
0
            intra_pos = ((x_nbr / 8) % 8);
574
575
0
            top_left = (*pu1_nbr_intra_flag >> intra_pos) & 1;
576
0
        }
577
0
    }
578
0
    else
579
0
    {
580
0
        if(u1_top_avail)
581
0
            top = 0xF;
582
0
        if(u1_top_rt_avail)
583
0
            top_right = 0xF;
584
0
        if(u1_bot_lt_avail)
585
0
            bot_left = 0xF;
586
0
        if(u1_left_avail)
587
0
            left = 0xF;
588
0
        if(u1_top_lt_avail)
589
0
            top_left = 0x1;
590
0
    }
591
592
    /* Handling incomplete CTBs */
593
0
    {
594
0
        WORD32 pu_size_limit = MIN(trans_size, 8);
595
0
        WORD32 cols_remaining = ps_sps->i2_pic_width_in_luma_samples
596
0
                        - (ps_proc->i4_ctb_x << ps_sps->i1_log2_ctb_size)
597
0
                        - (ps_tu->b4_pos_x * MIN_TU_SIZE)
598
0
                        - (1 << (ps_tu->b3_size + 2));
599
        /* ctb_size_top gives number of valid pixels remaining in the current row */
600
0
        WORD32 ctb_size_top = MIN(ctb_size, cols_remaining);
601
0
        WORD32 ctb_size_top_bits = (1 << (ctb_size_top / pu_size_limit)) - 1;
602
603
0
        WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples
604
0
                        - (ps_proc->i4_ctb_y << ps_sps->i1_log2_ctb_size)
605
0
                        - (ps_tu->b4_pos_y * MIN_TU_SIZE)
606
0
                        - (1 << (ps_tu->b3_size + 2));
607
        /* ctb_size_bot gives number of valid pixels remaining in the current column */
608
0
        WORD32 ctb_size_bot = MIN(ctb_size, rows_remaining);
609
0
        WORD32 ctb_size_bot_bits = (1 << (ctb_size_bot / pu_size_limit)) - 1;
610
611
0
        top_right &= ctb_size_top_bits;
612
0
        bot_left &= ctb_size_bot_bits;
613
0
    }
614
615
    /*    Top-Left | Top-Right | Top | Left | Bottom-Left
616
     *      1         4         4     4         4
617
     */
618
619
    /*
620
     nbr_flags = (top_left << 16) | (gau4_ihevcd_4_bit_reverse[top_right] << 12) | (gau4_ihevcd_4_bit_reverse[top] << 8) | (gau4_ihevcd_4_bit_reverse[left] << 4)
621
     | gau4_ihevcd_4_bit_reverse[bot_left];
622
     */
623
0
    nbr_flags = (top_left << 16) | (top_right << 12) | (top << 8) | (gau4_ihevcd_4_bit_reverse[left] << 4)
624
0
                    | gau4_ihevcd_4_bit_reverse[bot_left];
625
626
627
0
    return nbr_flags;
628
629
0
}
630
631
static void ihevcd_iquant_itrans_recon_tu_plane(process_ctxt_t *ps_proc,
632
                                                tu_t *ps_tu,
633
                                                tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt,
634
                                                WORD32 func_idx,
635
                                                WORD32 log2_trans_size,
636
                                                CHROMA_PLANE_ID_T chroma_plane,
637
                                                WORD8 intra_flag,
638
                                                WORD8 intra_pred_mode)
639
0
{
640
0
    sps_t *ps_sps = ps_proc->ps_sps;
641
0
    pps_t *ps_pps = ps_proc->ps_pps;
642
0
    codec_t *ps_codec = ps_proc->ps_codec;
643
644
0
    if(1 == ps_pl_tu_ctxt->cbf)
645
0
    {
646
0
        if(ps_tu->b1_transquant_bypass || ps_pl_tu_ctxt->transform_skip_flag)
647
0
        {
648
            /* Recon */
649
0
            ps_codec->apf_recon[func_idx](ps_pl_tu_ctxt->pi2_tu_coeff, ps_pl_tu_ctxt->pu1_pred,
650
0
                                          ps_pl_tu_ctxt->pu1_dst, ps_pl_tu_ctxt->tu_coeff_stride,
651
0
                                          ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd,
652
0
                                          ps_pl_tu_ctxt->zero_cols);
653
0
        }
654
0
        else
655
0
        {
656
            /* iQuant , iTrans and Recon */
657
0
            if((0 == ps_pl_tu_ctxt->coeff_type))
658
0
            {
659
0
                ps_codec->apf_itrans_recon[func_idx](ps_pl_tu_ctxt->pi2_tu_coeff,
660
0
                                                     ps_proc->pi2_itrans_intrmd_buf,
661
0
                                                     ps_pl_tu_ctxt->pu1_pred,
662
0
                                                     ps_pl_tu_ctxt->pu1_dst,
663
0
                                                     ps_pl_tu_ctxt->tu_coeff_stride,
664
0
                                                     ps_pl_tu_ctxt->pred_strd,
665
0
                                                     ps_pl_tu_ctxt->dst_strd,
666
0
                                                     ps_pl_tu_ctxt->zero_cols,
667
0
                                                     ps_pl_tu_ctxt->zero_rows);
668
0
            }
669
0
            else /* DC only */
670
0
            {
671
0
                ps_codec->apf_itrans_recon_dc[chroma_plane != NULL_PLANE](
672
0
                                ps_pl_tu_ctxt->pu1_pred, ps_pl_tu_ctxt->pu1_dst,
673
0
                                ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd, log2_trans_size,
674
0
                                ps_pl_tu_ctxt->coeff_value);
675
0
            }
676
0
        }
677
0
    }
678
0
}
679
680
#ifdef ENABLE_MAIN_REXT_PROFILE
681
static void ihevcd_iquant_itrans_resi_recon_tu_plane(process_ctxt_t *ps_proc,
682
                                                     tu_t *ps_tu,
683
                                                     tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt,
684
                                                     WORD32 func_idx,
685
                                                     WORD32 log2_trans_size,
686
                                                     CHROMA_PLANE_ID_T chroma_plane,
687
                                                     WORD8 intra_flag,
688
                                                     WORD8 intra_pred_mode)
689
0
{
690
0
    sps_t *ps_sps = ps_proc->ps_sps;
691
0
    pps_t *ps_pps = ps_proc->ps_pps;
692
0
    codec_t *ps_codec = ps_proc->ps_codec;
693
0
    WORD8 trans_size = 1 << log2_trans_size;
694
0
    WORD16 *pi2_res = ps_proc->pi2_res_luma_buf;
695
0
    WORD16 *pi2_res_uv = ps_proc->pi2_res_chroma_buf;
696
0
    WORD32 alpha = 0;
697
0
    WORD16 *residue_out_base = chroma_plane == NULL_PLANE ? pi2_res : pi2_res_uv;
698
0
    WORD16 *residue_out = residue_out_base;
699
    // if both rdpcm and rotate are to be applied, share the output residue buffer between the
700
    // two transforms
701
0
    WORD16 *residue_out_intrmdt = residue_out_base + (TRANS_SIZE_4 * TRANS_SIZE_4);
702
703
0
    if(chroma_plane == U_PLANE && ps_tu->b3_cb_log2_res_scale_abs_plus1 != 0)
704
0
    {
705
0
        alpha = (1 << (ps_tu->b3_cb_log2_res_scale_abs_plus1 - 1))
706
0
                        * (1 - 2 * ps_tu->b1_cb_log2_res_sign);
707
0
    }
708
0
    else if(chroma_plane == V_PLANE && ps_tu->b3_cr_log2_res_scale_abs_plus1 != 0)
709
0
    {
710
0
        alpha = (1 << (ps_tu->b3_cr_log2_res_scale_abs_plus1 - 1))
711
0
                        * (1 - 2 * ps_tu->b1_cr_log2_res_sign);
712
0
    }
713
0
    if(1 == ps_pl_tu_ctxt->cbf)
714
0
    {
715
0
        if(ps_tu->b1_transquant_bypass || ps_pl_tu_ctxt->transform_skip_flag)
716
0
        {
717
0
            WORD8 rotate = ps_sps->i1_transform_skip_rotation_enabled_flag && trans_size == 4
718
0
                            && intra_flag;
719
0
            WORD8 rdpcm = (ps_sps->i1_implicit_rdpcm_enabled_flag && intra_flag
720
0
                            && (intra_pred_mode == 10 || intra_pred_mode == 26))
721
0
                            || ps_pl_tu_ctxt->explicit_rdpcm_flag;
722
0
            WORD16 *src_residue = ps_pl_tu_ctxt->pi2_tu_coeff;
723
0
            WORD16 src_residue_strd = ps_pl_tu_ctxt->tu_coeff_stride;
724
725
0
            if(rotate)
726
0
            {
727
0
                ihevc_res_4x4_rotate(src_residue, rdpcm ? residue_out_intrmdt : residue_out,
728
0
                                     src_residue_strd, trans_size, ps_pl_tu_ctxt->zero_cols);
729
0
                ps_pl_tu_ctxt->zero_cols =
730
0
                                gau4_ihevcd_4_bit_reverse[ps_pl_tu_ctxt->zero_cols & 0xF];
731
0
                src_residue = residue_out_intrmdt;
732
0
                src_residue_strd = trans_size;
733
0
            }
734
735
0
            if(rdpcm)
736
0
            {
737
0
                WORD8 rdpcm_dir =
738
0
                                ps_pl_tu_ctxt->explicit_rdpcm_flag ?
739
0
                                                ps_pl_tu_ctxt->explicit_rdpcm_dir :
740
0
                                                intra_pred_mode != 10;
741
0
                if(rdpcm_dir == 0)
742
0
                {
743
0
                    ihevc_res_nxn_rdpcm_horz(src_residue, residue_out, src_residue_strd, trans_size,
744
0
                                             trans_size, ps_pl_tu_ctxt->zero_cols);
745
0
                    ps_pl_tu_ctxt->zero_cols = (1 << CTZ(~ps_pl_tu_ctxt->zero_cols)) - 1;
746
0
                }
747
0
                else
748
0
                {
749
0
                    ihevc_res_nxn_rdpcm_vert(src_residue, residue_out, src_residue_strd, trans_size,
750
0
                                             trans_size, ps_pl_tu_ctxt->zero_cols);
751
0
                }
752
0
            }
753
754
0
            if(!rdpcm && !rotate)
755
0
            {
756
0
                ihevc_res_nxn_copy(src_residue, residue_out, src_residue_strd, trans_size,
757
0
                                   trans_size, ps_pl_tu_ctxt->zero_cols);
758
0
            }
759
0
        }
760
0
        else
761
0
        {
762
            /* iQuant, iTrans */
763
0
            if(0 == ps_pl_tu_ctxt->coeff_type)
764
0
            {
765
0
                WORD32 func_tmp_idx = chroma_plane != NULL_PLANE ? func_idx - 4 : func_idx;
766
0
                ps_codec->apf_itrans_res[func_tmp_idx](ps_pl_tu_ctxt->pi2_tu_coeff,
767
0
                                                       ps_proc->pi2_itrans_intrmd_buf, residue_out,
768
0
                                                       ps_pl_tu_ctxt->tu_coeff_stride, trans_size,
769
0
                                                       ps_pl_tu_ctxt->zero_cols,
770
0
                                                       ps_pl_tu_ctxt->zero_rows);
771
0
            }
772
0
            else /* DC only */
773
0
            {
774
0
                ps_codec->apf_itrans_res_dc(residue_out, trans_size, log2_trans_size,
775
0
                                            ps_pl_tu_ctxt->coeff_value);
776
0
            }
777
0
            ps_pl_tu_ctxt->zero_cols = 0;
778
0
        }
779
0
        if(!alpha)
780
0
        {
781
0
            ps_codec->apf_recon[func_idx](residue_out, ps_pl_tu_ctxt->pu1_pred,
782
0
                                          ps_pl_tu_ctxt->pu1_dst, trans_size,
783
0
                                          ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd,
784
0
                                          ps_pl_tu_ctxt->zero_cols);
785
0
        }
786
0
    }
787
0
    if(alpha)
788
0
    {
789
0
        if(0 == ps_pl_tu_ctxt->cbf)
790
0
        {
791
0
            memset(residue_out, 0, trans_size * trans_size * sizeof(WORD16));
792
0
        }
793
0
        ihevc_chroma_recon_nxn_ccp(pi2_res, pi2_res_uv, ps_pl_tu_ctxt->pu1_pred,
794
0
                                   ps_pl_tu_ctxt->pu1_dst, alpha, trans_size, trans_size,
795
0
                                   trans_size, ps_pl_tu_ctxt->pred_strd, ps_pl_tu_ctxt->dst_strd);
796
0
    }
797
0
}
798
799
PF_IQITRECON_PLANE get_iqitrec_func(process_ctxt_t *ps_proc,
800
                                    tu_t *ps_tu,
801
                                    tu_plane_iq_it_recon_ctxt_t *ps_pl_tu_ctxt,
802
                                    WORD32 log2_trans_size,
803
                                    CHROMA_PLANE_ID_T chroma_plane,
804
                                    WORD8 intra_flag,
805
                                    WORD8 intra_pred_mode)
806
0
{
807
0
    sps_t *ps_sps = ps_proc->ps_sps;
808
0
    pps_t *ps_pps = ps_proc->ps_pps;
809
0
    WORD8 trans_size = 1 << log2_trans_size;
810
811
0
    if(1 == ps_pl_tu_ctxt->cbf
812
0
                    && (ps_tu->b1_transquant_bypass || ps_pl_tu_ctxt->transform_skip_flag))
813
0
    {
814
0
        if(ps_sps->i1_transform_skip_rotation_enabled_flag && trans_size == 4 && intra_flag)
815
0
            return ihevcd_iquant_itrans_resi_recon_tu_plane;
816
0
        if(ps_sps->i1_implicit_rdpcm_enabled_flag && intra_flag
817
0
                        && (intra_pred_mode == 10 || intra_pred_mode == 26))
818
0
            return ihevcd_iquant_itrans_resi_recon_tu_plane;
819
0
        if(ps_pl_tu_ctxt->explicit_rdpcm_flag)
820
0
            return ihevcd_iquant_itrans_resi_recon_tu_plane;
821
0
    }
822
0
    if(ps_pps->i1_cross_component_prediction_enabled_flag)
823
0
    {
824
0
        if((chroma_plane == NULL_PLANE
825
0
                        && (ps_tu->b3_cb_log2_res_scale_abs_plus1 != 0
826
0
                                        || ps_tu->b3_cr_log2_res_scale_abs_plus1 != 0))
827
0
                        || (chroma_plane == V_PLANE && ps_tu->b3_cr_log2_res_scale_abs_plus1 != 0)
828
0
                        || (chroma_plane == U_PLANE && ps_tu->b3_cb_log2_res_scale_abs_plus1 != 0))
829
0
            return ihevcd_iquant_itrans_resi_recon_tu_plane;
830
0
    }
831
0
    return ihevcd_iquant_itrans_recon_tu_plane;
832
0
}
833
#endif
834
835
WORD32 ihevcd_iquant_itrans_recon_ctb(process_ctxt_t *ps_proc)
836
0
{
837
0
    WORD16 *pi2_scaling_mat;
838
0
    UWORD8 *pu1_y_dst_ctb;
839
0
    UWORD8 *pu1_uv_dst_ctb;
840
0
    WORD32 ctb_size;
841
0
    codec_t *ps_codec;
842
0
    slice_header_t *ps_slice_hdr;
843
0
    tu_t *ps_tu;
844
0
    WORD16 *pi2_ctb_coeff;
845
0
    WORD32 tu_cnt;
846
0
    WORD16 *pi2_tu_coeff;
847
0
    WORD32 pic_strd;
848
0
    WORD32 luma_nbr_flags;
849
0
    WORD32 luma_nbr_flags_4x4[4] = { 0 };
850
0
    WORD32 chroma_nbr_flags = 0;
851
0
    WORD32 chroma_nbr_flags_subtu = 0;
852
0
    WORD32 disable_boundary_filter = 0;
853
854
0
    UWORD8 u1_luma_pred_mode_first_tu = 0;
855
    /* Pointers for generating 2d coeffs from coeff-map */
856
0
    UWORD8 *pu1_tu_coeff_data;
857
    /* nbr avail map for CTB */
858
    /* 1st bit points to neighbor (left/top_left/bot_left) */
859
    /* 1Tb starts at 2nd bit from msb of 2nd value in array, followed by number of min_tu's in that ctb */
860
0
    UWORD32 au4_intra_nbr_avail[MAX_CTB_SIZE / MIN_TU_SIZE + 2 /* Top nbr + bot nbr */];
861
0
    UWORD32 top_avail_bits;
862
0
    sps_t *ps_sps;
863
0
    pps_t *ps_pps;
864
0
    WORD32 intra_flag;
865
0
    UWORD8 *pu1_pic_intra_flag;
866
0
    WORD32 h_samp_factor, v_samp_factor;
867
0
    WORD32 chroma_pixel_strd = 2;
868
0
    PF_IQITRECON_PLANE iqitrecon_fptr = ihevcd_iquant_itrans_recon_tu_plane;
869
870
    /*************************************************************************/
871
    /* Contanis scaling matrix offset in the following order in a 1D buffer  */
872
    /* Entries that are listed as UNUSED are invalid combinations where      */
873
    /* scaling matrix is not used. eg: 64x64 SKIP CU, 64x64 PCM CU           */
874
    /* Intra 4 x 4 Y, 4 x 4 U, 4 x 4 V                                       */
875
    /* Inter 4 x 4 Y, 4 x 4 U, 4 x 4 V                                       */
876
    /* Intra 8 x 8 Y, 8 x 8 U, 8 x 8 V                                       */
877
    /* Inter 8 x 8 Y, 8 x 8 U, 8 x 8 V                                       */
878
    /* Intra 16x16 Y, 16x16 U, 16x16 V                                       */
879
    /* Inter 16x16 Y, 16x16 U, 16x16 V                                       */
880
    /* Intra 32x32 Y, 32x32 U, 32x32 V                                       */
881
    /* Inter 32x32 Y, 32x32 U, 32x32 V                                       */
882
    /* UNUSED,        UNUSED,  UNUSED                                        */
883
    /* UNUSED,        UNUSED,  UNUSED                                        */
884
    /*************************************************************************/
885
0
    static const WORD32 scaling_mat_offset[] =
886
0
      { 0, 16, 32, 48, 64, 80, 96, 160, 224, 288, 352, 416, 480, 736, 992,
887
0
        1248, 1504, 1760, 2016, 3040, 4064, 5088, 6112, 7136, 0, 0, 0, 0, 0, 0};
888
889
0
    PROFILE_DISABLE_IQ_IT_RECON_INTRA_PRED();
890
891
0
    ps_sps = ps_proc->ps_sps;
892
0
    ps_pps = ps_proc->ps_pps;
893
0
    ps_slice_hdr = ps_proc->ps_slice_hdr;
894
0
    ps_codec = ps_proc->ps_codec;
895
896
0
    pu1_y_dst_ctb = ps_proc->pu1_cur_ctb_luma;
897
0
    pu1_uv_dst_ctb = ps_proc->pu1_cur_ctb_chroma;
898
899
0
    pi2_ctb_coeff = ps_proc->pi2_invscan_out;
900
901
0
    ctb_size = (1 << ps_sps->i1_log2_ctb_size);
902
0
    pu1_tu_coeff_data = (UWORD8 *)ps_proc->pv_tu_coeff_data;
903
904
0
    pic_strd = ps_codec->i4_strd;
905
906
0
    pi2_tu_coeff = pi2_ctb_coeff;
907
908
0
    ps_tu = ps_proc->ps_tu;
909
910
0
    if((1 == ps_sps->i1_scaling_list_enable_flag) && (1 == ps_pps->i1_pps_scaling_list_data_present_flag))
911
0
    {
912
0
        pi2_scaling_mat = ps_pps->pi2_scaling_mat;
913
0
    }
914
0
    else
915
0
    {
916
0
        pi2_scaling_mat = ps_sps->pi2_scaling_mat;
917
0
    }
918
919
0
    {
920
        /* Updating the initial availability map */
921
0
        WORD32 i;
922
0
        UWORD8 u1_left_ctb_avail, u1_top_lt_ctb_avail, u1_top_rt_ctb_avail,
923
0
                        u1_top_ctb_avail;
924
925
0
        u1_left_ctb_avail = ps_proc->u1_left_ctb_avail;
926
0
        u1_top_lt_ctb_avail = ps_proc->u1_top_lt_ctb_avail;
927
0
        u1_top_ctb_avail = ps_proc->u1_top_ctb_avail;
928
0
        u1_top_rt_ctb_avail = ps_proc->u1_top_rt_ctb_avail;
929
930
        /* Initializing the availability array */
931
0
        memset(au4_intra_nbr_avail, 0,
932
0
               (MAX_CTB_SIZE / MIN_TU_SIZE + 2) * sizeof(UWORD32));
933
        /* Initializing the availability array with CTB level availability flags */
934
0
        {
935
0
            WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples - (ps_proc->i4_ctb_y << ps_sps->i1_log2_ctb_size);
936
0
            WORD32 ctb_size_left = MIN(ctb_size, rows_remaining);
937
0
            for(i = 0; i < ctb_size_left / MIN_TU_SIZE; i++)
938
0
            {
939
0
                au4_intra_nbr_avail[i + 1] = ((UWORD32)u1_left_ctb_avail << 31);
940
0
            }
941
0
        }
942
0
        au4_intra_nbr_avail[0] |= (((UWORD32)u1_top_rt_ctb_avail << 31)
943
0
                        >> (1 + ctb_size / MIN_TU_SIZE)); /* 1+ctb_size/4 position bit pos from msb */
944
945
0
        au4_intra_nbr_avail[0] |= ((UWORD32)u1_top_lt_ctb_avail << 31);
946
947
0
        {
948
0
            WORD32 cols_remaining = ps_sps->i2_pic_width_in_luma_samples - (ps_proc->i4_ctb_x << ps_sps->i1_log2_ctb_size);
949
0
            WORD32 ctb_size_top = MIN(ctb_size, cols_remaining);
950
0
            WORD32 shift = (31 - (ctb_size / MIN_TU_SIZE));
951
952
            /* ctb_size_top gives number of valid pixels remaining in the current row */
953
            /* Since we need pattern of 1's starting from the MSB, an additional shift */
954
            /* is needed */
955
0
            shift += ((ctb_size - ctb_size_top) / MIN_TU_SIZE);
956
957
0
            top_avail_bits = ((1 << (ctb_size_top / MIN_TU_SIZE)) - 1)
958
0
                            << shift;
959
0
        }
960
0
        au4_intra_nbr_avail[0] |= (
961
0
                        (u1_top_ctb_avail == 1) ? top_avail_bits : 0x0);
962
        /* Starting from msb 2nd bit to (1+ctb_size/4) bit, set 1 if top avail,or 0 */
963
964
0
    }
965
966
0
    h_samp_factor = (CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) ? 1 : 2;
967
0
    v_samp_factor = (CHROMA_FMT_IDC_YUV420 == ps_sps->i1_chroma_format_idc) ? 2 : 1;
968
969
    /* Applying Inverse transform on all the TU's in CTB */
970
0
    for(tu_cnt = 0; tu_cnt < ps_proc->i4_ctb_tu_cnt; tu_cnt++, ps_tu++)
971
0
    {
972
        /* Reset boundary filter flag for each transform unit (TU) iteration */
973
0
        disable_boundary_filter = 0;
974
0
        tu_plane_iq_it_recon_ctxt_t y_cb_tu = { 0 };
975
0
        tu_plane_iq_it_recon_ctxt_t cr_tu = { 0 };
976
0
        tu_plane_iq_it_recon_ctxt_t *ps_cb_tu = &y_cb_tu;
977
0
        tu_plane_iq_it_recon_ctxt_t *ps_cr_tu = &cr_tu;
978
0
#ifdef ENABLE_MAIN_REXT_PROFILE
979
0
        tu_plane_iq_it_recon_ctxt_t cb_sub_tu = { 0 };
980
0
        tu_plane_iq_it_recon_ctxt_t cr_sub_tu = { 0 };
981
0
#endif
982
983
0
        WORD32 num_comp, c_idx, func_idx;
984
985
0
        WORD32 qp_div = 0, qp_rem = 0;
986
0
        WORD32 qp_div_v = 0, qp_rem_v = 0;
987
0
        WORD32 chroma_qp_idx;
988
0
        WORD8 i1_chroma_pic_qp_offset, i1_chroma_slice_qp_offset;
989
0
        WORD16 *pi2_dequant_matrix = NULL, *pi2_dequant_matrix_v = NULL;
990
991
0
        WORD32 trans_size = 0;
992
0
        TRANSFORM_TYPE e_trans_type;
993
0
        WORD32 log2_y_trans_size_minus_2, log2_uv_trans_size_minus_2;
994
0
        WORD32 log2_trans_size;
995
996
0
        WORD32 tu_x, tu_y;
997
0
        WORD32 tu_y_offset, tu_uv_offset;
998
0
        UWORD8 u1_luma_pred_mode, u1_chroma_pred_mode;
999
0
        WORD32 offset;
1000
0
        WORD32 pcm_flag;
1001
0
        WORD32 chroma_yuv420sp_vu = (ps_codec->e_ref_chroma_fmt == IV_YUV_420SP_VU);
1002
        /* If 420SP_VU is chroma format, pred and dst pointer   */
1003
        /* will be added +1 to point to U                       */
1004
0
        WORD32 chroma_yuv420sp_vu_u_offset = 1 * chroma_yuv420sp_vu;
1005
        /* If 420SP_VU is chroma format, pred and dst pointer   */
1006
        /* will be added U offset of +1 and subtracted 2        */
1007
        /* to point to V                                        */
1008
0
        WORD32 chroma_yuv420sp_vu_v_offset = -2 * chroma_yuv420sp_vu;
1009
1010
0
        tu_x = ps_tu->b4_pos_x * 4; /* Converting minTU unit to pixel unit */
1011
0
        tu_y = ps_tu->b4_pos_y * 4; /* Converting minTU unit to pixel unit */
1012
0
        {
1013
0
            WORD32 tu_abs_x = (ps_proc->i4_ctb_x << ps_sps->i1_log2_ctb_size) + (tu_x);
1014
0
            WORD32 tu_abs_y = (ps_proc->i4_ctb_y << ps_sps->i1_log2_ctb_size) + (tu_y);
1015
1016
0
            WORD32 numbytes_row =  (ps_sps->i2_pic_width_in_luma_samples + 63) / 64;
1017
1018
0
            pu1_pic_intra_flag = ps_proc->pu1_pic_intra_flag;
1019
0
            pu1_pic_intra_flag += (tu_abs_y >> 3) * numbytes_row;
1020
0
            pu1_pic_intra_flag += (tu_abs_x >> 6);
1021
1022
0
            intra_flag = *pu1_pic_intra_flag;
1023
0
            intra_flag &= (1 << ((tu_abs_x >> 3) % 8));
1024
0
        }
1025
1026
0
        u1_luma_pred_mode = ps_tu->b6_luma_intra_mode;
1027
0
        u1_chroma_pred_mode = ps_tu->b3_chroma_intra_mode_idx;
1028
1029
0
        if(CHROMA_FMT_IDC_MONOCHROME != ps_sps->i1_chroma_format_idc && u1_chroma_pred_mode != 7)
1030
0
            num_comp = 2; /* Y and UV */
1031
0
        else
1032
0
            num_comp = 1; /* Y */
1033
1034
0
        pcm_flag = 0;
1035
1036
0
        if((intra_flag) && (u1_luma_pred_mode == INTRA_PRED_NONE))
1037
0
        {
1038
0
            UWORD8 *pu1_buf;
1039
0
            UWORD8 *pu1_y_dst = pu1_y_dst_ctb;
1040
0
            UWORD8 *pu1_uv_dst = pu1_uv_dst_ctb;
1041
0
            WORD32 i, j;
1042
0
            tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data;
1043
0
            WORD32 cb_size = 1 << (ps_tu->b3_size + 2);
1044
1045
            /* trans_size is used to update availability after reconstruction */
1046
0
            trans_size = cb_size;
1047
1048
0
            pcm_flag = 1;
1049
1050
0
            tu_y_offset = tu_x + tu_y * pic_strd;
1051
0
            pu1_y_dst += tu_x + tu_y * pic_strd;
1052
1053
            /* First byte points to number of coded blocks */
1054
0
            pu1_tu_coeff_data++;
1055
1056
            /* Next byte points to scan type */
1057
0
            pu1_tu_coeff_data++;
1058
1059
0
            ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)pu1_tu_coeff_data;
1060
1061
0
            pu1_buf = (UWORD8 *)&ps_tu_sblk_coeff_data->ai2_level[0];
1062
0
            {
1063
1064
0
                for(i = 0; i < cb_size; i++)
1065
0
                {
1066
                    //pu1_y_dst[i * pic_strd + j] = *pu1_buf++;
1067
0
                    memcpy(&pu1_y_dst[i * pic_strd], pu1_buf, cb_size);
1068
0
                    pu1_buf += cb_size;
1069
0
                }
1070
1071
0
                if(ps_sps->i1_chroma_format_idc != CHROMA_FMT_IDC_MONOCHROME)
1072
0
                {
1073
0
                    WORD32 chroma_strd = (pic_strd * chroma_pixel_strd) / h_samp_factor;
1074
1075
0
                    pu1_uv_dst += (tu_x * chroma_pixel_strd / h_samp_factor)
1076
0
                                    + (tu_y * chroma_pixel_strd * pic_strd / (h_samp_factor * v_samp_factor));
1077
0
                    pu1_uv_dst = pu1_uv_dst + chroma_yuv420sp_vu_u_offset;
1078
1079
                    /* U */
1080
0
                    for(i = 0; i < cb_size / v_samp_factor; i++)
1081
0
                    {
1082
0
                        for(j = 0; j < cb_size / h_samp_factor; j++)
1083
0
                        {
1084
0
                            pu1_uv_dst[i * chroma_strd + chroma_pixel_strd * j] = *pu1_buf++;
1085
0
                        }
1086
0
                    }
1087
1088
0
                    pu1_uv_dst = pu1_uv_dst + 1 + chroma_yuv420sp_vu_v_offset;
1089
1090
                    /* V */
1091
0
                    for(i = 0; i < cb_size / v_samp_factor; i++)
1092
0
                    {
1093
0
                        for(j = 0; j < cb_size / h_samp_factor; j++)
1094
0
                        {
1095
0
                            pu1_uv_dst[i * chroma_strd + chroma_pixel_strd * j] = *pu1_buf++;
1096
0
                        }
1097
0
                    }
1098
0
                }
1099
0
            }
1100
1101
0
            pu1_tu_coeff_data = pu1_buf;
1102
1103
0
        }
1104
1105
1106
1107
1108
1109
0
        for(c_idx = 0; c_idx < num_comp; c_idx++)
1110
0
        {
1111
0
            if(0 == pcm_flag)
1112
0
            {
1113
1114
0
                if(c_idx == 0) /* Y */
1115
0
                {
1116
                    /* Initializing variables */
1117
1118
0
                    log2_y_trans_size_minus_2 = ps_tu->b3_size;
1119
0
                    trans_size = 1 << (log2_y_trans_size_minus_2 + 2);
1120
0
                    log2_trans_size = log2_y_trans_size_minus_2 + 2;
1121
1122
0
                    tu_y_offset = tu_x + tu_y * pic_strd;
1123
1124
                    /* Calculating scaling matrix offset */
1125
0
                    offset = log2_y_trans_size_minus_2 * 6 + (!intra_flag) * 3 + c_idx;
1126
0
                    pi2_dequant_matrix = pi2_scaling_mat + scaling_mat_offset[offset];
1127
1128
                    /* 4x4 transform Luma in INTRA mode is DST */
1129
0
                    if(log2_y_trans_size_minus_2 == 0 && intra_flag)
1130
0
                    {
1131
0
                        func_idx = log2_y_trans_size_minus_2;
1132
0
                        e_trans_type = DST_4x4;
1133
0
                    }
1134
0
                    else
1135
0
                    {
1136
0
                        func_idx = log2_y_trans_size_minus_2 + 1;
1137
0
                        e_trans_type = (TRANSFORM_TYPE)(log2_y_trans_size_minus_2 + 1);
1138
0
                    }
1139
1140
0
                    qp_div = ps_tu->b7_qp / 6;
1141
0
                    qp_rem = ps_tu->b7_qp % 6;
1142
1143
0
                    y_cb_tu.pi2_tu_coeff = pi2_tu_coeff;
1144
0
                    y_cb_tu.pu1_pred = pu1_y_dst_ctb + tu_y_offset;
1145
0
                    y_cb_tu.pu1_dst = pu1_y_dst_ctb + tu_y_offset;
1146
0
                    y_cb_tu.tu_coeff_stride = trans_size;
1147
0
                    y_cb_tu.pred_strd = pic_strd;
1148
0
                    y_cb_tu.dst_strd = pic_strd;
1149
0
                    y_cb_tu.cbf = ps_tu->b1_y_cbf;
1150
0
                    y_cb_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1;
1151
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1152
0
                    y_cb_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1;
1153
0
                    y_cb_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1;
1154
0
#endif
1155
                    /* Unpacking coeffs */
1156
0
                    if(1 == y_cb_tu.cbf)
1157
0
                    {
1158
0
                        pu1_tu_coeff_data = ihevcd_unpack_coeffs(
1159
0
                                        y_cb_tu.pi2_tu_coeff, log2_y_trans_size_minus_2 + 2,
1160
0
                                        pu1_tu_coeff_data, pi2_dequant_matrix,
1161
0
                                        qp_rem, qp_div, e_trans_type,
1162
0
                                        ps_tu->b1_transquant_bypass, &y_cb_tu.zero_cols,
1163
0
                                        &y_cb_tu.zero_rows, &y_cb_tu.coeff_type,
1164
0
                                        &y_cb_tu.coeff_value);
1165
0
                    }
1166
0
                }
1167
0
                else /* UV interleaved */
1168
0
                {
1169
                    /* Initializing variables */
1170
0
                    const WORD16 *pi2_ihevcd_chroma_qp =
1171
0
                                    CHROMA_FMT_IDC_YUV420 != ps_sps->i1_chroma_format_idc ?
1172
0
                                                    gai2_ihevcd_chroma_qp_clip :
1173
0
                                                    gai2_ihevcd_chroma_qp_420;
1174
1175
                    /* Chroma :If Transform size is 4x4, keep 4x4 else do transform on (trans_size/2 x trans_size/2) */
1176
0
                    if(ps_tu->b3_size == 0)
1177
0
                    {
1178
0
                        log2_uv_trans_size_minus_2 = ps_tu->b3_size;
1179
0
                        if(CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc)
1180
0
                        {
1181
0
                            tu_uv_offset = (tu_x * chroma_pixel_strd)
1182
0
                                            + (tu_y * chroma_pixel_strd * pic_strd);
1183
0
                        }
1184
0
                        else
1185
0
                        {
1186
                            /* Chroma 4x4 is present with 4th luma 4x4 block. For this case chroma postion has to be (luma pos x - 4, luma pos y - 4) */
1187
0
                            tu_uv_offset = (tu_x - 4) + ((tu_y - 4) / v_samp_factor) * pic_strd;
1188
0
                        }
1189
0
                    }
1190
0
                    else
1191
0
                    {
1192
0
                        if(CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc)
1193
0
                        {
1194
0
                            log2_uv_trans_size_minus_2 = ps_tu->b3_size;
1195
0
                        }
1196
0
                        else
1197
0
                        {
1198
0
                            log2_uv_trans_size_minus_2 = ps_tu->b3_size - 1;
1199
0
                        }
1200
0
                        tu_uv_offset = (tu_x * chroma_pixel_strd / h_samp_factor)
1201
0
                                        + (tu_y * chroma_pixel_strd * pic_strd / (h_samp_factor * v_samp_factor));
1202
0
                    }
1203
0
                    trans_size = 1 << (log2_uv_trans_size_minus_2 + 2);
1204
0
                    log2_trans_size = log2_uv_trans_size_minus_2 + 2;
1205
1206
                    /*TODO: Add support for choosing different tables for U and V,
1207
                     * change this to a single array to handle flat/default/custom, intra/inter, luma/chroma and various sizes
1208
                     */
1209
                    /* Calculating scaling matrix offset */
1210
                    /* ((log2_uv_trans_size_minus_2 == 3) ? 1:3) condition check is not needed, since
1211
                     * max uv trans size is 16x16
1212
                     */
1213
0
                    offset = log2_uv_trans_size_minus_2 * 6 + (!intra_flag) * 3 + c_idx;
1214
0
                    pi2_dequant_matrix = pi2_scaling_mat + scaling_mat_offset[offset];
1215
0
                    pi2_dequant_matrix_v = pi2_scaling_mat + scaling_mat_offset[offset + 1];
1216
1217
0
                    func_idx = 1 + 4 + log2_uv_trans_size_minus_2; /* DST func + Y funcs + cur func index*/
1218
1219
                    /* Handle error cases where 64x64 TU is signalled which results in 32x32 chroma.
1220
                     * Limit func_idx based on allowed max chroma tu size */
1221
0
                    func_idx = MIN(func_idx, (CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) ? 8 : 7);
1222
1223
0
                    e_trans_type = (TRANSFORM_TYPE)(log2_uv_trans_size_minus_2 + 1);
1224
                    /* QP for U */
1225
0
                    i1_chroma_pic_qp_offset = ps_pps->i1_pic_cb_qp_offset;
1226
0
                    i1_chroma_slice_qp_offset = ps_slice_hdr->i1_slice_cb_qp_offset;
1227
1228
0
                    chroma_qp_idx = ps_tu->b7_qp + i1_chroma_pic_qp_offset + i1_chroma_slice_qp_offset;
1229
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1230
0
                    if(ps_tu->b1_cu_chroma_qp_offset_flag)
1231
0
                    {
1232
0
                        chroma_qp_idx += ps_pps->i4_cb_qp_offset_list[ps_tu->b3_cu_chroma_qp_offset_idx];
1233
0
                    }
1234
0
#endif
1235
0
                    chroma_qp_idx = CLIP3(chroma_qp_idx, 0, 57);
1236
0
                    qp_div = pi2_ihevcd_chroma_qp[chroma_qp_idx] / 6;
1237
0
                    qp_rem = pi2_ihevcd_chroma_qp[chroma_qp_idx] % 6;
1238
1239
                    /* QP for V */
1240
0
                    i1_chroma_pic_qp_offset = ps_pps->i1_pic_cr_qp_offset;
1241
0
                    i1_chroma_slice_qp_offset = ps_slice_hdr->i1_slice_cr_qp_offset;
1242
1243
0
                    chroma_qp_idx = ps_tu->b7_qp + i1_chroma_pic_qp_offset + i1_chroma_slice_qp_offset;
1244
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1245
0
                    if(ps_tu->b1_cu_chroma_qp_offset_flag)
1246
0
                    {
1247
0
                        chroma_qp_idx += ps_pps->i4_cr_qp_offset_list[ps_tu->b3_cu_chroma_qp_offset_idx];
1248
0
                    }
1249
0
#endif
1250
0
                    chroma_qp_idx = CLIP3(chroma_qp_idx, 0, 57);
1251
0
                    qp_div_v = pi2_ihevcd_chroma_qp[chroma_qp_idx] / 6;
1252
0
                    qp_rem_v = pi2_ihevcd_chroma_qp[chroma_qp_idx] % 6;
1253
1254
0
                    y_cb_tu.pi2_tu_coeff = pi2_tu_coeff;
1255
0
                    y_cb_tu.pu1_pred = pu1_uv_dst_ctb + tu_uv_offset + chroma_yuv420sp_vu_u_offset; /* Pointing to start byte of U*/
1256
0
                    y_cb_tu.pu1_dst = pu1_uv_dst_ctb + tu_uv_offset + chroma_yuv420sp_vu_u_offset; /* Pointing to start byte of U*/
1257
0
                    y_cb_tu.tu_coeff_stride = trans_size;
1258
0
                    y_cb_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1259
0
                    y_cb_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1260
0
                    y_cb_tu.cbf = ps_tu->b1_cb_cbf;
1261
1262
0
                    cr_tu.pi2_tu_coeff = pi2_tu_coeff + trans_size * trans_size;
1263
0
                    cr_tu.pu1_pred = y_cb_tu.pu1_pred + 1 + chroma_yuv420sp_vu_v_offset; /* Pointing to start byte of V*/
1264
0
                    cr_tu.pu1_dst = y_cb_tu.pu1_dst + 1 + chroma_yuv420sp_vu_v_offset; /* Pointing to start byte of V*/
1265
0
                    cr_tu.tu_coeff_stride = trans_size;
1266
0
                    cr_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1267
0
                    cr_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1268
0
                    cr_tu.cbf = ps_tu->b1_cr_cbf;
1269
1270
                    /* Unpacking coeffs */
1271
0
                    y_cb_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1;
1272
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1273
0
                    y_cb_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1;
1274
0
                    y_cb_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1;
1275
0
#endif
1276
0
                    if(1 == y_cb_tu.cbf)
1277
0
                    {
1278
0
                        pu1_tu_coeff_data = ihevcd_unpack_coeffs(
1279
0
                                        y_cb_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2,
1280
0
                                        pu1_tu_coeff_data, pi2_dequant_matrix,
1281
0
                                        qp_rem, qp_div, e_trans_type,
1282
0
                                        ps_tu->b1_transquant_bypass, &y_cb_tu.zero_cols,
1283
0
                                        &y_cb_tu.zero_rows, &y_cb_tu.coeff_type,
1284
0
                                        &y_cb_tu.coeff_value);
1285
0
                    }
1286
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1287
0
                    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
1288
0
                    {
1289
0
                        cb_sub_tu.pi2_tu_coeff = ps_proc->pi2_invscan_out_subtu;
1290
0
                        cb_sub_tu.pu1_pred = y_cb_tu.pu1_pred + trans_size * y_cb_tu.pred_strd;
1291
0
                        cb_sub_tu.pu1_dst = y_cb_tu.pu1_dst + trans_size * y_cb_tu.dst_strd;
1292
0
                        cb_sub_tu.tu_coeff_stride = trans_size;
1293
0
                        cb_sub_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1294
0
                        cb_sub_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1295
0
                        cb_sub_tu.cbf = ps_tu->b1_cb_cbf_subtu1;
1296
0
                        cb_sub_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1;
1297
0
                        cb_sub_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1;
1298
0
                        cb_sub_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1;
1299
0
                        if(1 == cb_sub_tu.cbf)
1300
0
                        {
1301
0
                            pu1_tu_coeff_data = ihevcd_unpack_coeffs(
1302
0
                                            cb_sub_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2,
1303
0
                                            pu1_tu_coeff_data, pi2_dequant_matrix,
1304
0
                                            qp_rem, qp_div, e_trans_type,
1305
0
                                            ps_tu->b1_transquant_bypass, &cb_sub_tu.zero_cols,
1306
0
                                            &cb_sub_tu.zero_rows, &cb_sub_tu.coeff_type,
1307
0
                                            &cb_sub_tu.coeff_value);
1308
0
                        }
1309
0
                    }
1310
0
#endif
1311
1312
0
                    cr_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1;
1313
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1314
0
                    cr_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1;
1315
0
                    cr_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1;
1316
0
#endif
1317
0
                    if(1 == cr_tu.cbf)
1318
0
                    {
1319
0
                        pu1_tu_coeff_data = ihevcd_unpack_coeffs(
1320
0
                                        cr_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2,
1321
0
                                        pu1_tu_coeff_data, pi2_dequant_matrix_v,
1322
0
                                        qp_rem_v, qp_div_v, e_trans_type,
1323
0
                                        ps_tu->b1_transquant_bypass, &cr_tu.zero_cols,
1324
0
                                        &cr_tu.zero_rows, &cr_tu.coeff_type, &cr_tu.coeff_value);
1325
0
                    }
1326
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1327
0
                    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
1328
0
                    {
1329
0
                        cr_sub_tu.pi2_tu_coeff = ps_proc->pi2_invscan_out_subtu + trans_size * trans_size;
1330
0
                        cr_sub_tu.pu1_pred = cr_tu.pu1_pred + trans_size * cr_tu.pred_strd;
1331
0
                        cr_sub_tu.pu1_dst = cr_tu.pu1_dst + trans_size * cr_tu.dst_strd;
1332
0
                        cr_sub_tu.tu_coeff_stride = trans_size;
1333
0
                        cr_sub_tu.pred_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1334
0
                        cr_sub_tu.dst_strd = pic_strd * chroma_pixel_strd / h_samp_factor;
1335
0
                        cr_sub_tu.cbf = ps_tu->b1_cr_cbf_subtu1;
1336
0
                        cr_sub_tu.transform_skip_flag = pu1_tu_coeff_data[1] & 1;
1337
0
                        cr_sub_tu.explicit_rdpcm_flag = (pu1_tu_coeff_data[1] >> 4) & 1;
1338
0
                        cr_sub_tu.explicit_rdpcm_dir = (pu1_tu_coeff_data[1] >> 5) & 1;
1339
0
                        if(1 == cr_sub_tu.cbf)
1340
0
                        {
1341
0
                            pu1_tu_coeff_data = ihevcd_unpack_coeffs(
1342
0
                                            cr_sub_tu.pi2_tu_coeff, log2_uv_trans_size_minus_2 + 2,
1343
0
                                            pu1_tu_coeff_data, pi2_dequant_matrix_v,
1344
0
                                            qp_rem_v, qp_div_v, e_trans_type,
1345
0
                                            ps_tu->b1_transquant_bypass, &cr_sub_tu.zero_cols,
1346
0
                                            &cr_sub_tu.zero_rows, &cr_sub_tu.coeff_type,
1347
0
                                            &cr_sub_tu.coeff_value);
1348
0
                        }
1349
0
                    }
1350
0
#endif
1351
0
                }
1352
0
                WORD8 subtu_idx = 0;
1353
0
                do
1354
0
                {
1355
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1356
0
                if(subtu_idx != 0 && c_idx != 0)
1357
0
                {
1358
0
                    ps_cb_tu = &cb_sub_tu;
1359
0
                    ps_cr_tu = &cr_sub_tu;
1360
0
                    chroma_nbr_flags = chroma_nbr_flags_subtu;
1361
0
                }
1362
0
#endif
1363
                /***************************************************************/
1364
                /******************  Intra Prediction **************************/
1365
                /***************************************************************/
1366
0
                if(intra_flag) /* Intra */
1367
0
                {
1368
                    /* While (MAX_TU_SIZE * 2 * 2) + 1 is the actaul size needed,
1369
                       au1_ref_sub_out size is kept as multiple of 8,
1370
                       so that SIMD functions can load 64 bits. Also some SIMD
1371
                       modules read few bytes before the start of the array, so
1372
                       allocate 16 extra bytes at the start */
1373
0
                    UWORD8 au1_ref_sub_out[16 + (MAX_TU_SIZE * 2 * 2 * 2) + 8] = {0};
1374
0
                    UWORD8 *pu1_ref_sub_out = &au1_ref_sub_out[16];
1375
0
                    UWORD8 *pu1_top_left, *pu1_top, *pu1_left;
1376
0
                    WORD32 luma_pred_func_idx, chroma_pred_func_idx;
1377
1378
                    /* Get the neighbour availability flags */
1379
                    /* Done for only Y */
1380
0
                    if(c_idx == 0)
1381
0
                    {
1382
                        /* Get neighbor availability for Y only */
1383
0
                        luma_nbr_flags = ihevcd_get_intra_nbr_flag(ps_proc,
1384
0
                                                                   ps_tu,
1385
0
                                                                   au4_intra_nbr_avail,
1386
0
                                                                   ps_sps->i2_pic_width_in_luma_samples,
1387
0
                                                                   ps_pps->i1_constrained_intra_pred_flag,
1388
0
                                                                   trans_size,
1389
0
                                                                   ctb_size);
1390
1391
0
                        if(trans_size == 4)
1392
0
                            luma_nbr_flags_4x4[(ps_tu->b4_pos_x % 2) + (ps_tu->b4_pos_y % 2) * 2] = luma_nbr_flags;
1393
1394
0
                        if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
1395
0
                        {
1396
0
                            chroma_nbr_flags = luma_nbr_flags;
1397
0
                        }
1398
0
                        else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
1399
0
                        {
1400
                            /*
1401
                             * Neighbor Bitfield Layout in libhevc (17 bits):
1402
                             *   Bit 16: Top-Left (TL)
1403
                             *   Bits 15..12: Top-Right (TR) - 4 chunks of 8px (Bits 12, 13, 14, 15)
1404
                             *   Bits 11..8:  Top (T)       - 4 chunks of 8px (Bits 8, 9, 10, 11)
1405
                             *   Bits 7..4:   Left (L)      - 4 chunks of 8px (Bits 7, 6, 5, 4)
1406
                             *   Bits 3..0:   Bottom-Left (BL) - 4 chunks of 8px (Bits 3, 2, 1, 0)
1407
                             *
1408
                             * Mapping Rules for 4:2:2:
1409
                             * 1. Sub-TU 0 (Upper (trans_size/2) x (trans_size/2)):
1410
                             *    - Left: Upper half of parent Luma Left boundary.
1411
                             *    - Bottom-Left: Lower half of parent Luma Left boundary.
1412
                             * 2. Sub-TU 1 (Lower (trans_size/2) x (trans_size/2)):
1413
                             *    - Top-Left: Bottom pixel of Sub-TU 0 Left boundary.
1414
                             *    - Top: Always available from reconstructed bottom row of Sub-TU 0.
1415
                             *    - Top-Right: 0 (not yet decoded in Z-scan order; padded by substitution).
1416
                             *    - Left: Lower half of parent Luma Left boundary.
1417
                             *    - Bottom-Left: Parent Luma Bottom-Left boundary.
1418
                             */
1419
0
                            WORD32 tp_left = (luma_nbr_flags & 0x10000);
1420
1421
0
                            switch (trans_size)
1422
0
                            {
1423
0
                            case 8:
1424
0
                                 {
1425
                                     /* Luma 8x8 -> Two 4x4 Chroma Sub-TUs (1 chunk of 4/8px per edge) */
1426
0
                                     WORD32 chroma_Left = (luma_nbr_flags & 0x80);
1427
0
                                     WORD32 chroma_BL = (luma_nbr_flags & 0x80) ? 0x8 : 0;
1428
0
                                     chroma_nbr_flags = tp_left | (luma_nbr_flags & 0x1000) | (luma_nbr_flags & 0x100) | chroma_Left | chroma_BL;
1429
1430
0
                                     WORD32 tp_left_subtu1 = (luma_nbr_flags & 0x80) ? 0x10000 : 0;
1431
0
                                     WORD32 chroma_Left_subtu = (luma_nbr_flags & 0x80);
1432
0
                                     WORD32 chroma_BL_subtu = (luma_nbr_flags & 0x8);
1433
                                     /* Top of Sub-TU 1 is 1 chunk (Bit 8 = 0x100) from reconstructed Sub-TU 0 */
1434
0
                                     chroma_nbr_flags_subtu = tp_left_subtu1 | 0x100 | chroma_Left_subtu | chroma_BL_subtu;
1435
0
                                 }
1436
0
                                 break;
1437
0
                            case 16:
1438
0
                                 {
1439
                                     /* Luma 16x16 -> Two 8x8 Chroma Sub-TUs (1 chunk of 8px per edge) */
1440
0
                                     WORD32 chroma_Left = (luma_nbr_flags & 0x80) ? 0xC0 : 0;
1441
0
                                     WORD32 chroma_BL = (luma_nbr_flags & 0x40) ? 0xC : 0;
1442
0
                                     chroma_nbr_flags = tp_left | (luma_nbr_flags & 0x3000) | (luma_nbr_flags & 0x300) | chroma_Left | chroma_BL;
1443
1444
0
                                     WORD32 tp_left_subtu1 = (luma_nbr_flags & 0x80) ? 0x10000 : 0;
1445
0
                                     WORD32 chroma_Left_subtu = (luma_nbr_flags & 0x40) ? 0xC0 : 0;
1446
0
                                     WORD32 chroma_BL_subtu = (luma_nbr_flags & 0x8) ? 0xC : 0;
1447
                                     /* Top of Sub-TU 1 is 2 chunks (Bits 8,9 = 0x300) from reconstructed Sub-TU 0 */
1448
0
                                     chroma_nbr_flags_subtu = tp_left_subtu1 | 0x300 | chroma_Left_subtu | chroma_BL_subtu;
1449
0
                                 }
1450
0
                                 break;
1451
0
                            case 32:
1452
0
                                 {
1453
                                     /* Luma 32x32 -> Two 16x16 Chroma Sub-TUs (2 chunks of 8px per edge) */
1454
0
                                     WORD32 chroma_Left = ((luma_nbr_flags & 0x80) ? 0xC0 : 0) | ((luma_nbr_flags & 0x40) ? 0x30 : 0);
1455
0
                                     WORD32 chroma_BL = ((luma_nbr_flags & 0x20) ? 0xC : 0) | ((luma_nbr_flags & 0x10) ? 0x3 : 0);
1456
0
                                     chroma_nbr_flags = tp_left | (luma_nbr_flags & 0xF000) | (luma_nbr_flags & 0xF00) | chroma_Left | chroma_BL;
1457
1458
0
                                     WORD32 tp_left_subtu1 = (luma_nbr_flags & 0x40) ? 0x10000 : 0;
1459
0
                                     WORD32 chroma_Left_subtu = ((luma_nbr_flags & 0x20) ? 0xC0 : 0) | ((luma_nbr_flags & 0x10) ? 0x30 : 0);
1460
0
                                     WORD32 chroma_BL_subtu = ((luma_nbr_flags & 0x8) ? 0xC : 0) | ((luma_nbr_flags & 0x4) ? 0x3 : 0);
1461
                                     /* Top of Sub-TU 1 is 4 chunks (Bits 8..11 = 0xF00) from reconstructed Sub-TU 0 */
1462
0
                                     chroma_nbr_flags_subtu = tp_left_subtu1 | 0xF00 | chroma_Left_subtu | chroma_BL_subtu;
1463
0
                                 }
1464
0
                                 break;
1465
0
                            default:
1466
0
                                chroma_nbr_flags = (luma_nbr_flags & 0x1ff00) | (luma_nbr_flags & 0xf0) | ((luma_nbr_flags & 0xf0) >> 4);
1467
0
                                chroma_nbr_flags_subtu = (((luma_nbr_flags & 0xf0) != 0 ? 1 : 0) << 16) | (0xf << 8) | (luma_nbr_flags & 0xff);
1468
0
                                break;
1469
0
                            }
1470
0
                        }
1471
0
                        else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420)
1472
0
                        {
1473
0
                            if(((ps_tu->b4_pos_x % 2 == 0) && (ps_tu->b4_pos_y % 2 == 0)))
1474
0
                                chroma_nbr_flags = luma_nbr_flags;
1475
0
                        }
1476
1477
                        /* Initializing nbr pointers */
1478
0
                        pu1_top = y_cb_tu.pu1_pred - pic_strd;
1479
0
                        pu1_left = y_cb_tu.pu1_pred - 1;
1480
0
                        pu1_top_left = y_cb_tu.pu1_pred - pic_strd - 1;
1481
1482
                        /* call reference array substitution */
1483
0
                        if(luma_nbr_flags == 0x1ffff)
1484
0
                            ps_codec->s_func_selector.ihevc_intra_pred_luma_ref_subst_all_avlble_fptr(
1485
0
                                            pu1_top_left,
1486
0
                                            pu1_top, pu1_left, y_cb_tu.pred_strd, trans_size, luma_nbr_flags, pu1_ref_sub_out, 1);
1487
0
                        else
1488
0
                            ps_codec->s_func_selector.ihevc_intra_pred_luma_ref_substitution_fptr(
1489
0
                                            pu1_top_left,
1490
0
                                            pu1_top, pu1_left, y_cb_tu.pred_strd, trans_size, luma_nbr_flags, pu1_ref_sub_out, 1);
1491
1492
                        /* call reference filtering */
1493
0
                        ps_codec->s_func_selector.ihevc_intra_pred_ref_filtering_fptr(
1494
0
                                        pu1_ref_sub_out,
1495
0
                                        trans_size,
1496
0
                                        pu1_ref_sub_out,
1497
0
                                        u1_luma_pred_mode,
1498
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1499
0
                                        (ps_sps->i1_intra_smoothing_disabled_flag << 3
1500
0
                                                        | ps_sps->i1_strong_intra_smoothing_enable_flag)
1501
#else
1502
                                        ps_sps->i1_strong_intra_smoothing_enable_flag
1503
#endif
1504
0
                                        );
1505
1506
                        /* use the look up to get the function idx */
1507
0
                        luma_pred_func_idx = g_i4_ip_funcs[u1_luma_pred_mode];
1508
1509
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1510
0
                        if(ps_sps->i1_implicit_rdpcm_enabled_flag && ps_tu->b1_transquant_bypass
1511
0
                                        && (u1_luma_pred_mode == 10 || u1_luma_pred_mode == 26))
1512
0
                            disable_boundary_filter = 1;
1513
0
#endif
1514
                        /* call the intra prediction function */
1515
0
                        ps_codec->apf_intra_pred_luma[luma_pred_func_idx](
1516
0
                                        pu1_ref_sub_out, 1,
1517
0
                                        y_cb_tu.pu1_pred,
1518
0
                                        y_cb_tu.pred_strd,
1519
0
                                        trans_size,
1520
0
                                        (u1_luma_pred_mode == 10 || u1_luma_pred_mode == 26) ?
1521
0
                                                        disable_boundary_filter :
1522
0
                                                        u1_luma_pred_mode
1523
0
                                        );
1524
0
                    }
1525
0
                    else
1526
0
                    {
1527
                        /* In case of yuv420sp_vu, prediction happens as usual.         */
1528
                        /* So point the pu1_pred pointer to original prediction pointer */
1529
0
                        UWORD8 *pu1_pred_orig = ps_cb_tu->pu1_pred - chroma_yuv420sp_vu_u_offset;
1530
1531
                        /*    Top-Left | Top-Right | Top | Left | Bottom-Left
1532
                         *      1         4         4     4         4
1533
                         *
1534
                         * Generating chroma_nbr_flags depending upon the transform size */
1535
0
                        if(ps_tu->b3_size == 0)
1536
0
                        {
1537
0
                            if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420)
1538
0
                            {
1539
                                /* Take TL,T,L flags of First luma 4x4 block */
1540
0
                                chroma_nbr_flags = (luma_nbr_flags_4x4[0] & 0x10FF0);
1541
                                /* Take TR flags of Second luma 4x4 block */
1542
0
                                chroma_nbr_flags |= (luma_nbr_flags_4x4[1] & 0x0F000);
1543
                                /* Take BL flags of Third luma 4x4 block */
1544
0
                                chroma_nbr_flags |= (luma_nbr_flags_4x4[2] & 0x0000F);
1545
0
                            }
1546
0
                            else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
1547
0
                            {
1548
0
                                if(subtu_idx == 0)
1549
0
                                {
1550
                                    /* Take TL,T,L flags of First luma 4x4 block */
1551
0
                                    chroma_nbr_flags = (luma_nbr_flags_4x4[0] & 0x10FF0);
1552
                                    /* Take TR flags of Second luma 4x4 block */
1553
0
                                    chroma_nbr_flags |= (luma_nbr_flags_4x4[1] & 0x0F000);
1554
                                    /* Take BL flags of first luma 4x4 block */
1555
0
                                    chroma_nbr_flags |= (luma_nbr_flags_4x4[0] & 0x0000F);
1556
0
                                }
1557
0
                                else
1558
0
                                {
1559
                                    /* Take TL,T,L flags of Third luma 4x4 block */
1560
0
                                    chroma_nbr_flags = (luma_nbr_flags_4x4[2] & 0x10FF0);
1561
                                    /* Take BL flags of Third luma 4x4 block */
1562
0
                                    chroma_nbr_flags |= (luma_nbr_flags_4x4[2] & 0x0000F);
1563
0
                                }
1564
0
                            }
1565
0
                        }
1566
1567
                        /* Initializing nbr pointers */
1568
0
                        pu1_top = pu1_pred_orig - (pic_strd * chroma_pixel_strd / h_samp_factor);
1569
0
                        pu1_left = pu1_pred_orig - 2;
1570
0
                        pu1_top_left = pu1_pred_orig - (pic_strd * chroma_pixel_strd / h_samp_factor) - 2;
1571
1572
0
                        if(subtu_idx == 0)
1573
0
                        {
1574
                        /* Chroma pred  mode derivation from luma pred mode */
1575
0
                        {
1576
0
                            tu_t *ps_tu_tmp = ps_tu;
1577
0
                            if(ps_sps->i1_chroma_format_idc != CHROMA_FMT_IDC_YUV444)
1578
0
                            {
1579
0
                                while(!ps_tu_tmp->b1_first_tu_in_cu)
1580
0
                                {
1581
0
                                    ps_tu_tmp--;
1582
0
                                }
1583
0
                            }
1584
0
                            u1_luma_pred_mode_first_tu = ps_tu_tmp->b6_luma_intra_mode;
1585
0
                        }
1586
0
                        if(4 == u1_chroma_pred_mode)
1587
0
                            u1_chroma_pred_mode = u1_luma_pred_mode_first_tu;
1588
0
                        else
1589
0
                        {
1590
0
                            u1_chroma_pred_mode = gau1_intra_pred_chroma_modes[u1_chroma_pred_mode];
1591
1592
0
                            if(u1_chroma_pred_mode == u1_luma_pred_mode_first_tu)
1593
0
                            {
1594
0
                                u1_chroma_pred_mode = INTRA_ANGULAR(34);
1595
0
                            }
1596
0
                        }
1597
0
                        if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
1598
0
                        {
1599
0
                            u1_chroma_pred_mode = gau1_intra_pred_chroma_modes_422[u1_chroma_pred_mode];
1600
0
                        }
1601
0
                        }
1602
1603
                        /* call the chroma reference array substitution */
1604
0
                        ps_codec->s_func_selector.ihevc_intra_pred_chroma_ref_substitution_fptr(
1605
0
                                        pu1_top_left,
1606
0
                                        pu1_top, pu1_left,
1607
0
                                        ps_cb_tu->pred_strd,
1608
0
                                        trans_size, chroma_nbr_flags, pu1_ref_sub_out, 1,
1609
0
                                        ps_sps->i1_chroma_format_idc);
1610
1611
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1612
                        /* call reference filtering */
1613
0
                        if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
1614
0
                        {
1615
0
                            ps_codec->s_func_selector.ihevc_intra_pred_chroma_ref_filtering_fptr(
1616
0
                                            pu1_ref_sub_out,
1617
0
                                            trans_size,
1618
0
                                            pu1_ref_sub_out,
1619
0
                                            u1_chroma_pred_mode,
1620
0
                                            (ps_sps->i1_intra_smoothing_disabled_flag << 3
1621
0
                                                            | ps_sps->i1_strong_intra_smoothing_enable_flag));
1622
0
                        }
1623
0
#endif
1624
1625
                        /* use the look up to get the function idx */
1626
0
                        chroma_pred_func_idx = g_i4_ip_funcs[u1_chroma_pred_mode];
1627
1628
                        /* call the intra prediction function */
1629
0
                        ps_codec->apf_intra_pred_chroma[chroma_pred_func_idx](pu1_ref_sub_out, 1, pu1_pred_orig, ps_cb_tu->pred_strd, trans_size, u1_chroma_pred_mode);
1630
0
                    }
1631
0
                }
1632
1633
                /* Updating number of transform types */
1634
0
                STATS_UPDATE_ALL_TRANS(e_trans_type, c_idx);
1635
1636
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1637
0
                iqitrecon_fptr = get_iqitrec_func(
1638
0
                                ps_proc, ps_tu, ps_cb_tu, log2_trans_size,
1639
0
                                c_idx != 0 ? U_PLANE : NULL_PLANE, intra_flag,
1640
0
                                c_idx == 0 ? u1_luma_pred_mode : u1_chroma_pred_mode);
1641
0
#endif
1642
                /* IQ, IT and Recon for Y if c_idx == 0, and U if c_idx !=0 */
1643
0
                iqitrecon_fptr(ps_proc, ps_tu, ps_cb_tu, func_idx, log2_trans_size,
1644
0
                               c_idx != 0 ? U_PLANE : NULL_PLANE, intra_flag,
1645
0
                               c_idx == 0 ? u1_luma_pred_mode : u1_chroma_pred_mode);
1646
                /* IQ, IT and Recon for V */
1647
0
                if(c_idx != 0)
1648
0
                {
1649
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1650
0
                    iqitrecon_fptr = get_iqitrec_func(ps_proc, ps_tu, ps_cr_tu, log2_trans_size,
1651
0
                                                      V_PLANE, intra_flag, u1_chroma_pred_mode);
1652
0
#endif
1653
0
                    iqitrecon_fptr(ps_proc, ps_tu, ps_cr_tu, func_idx, log2_trans_size, V_PLANE,
1654
0
                                   intra_flag, u1_chroma_pred_mode);
1655
0
                }
1656
0
                }
1657
0
                while(c_idx != 0 && ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422
1658
0
                                && ++subtu_idx < 2);
1659
0
            }
1660
1661
            /* Neighbor availability inside CTB */
1662
            /* 1bit per 4x4. Indicates whether that 4x4 block has been reconstructed(avialable) */
1663
            /* Used for neighbor availability in intra pred */
1664
0
            if(c_idx == 0)
1665
0
            {
1666
0
                WORD32 i;
1667
0
                WORD32 trans_in_min_tu;
1668
0
                UWORD32 cur_tu_in_bits;
1669
0
                UWORD32 cur_tu_avail_flag;
1670
1671
0
                trans_in_min_tu = trans_size / MIN_TU_SIZE;
1672
0
                cur_tu_in_bits = (1 << trans_in_min_tu) - 1;
1673
0
                cur_tu_in_bits = cur_tu_in_bits << (32 - trans_in_min_tu);
1674
1675
0
                cur_tu_avail_flag = cur_tu_in_bits >> (ps_tu->b4_pos_x + 1);
1676
1677
0
                for(i = 0; i < trans_in_min_tu; i++)
1678
0
                    au4_intra_nbr_avail[1 + ps_tu->b4_pos_y + i] |=
1679
0
                                    cur_tu_avail_flag;
1680
0
            }
1681
0
        }
1682
0
    }
1683
0
    ps_proc->pv_tu_coeff_data = pu1_tu_coeff_data;
1684
1685
0
    return ps_proc->i4_ctb_tu_cnt;
1686
0
}
1687