Coverage Report

Created: 2026-08-13 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_parse_slice.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at:
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*
17
******************************************************************************/
18
/**
19
 *******************************************************************************
20
 * @file
21
 *  ihevcd_parse_slice.c
22
 *
23
 * @brief
24
 *  Contains functions for parsing slice data
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
#include "ithread.h"
50
51
#include "ihevc_defs.h"
52
#include "ihevc_debug.h"
53
#include "ihevc_structs.h"
54
#include "ihevc_macros.h"
55
#include "ihevc_mem_fns.h"
56
#include "ihevc_platform_macros.h"
57
58
#include "ihevc_common_tables.h"
59
#include "ihevc_error.h"
60
#include "ihevc_cabac_tables.h"
61
62
#include "ihevcd_trace.h"
63
#include "ihevcd_defs.h"
64
#include "ihevcd_function_selector.h"
65
#include "ihevcd_structs.h"
66
#include "ihevcd_error.h"
67
#include "ihevcd_nal.h"
68
#include "ihevcd_bitstream.h"
69
#include "ihevcd_utils.h"
70
#include "ihevcd_parse_slice.h"
71
#include "ihevcd_parse_residual.h"
72
#include "ihevcd_cabac.h"
73
#include "ihevcd_job_queue.h"
74
#include "ihevcd_intra_pred_mode_prediction.h"
75
#include "ihevcd_common_tables.h"
76
#include "ihevcd_process_slice.h"
77
#include "ihevcd_debug.h"
78
#include "ihevcd_get_mv.h"
79
#include "ihevcd_boundary_strength.h"
80
#include "ihevcd_ilf_padding.h"
81
#include "ihevcd_statistics.h"
82
/* Bit stream offset threshold */
83
0
#define BITSTRM_OFF_THRS 8
84
85
0
#define MIN_CU_QP_DELTA_ABS(x) (-26 + ((x) * 6) / 2)
86
0
#define MAX_CU_QP_DELTA_ABS(x) (25 + ((x) * 6) / 2)
87
88
/**
89
 * Table used to decode part_mode if AMP is enabled and current CU is not min CU
90
 */
91
const UWORD8 gau1_part_mode_amp[] = { PART_nLx2N, PART_nRx2N, PART_Nx2N, 0xFF, PART_2NxnU, PART_2NxnD, PART_2NxN, 0xFF };
92
93
const UWORD32 gau4_ct_depth_mask[] = { 0x0, 0x55555555, 0xAAAAAAAA, 0xFFFFFFFF };
94
95
96
97
/**
98
 *******************************************************************************
99
 *
100
 * @brief
101
 *  Parses Transform tree syntax
102
 *
103
 * @par Description:
104
 *  Parses Transform tree syntax as per Section:7.3.9.8
105
 *
106
 * @param[in] ps_codec
107
 *  Pointer to codec context
108
 *
109
 * @returns  Status
110
 *
111
 * @remarks
112
 *
113
 *
114
 *******************************************************************************
115
 */
116
117
WORD32 ihevcd_parse_transform_tree(codec_t *ps_codec,
118
                                   WORD32 x0, WORD32 y0,
119
                                   WORD32 cu_x_base, WORD32 cu_y_base,
120
                                   WORD32 log2_trafo_size,
121
                                   WORD32 trafo_depth,
122
                                   WORD32 blk_idx,
123
                                   WORD32 intra_pred_mode,
124
                                   WORD32 chroma_intra_pred_mode_idx)
125
0
{
126
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
127
0
    sps_t *ps_sps;
128
0
    pps_t *ps_pps;
129
0
#ifdef ENABLE_MAIN_REXT_PROFILE
130
0
    slice_header_t *ps_slice_hdr;
131
0
#endif
132
0
    WORD32 value;
133
0
    WORD32 x1, y1;
134
0
    WORD32 max_trafo_depth;
135
136
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
137
0
    WORD32 intra_split_flag;
138
0
    WORD32 split_transform_flag;
139
0
    WORD32 ctxt_idx;
140
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
141
142
0
    max_trafo_depth = ps_codec->s_parse.s_cu.i4_max_trafo_depth;
143
0
    ps_sps = ps_codec->s_parse.ps_sps;
144
0
    ps_pps = ps_codec->s_parse.ps_pps;
145
0
#ifdef ENABLE_MAIN_REXT_PROFILE
146
0
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
147
0
#endif
148
0
    intra_split_flag = ps_codec->s_parse.s_cu.i4_intra_split_flag;
149
150
0
    {
151
0
        split_transform_flag = 0;
152
0
        if((log2_trafo_size <= ps_sps->i1_log2_max_transform_block_size) &&
153
0
                        (log2_trafo_size > ps_sps->i1_log2_min_transform_block_size) &&
154
0
                        (trafo_depth < max_trafo_depth) &&
155
0
                        !(intra_split_flag && (trafo_depth == 0)))
156
0
        {
157
            /* encode the split transform flag, context derived as per Table9-37 */
158
0
            ctxt_idx = IHEVC_CAB_SPLIT_TFM + (5 - log2_trafo_size);
159
160
0
            TRACE_CABAC_CTXT("split_transform_flag", ps_cabac->u4_range, ctxt_idx);
161
0
            split_transform_flag = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
162
0
            AEV_TRACE("split_transform_flag", split_transform_flag,
163
0
                      ps_cabac->u4_range);
164
165
0
        }
166
0
        else
167
0
        {
168
0
            WORD32 inter_split_flag = 0;
169
170
0
            if((0 == ps_sps->i1_max_transform_hierarchy_depth_inter) &&
171
0
                            (PRED_MODE_INTER == ps_codec->s_parse.s_cu.i4_pred_mode) &&
172
0
                            (PART_2Nx2N != ps_codec->s_parse.s_cu.i4_part_mode) &&
173
0
                            (0 == trafo_depth))
174
0
            {
175
0
                inter_split_flag = 1;
176
0
            }
177
178
0
            if((log2_trafo_size > ps_sps->i1_log2_max_transform_block_size) ||
179
0
                            ((1 == intra_split_flag) && (0 == trafo_depth)) ||
180
0
                            (1 == inter_split_flag))
181
0
            {
182
0
                split_transform_flag = 1;
183
0
            }
184
0
        }
185
186
0
        if(0 == trafo_depth)
187
0
        {
188
0
            ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth] = 0;
189
0
            ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth] = 0;
190
0
#ifdef ENABLE_MAIN_REXT_PROFILE
191
0
            if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
192
0
            {
193
0
                ps_codec->s_parse.s_cu.ai1_cbf_cr_subtu[trafo_depth] = 0;
194
0
                ps_codec->s_parse.s_cu.ai1_cbf_cb_subtu[trafo_depth] = 0;
195
0
            }
196
0
#endif
197
0
        }
198
0
        else
199
0
        {
200
0
            ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth] = ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth - 1];
201
0
            ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth] = ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth - 1];
202
0
#ifdef ENABLE_MAIN_REXT_PROFILE
203
0
            if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
204
0
            {
205
0
                ps_codec->s_parse.s_cu.ai1_cbf_cb_subtu[trafo_depth] =
206
0
                                ps_codec->s_parse.s_cu.ai1_cbf_cb_subtu[trafo_depth - 1];
207
0
                ps_codec->s_parse.s_cu.ai1_cbf_cr_subtu[trafo_depth] =
208
0
                                ps_codec->s_parse.s_cu.ai1_cbf_cr_subtu[trafo_depth - 1];
209
0
            }
210
0
#endif
211
0
        }
212
0
        if ((CHROMA_FMT_IDC_MONOCHROME != ps_sps->i1_chroma_format_idc && log2_trafo_size > 2) ||
213
0
            ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
214
0
        {
215
0
            ctxt_idx = IHEVC_CAB_CBCR_IDX + trafo_depth;
216
            /* CBF for Cb/Cr is sent only if the parent CBF for Cb/Cr is non-zero */
217
0
            if((trafo_depth == 0) || ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth - 1])
218
0
            {
219
0
                TRACE_CABAC_CTXT("cbf_cb", ps_cabac->u4_range, ctxt_idx);
220
0
                value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
221
0
                AEV_TRACE("cbf_cb", value, ps_cabac->u4_range);
222
0
                ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth] = value;
223
0
#ifdef ENABLE_MAIN_REXT_PROFILE
224
0
                if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422
225
0
                                && (!split_transform_flag || log2_trafo_size == 3))
226
0
                {
227
0
                    TRACE_CABAC_CTXT("cbf_cb", ps_cabac->u4_range, ctxt_idx);
228
0
                    value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
229
0
                    AEV_TRACE("cbf_cb", value, ps_cabac->u4_range);
230
0
                    ps_codec->s_parse.s_cu.ai1_cbf_cb_subtu[trafo_depth] = value;
231
0
                }
232
0
#endif
233
0
            }
234
235
0
            if((trafo_depth == 0) || ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth - 1])
236
0
            {
237
0
                TRACE_CABAC_CTXT("cbf_cr", ps_cabac->u4_range, ctxt_idx);
238
0
                value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
239
0
                AEV_TRACE("cbf_cr", value, ps_cabac->u4_range);
240
0
                ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth] = value;
241
0
#ifdef ENABLE_MAIN_REXT_PROFILE
242
0
                if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422
243
0
                                && (!split_transform_flag || log2_trafo_size == 3))
244
0
                {
245
0
                    TRACE_CABAC_CTXT("cbf_cr", ps_cabac->u4_range, ctxt_idx);
246
0
                    value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
247
0
                    AEV_TRACE("cbf_cr", value, ps_cabac->u4_range);
248
0
                    ps_codec->s_parse.s_cu.ai1_cbf_cr_subtu[trafo_depth] = value;
249
0
                }
250
0
#endif
251
0
            }
252
0
        }
253
0
        if(split_transform_flag)
254
0
        {
255
0
            WORD32 intra_pred_mode_tmp;
256
0
            WORD32 chroma_intra_pred_mode_tmp_idx = ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[0];
257
0
            x1 = x0 + ((1 << log2_trafo_size) >> 1);
258
0
            y1 = y0 + ((1 << log2_trafo_size) >> 1);
259
260
            /* For transform depth of zero, intra pred mode as decoded at CU */
261
            /* level is sent to the transform tree nodes */
262
            /* When depth is non-zero intra pred mode of parent node is sent */
263
            /* This takes care of passing correct mode to all the child nodes */
264
0
            intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0];
265
0
            if (ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
266
0
                chroma_intra_pred_mode_tmp_idx = trafo_depth ? chroma_intra_pred_mode_idx : ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[0];
267
0
            ret = ihevcd_parse_transform_tree(ps_codec, x0, y0, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 0, intra_pred_mode_tmp, chroma_intra_pred_mode_tmp_idx);
268
0
            RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
269
270
0
            intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[1];
271
0
            if (ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
272
0
                chroma_intra_pred_mode_tmp_idx = trafo_depth ? chroma_intra_pred_mode_idx : ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[1];
273
0
            ret = ihevcd_parse_transform_tree(ps_codec, x1, y0, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 1, intra_pred_mode_tmp, chroma_intra_pred_mode_tmp_idx);
274
0
            RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
275
276
0
            intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[2];
277
0
            if (ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
278
0
                chroma_intra_pred_mode_tmp_idx = trafo_depth ? chroma_intra_pred_mode_idx : ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[2];
279
0
            ret = ihevcd_parse_transform_tree(ps_codec, x0, y1, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 2, intra_pred_mode_tmp, chroma_intra_pred_mode_tmp_idx);
280
0
            RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
281
282
0
            intra_pred_mode_tmp = trafo_depth ? intra_pred_mode : ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[3];
283
0
            if (ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
284
0
                chroma_intra_pred_mode_tmp_idx = trafo_depth ? chroma_intra_pred_mode_idx : ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[3];
285
0
            ret = ihevcd_parse_transform_tree(ps_codec, x1, y1, x0, y0, log2_trafo_size - 1, trafo_depth + 1, 3, intra_pred_mode_tmp, chroma_intra_pred_mode_tmp_idx);
286
0
            RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
287
288
0
        }
289
0
        else
290
0
        {
291
0
            WORD32 ctb_x_base;
292
0
            WORD32 ctb_y_base;
293
0
            WORD32 cu_qp_delta_abs;
294
0
            WORD32 cbf_chroma;
295
296
297
298
0
            tu_t *ps_tu = ps_codec->s_parse.ps_tu;
299
0
            cu_qp_delta_abs = 0;
300
0
            ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size;
301
0
            ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size;
302
0
            cbf_chroma = ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth]
303
0
                            || ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth];
304
0
#ifdef ENABLE_MAIN_REXT_PROFILE
305
0
            if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
306
0
            {
307
0
                cbf_chroma |= ps_codec->s_parse.s_cu.ai1_cbf_cb_subtu[trafo_depth]
308
0
                                || ps_codec->s_parse.s_cu.ai1_cbf_cr_subtu[trafo_depth];
309
0
            }
310
0
#endif
311
312
0
            if((ps_codec->s_parse.s_cu.i4_pred_mode == PRED_MODE_INTRA) ||
313
0
                            (trafo_depth != 0) ||
314
0
                            (cbf_chroma))
315
0
            {
316
0
                ctxt_idx = IHEVC_CAB_CBF_LUMA_IDX;
317
0
                ctxt_idx += (trafo_depth == 0) ? 1 : 0;
318
319
0
                TRACE_CABAC_CTXT("cbf_luma", ps_cabac->u4_range, ctxt_idx);
320
0
                value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
321
0
                AEV_TRACE("cbf_luma", value, ps_cabac->u4_range);
322
323
0
                ps_codec->s_parse.s_cu.i1_cbf_luma = value;
324
0
            }
325
0
            else
326
0
            {
327
0
                ps_codec->s_parse.s_cu.i1_cbf_luma = 1;
328
0
            }
329
330
            /* Initialize ps_tu to default values */
331
            /* If required change this to WORD32 packed write */
332
0
            ps_tu->b1_cb_cbf = 0;
333
0
#ifdef ENABLE_MAIN_REXT_PROFILE
334
0
            ps_tu->b1_cb_cbf_subtu1 = 0;
335
0
#endif
336
0
            ps_tu->b1_cr_cbf = 0;
337
0
#ifdef ENABLE_MAIN_REXT_PROFILE
338
0
            ps_tu->b1_cr_cbf_subtu1 = 0;
339
0
#endif
340
0
            ps_tu->b1_y_cbf = 0;
341
0
            ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2);
342
0
            ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2);
343
0
            ps_tu->b1_transquant_bypass = ps_codec->s_parse.s_cu.i4_cu_transquant_bypass;
344
0
            ps_tu->b3_size = (log2_trafo_size - 2);
345
0
            ps_tu->b7_qp = ps_codec->s_parse.u4_qp;
346
0
#ifdef ENABLE_MAIN_REXT_PROFILE
347
0
            ps_tu->b3_cb_log2_res_scale_abs_plus1 = 0;
348
0
            ps_tu->b1_cb_log2_res_sign = 0;
349
0
            ps_tu->b3_cr_log2_res_scale_abs_plus1 = 0;
350
0
            ps_tu->b1_cr_log2_res_sign = 0;
351
0
            ps_tu->b1_cu_chroma_qp_offset_flag = 0;
352
0
            ps_tu->b3_cu_chroma_qp_offset_idx = 0;
353
0
#endif
354
355
0
            ps_tu->b6_luma_intra_mode = intra_pred_mode;
356
0
            ps_tu->b3_chroma_intra_mode_idx = chroma_intra_pred_mode_idx;
357
358
            /* Section:7.3.12  Transform unit syntax inlined here */
359
0
            if(ps_codec->s_parse.s_cu.i1_cbf_luma || cbf_chroma)
360
0
            {
361
0
                WORD32 intra_pred_mode_chroma;
362
0
                if(ps_pps->i1_cu_qp_delta_enabled_flag && !ps_codec->s_parse.i4_is_cu_qp_delta_coded)
363
0
                {
364
365
366
0
                    WORD32 c_max        = TU_MAX_QP_DELTA_ABS;
367
0
                    WORD32 ctxt_inc     = IHEVC_CAB_QP_DELTA_ABS;
368
0
                    WORD32 ctxt_inc_max = CTXT_MAX_QP_DELTA_ABS;
369
370
0
                    TRACE_CABAC_CTXT("cu_qp_delta_abs", ps_cabac->u4_range, ctxt_inc);
371
                    /* qp_delta_abs is coded as combination of tunary and eg0 code  */
372
                    /* See Table 9-32 and Table 9-37 for details on cu_qp_delta_abs */
373
0
                    cu_qp_delta_abs = ihevcd_cabac_decode_bins_tunary(ps_cabac,
374
0
                                                                      ps_bitstrm,
375
0
                                                                      c_max,
376
0
                                                                      ctxt_inc,
377
0
                                                                      0,
378
0
                                                                      ctxt_inc_max);
379
0
                    if(cu_qp_delta_abs >= c_max)
380
0
                    {
381
0
                        value = ihevcd_cabac_decode_bypass_bins_egk(ps_cabac, ps_bitstrm, 0);
382
0
                        cu_qp_delta_abs += value;
383
0
                    }
384
0
                    AEV_TRACE("cu_qp_delta_abs", cu_qp_delta_abs, ps_cabac->u4_range);
385
386
0
                    ps_codec->s_parse.i4_is_cu_qp_delta_coded = 1;
387
388
389
0
                    if(cu_qp_delta_abs)
390
0
                    {
391
0
                        value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm);
392
0
                        AEV_TRACE("cu_qp_delta_sign", value, ps_cabac->u4_range);
393
394
0
                        if(value)
395
0
                            cu_qp_delta_abs = -cu_qp_delta_abs;
396
397
0
                    }
398
399
0
                    if (cu_qp_delta_abs < MIN_CU_QP_DELTA_ABS(ps_sps->i1_bit_depth_luma_minus8)
400
0
                                    || cu_qp_delta_abs > MAX_CU_QP_DELTA_ABS(ps_sps->i1_bit_depth_luma_minus8))
401
0
                    {
402
0
                        return IHEVCD_INVALID_PARAMETER;
403
0
                    }
404
405
0
                    ps_codec->s_parse.s_cu.i4_cu_qp_delta = cu_qp_delta_abs;
406
407
0
                }
408
409
0
#ifdef ENABLE_MAIN_REXT_PROFILE
410
0
                if(ps_slice_hdr->i1_cu_chroma_qp_offset_enabled_flag
411
0
                    && !ps_codec->s_parse.s_cu.i4_cu_transquant_bypass)
412
0
                {
413
0
                    if(!ps_codec->s_parse.i4_is_cu_chroma_qp_offset_coded
414
0
                        && cbf_chroma)
415
0
                    {
416
0
                        ctxt_idx = IHEVC_CAB_CHROMA_QP_OFF_FLAG;
417
0
                        TRACE_CABAC_CTXT("cu_chroma_qp_offset_flag", ps_cabac->u4_range, ctxt_idx);
418
0
                        value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
419
0
                        AEV_TRACE("cu_chroma_qp_offset_flag", value, ps_cabac->u4_range);
420
0
                        ps_codec->s_parse.i4_cu_chroma_qp_offset_flag = value;
421
422
0
                        ps_codec->s_parse.i4_cu_chroma_qp_offset_idx = 0;
423
0
                        if(ps_codec->s_parse.i4_cu_chroma_qp_offset_flag &&
424
0
                           ps_pps->i4_chroma_qp_offset_list_len_minus1 > 0)
425
0
                        {
426
0
                            ctxt_idx = IHEVC_CAB_CHROMA_QP_OFF_IDX;
427
0
                            TRACE_CABAC_CTXT("cu_chroma_qp_offset_idx", ps_cabac->u4_range, ctxt_idx);
428
0
                            value = ihevcd_cabac_decode_bins_tunary(ps_cabac,
429
0
                                                                    ps_bitstrm,
430
0
                                                                    ps_pps->i4_chroma_qp_offset_list_len_minus1,
431
0
                                                                    ctxt_idx,
432
0
                                                                    0,
433
0
                                                                    0);
434
0
                            AEV_TRACE("cu_chroma_qp_offset_idx", value, ps_cabac->u4_range);
435
0
                            ps_codec->s_parse.i4_cu_chroma_qp_offset_idx = value;
436
0
                        }
437
438
0
                        ps_codec->s_parse.i4_is_cu_chroma_qp_offset_coded = 1;
439
0
                    }
440
0
                    ps_tu->b1_cu_chroma_qp_offset_flag =
441
0
                            ps_codec->s_parse.i4_cu_chroma_qp_offset_flag;
442
0
                    ps_tu->b3_cu_chroma_qp_offset_idx =
443
0
                            ps_codec->s_parse.i4_cu_chroma_qp_offset_idx;
444
0
                }
445
0
#endif
446
447
0
                if(ps_codec->s_parse.s_cu.i1_cbf_luma)
448
0
                {
449
0
                    ps_tu->b1_y_cbf = 1;
450
0
                    ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size, 0, intra_pred_mode);
451
0
                }
452
453
0
                WORD32 chroma_blk_luma_intra_pred_mode =
454
0
                                ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444 ?
455
0
                                                intra_pred_mode :
456
0
                                                ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0];
457
0
                if(4 == chroma_intra_pred_mode_idx)
458
0
                    intra_pred_mode_chroma = chroma_blk_luma_intra_pred_mode;
459
0
                else
460
0
                {
461
0
                    intra_pred_mode_chroma = gau1_intra_pred_chroma_modes[chroma_intra_pred_mode_idx];
462
463
0
                    if(intra_pred_mode_chroma == chroma_blk_luma_intra_pred_mode)
464
0
                    {
465
0
                        intra_pred_mode_chroma = INTRA_ANGULAR(34);
466
0
                    }
467
0
                }
468
0
                if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
469
0
                {
470
0
                    intra_pred_mode_chroma = gau1_intra_pred_chroma_modes_422[intra_pred_mode_chroma];
471
0
                }
472
0
                if(log2_trafo_size > 2 || ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
473
0
                {
474
0
                    WORD32 trafo_offset = (ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444 ? 0 : 1);
475
0
                    WORD32 log2_trafo_size_c = MAX(2, log2_trafo_size - trafo_offset);
476
477
0
#ifdef ENABLE_MAIN_REXT_PROFILE
478
0
                    if(ps_pps->i1_cross_component_prediction_enabled_flag
479
0
                                    && ps_codec->s_parse.s_cu.i1_cbf_luma
480
0
                                    && (ps_codec->s_parse.s_cu.i4_pred_mode == PRED_MODE_INTER
481
0
                                                    || chroma_intra_pred_mode_idx == 4))
482
0
                    {
483
0
                        ctxt_idx = IHEVC_CAB_CCP_LOG2_RES_ABS;
484
0
                        TRACE_CABAC_CTXT("log2_res_scale_abs_plus1", ps_cabac->u4_range, ctxt_idx);
485
0
                        value = ihevcd_cabac_decode_bins_tunary(ps_cabac, ps_bitstrm, 4, ctxt_idx,
486
0
                                                                0, 3);
487
0
                        AEV_TRACE("log2_res_scale_abs_plus1", value, ps_cabac->u4_range);
488
489
0
                        if(value != 0)
490
0
                        {
491
0
                            ctxt_idx = IHEVC_CAB_CCP_RES_SIGN_FLAG;
492
0
                            TRACE_CABAC_CTXT("res_scale_sign_flag", ps_cabac->u4_range, ctxt_idx);
493
0
                            ps_tu->b1_cb_log2_res_sign = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
494
0
                            AEV_TRACE("res_scale_sign_flag", value, ps_cabac->u4_range);
495
0
                            ps_tu->b3_cb_log2_res_scale_abs_plus1 = value;
496
0
                        }
497
0
                    }
498
0
#endif
499
0
                    if(ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth])
500
0
                    {
501
0
                        ps_tu->b1_cb_cbf = 1;
502
0
                        ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size_c, 1, intra_pred_mode_chroma);
503
0
                    }
504
0
#ifdef ENABLE_MAIN_REXT_PROFILE
505
0
                    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422 && ps_codec->s_parse.s_cu.ai1_cbf_cb_subtu[trafo_depth])
506
0
                    {
507
0
                        ps_tu->b1_cb_cbf_subtu1 = 1;
508
0
                        ihevcd_parse_residual_coding(ps_codec, x0, y0 + (1 << log2_trafo_size_c), log2_trafo_size_c, 1, intra_pred_mode_chroma);
509
0
                    }
510
0
#endif
511
0
#ifdef ENABLE_MAIN_REXT_PROFILE
512
0
                    if(ps_pps->i1_cross_component_prediction_enabled_flag
513
0
                                    && ps_codec->s_parse.s_cu.i1_cbf_luma
514
0
                                    && (ps_codec->s_parse.s_cu.i4_pred_mode == PRED_MODE_INTER
515
0
                                                    || chroma_intra_pred_mode_idx == 4))
516
0
                    {
517
0
                        ctxt_idx = IHEVC_CAB_CCP_LOG2_RES_ABS + 4;
518
0
                        TRACE_CABAC_CTXT("log2_res_scale_abs_plus1", ps_cabac->u4_range, ctxt_idx);
519
0
                        value = ihevcd_cabac_decode_bins_tunary(ps_cabac, ps_bitstrm, 4, ctxt_idx,
520
0
                                                                0, 3);
521
0
                        AEV_TRACE("log2_res_scale_abs_plus1", value, ps_cabac->u4_range);
522
523
0
                        if(value != 0)
524
0
                        {
525
0
                            ctxt_idx = IHEVC_CAB_CCP_RES_SIGN_FLAG + 1;
526
0
                            TRACE_CABAC_CTXT("res_scale_sign_flag", ps_cabac->u4_range, ctxt_idx);
527
0
                            ps_tu->b1_cr_log2_res_sign = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
528
0
                            AEV_TRACE("res_scale_sign_flag", value, ps_cabac->u4_range);
529
0
                            ps_tu->b3_cr_log2_res_scale_abs_plus1 = value;
530
0
                        }
531
0
                    }
532
0
#endif
533
0
                    if(ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth])
534
0
                    {
535
0
                        ps_tu->b1_cr_cbf = 1;
536
0
                        ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size_c, 2, intra_pred_mode_chroma);
537
0
                    }
538
0
#ifdef ENABLE_MAIN_REXT_PROFILE
539
0
                    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422 && ps_codec->s_parse.s_cu.ai1_cbf_cr_subtu[trafo_depth])
540
0
                    {
541
0
                        ps_tu->b1_cr_cbf_subtu1 = 1;
542
0
                        ihevcd_parse_residual_coding(ps_codec, x0, y0 + (1 << log2_trafo_size_c), log2_trafo_size_c, 2, intra_pred_mode_chroma);
543
0
                    }
544
0
#endif
545
0
                }
546
0
                else if(blk_idx == 3)
547
0
                {
548
0
                    if(ps_codec->s_parse.s_cu.ai1_cbf_cb[trafo_depth])
549
0
                    {
550
0
                        ps_tu->b1_cb_cbf = 1;
551
0
                        ihevcd_parse_residual_coding(ps_codec, cu_x_base, cu_y_base, log2_trafo_size, 1, intra_pred_mode_chroma);
552
0
                    }
553
0
#ifdef ENABLE_MAIN_REXT_PROFILE
554
0
                    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422 && ps_codec->s_parse.s_cu.ai1_cbf_cb_subtu[trafo_depth])
555
0
                    {
556
0
                        ps_tu->b1_cb_cbf_subtu1 = 1;
557
0
                        ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size, 1, intra_pred_mode_chroma);
558
0
                    }
559
0
#endif
560
561
0
                    if(ps_codec->s_parse.s_cu.ai1_cbf_cr[trafo_depth])
562
0
                    {
563
0
                        ps_tu->b1_cr_cbf = 1;
564
0
                        ihevcd_parse_residual_coding(ps_codec, cu_x_base, cu_y_base, log2_trafo_size, 2, intra_pred_mode_chroma);
565
0
                    }
566
0
#ifdef ENABLE_MAIN_REXT_PROFILE
567
0
                    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422 && ps_codec->s_parse.s_cu.ai1_cbf_cr_subtu[trafo_depth])
568
0
                    {
569
0
                        ps_tu->b1_cr_cbf_subtu1 = 1;
570
0
                        ihevcd_parse_residual_coding(ps_codec, x0, y0, log2_trafo_size, 2, intra_pred_mode_chroma);
571
0
                    }
572
0
#endif
573
0
                }
574
0
                else
575
0
                {
576
                    //ps_tu->b1_chroma_present = 0;
577
0
                    ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE;
578
0
                }
579
0
            }
580
0
            else
581
0
            {
582
0
                if((3 != blk_idx) && (2 == log2_trafo_size && ps_sps->i1_chroma_format_idc != CHROMA_FMT_IDC_YUV444))
583
0
                {
584
0
                    ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE;
585
0
                }
586
0
            }
587
588
            /* Set the first TU in CU flag */
589
0
            {
590
0
                if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) &&
591
0
                                (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2))
592
0
                {
593
0
                    ps_tu->b1_first_tu_in_cu = 1;
594
0
                }
595
0
                else
596
0
                {
597
0
                    ps_tu->b1_first_tu_in_cu = 0;
598
0
                }
599
0
            }
600
0
            ps_codec->s_parse.ps_tu++;
601
0
            ps_codec->s_parse.s_cu.i4_tu_cnt++;
602
0
            ps_codec->s_parse.i4_pic_tu_idx++;
603
0
        }
604
0
    }
605
0
    return ret;
606
0
}
607
/**
608
 *******************************************************************************
609
 *
610
 * @brief
611
 *  Parses Motion vector difference
612
 *
613
 * @par Description:
614
 *  Parses Motion vector difference as per Section:7.3.9.9
615
 *
616
 * @param[in] ps_codec
617
 *  Pointer to codec context
618
 *
619
 * @returns  Error from IHEVCD_ERROR_T
620
 *
621
 * @remarks
622
 *
623
 *
624
 *******************************************************************************
625
 */
626
IHEVCD_ERROR_T ihevcd_parse_mvd(codec_t *ps_codec, mv_t *ps_mv)
627
0
{
628
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
629
0
    WORD32 value;
630
0
    WORD32 abs_mvd;
631
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
632
0
    WORD32 abs_mvd_greater0_flag[2];
633
0
    WORD32 abs_mvd_greater1_flag[2];
634
0
    WORD32 ctxt_idx;
635
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
636
637
638
0
    ctxt_idx  = IHEVC_CAB_MVD_GRT0;
639
    /* encode absmvd_x > 0 */
640
0
    TRACE_CABAC_CTXT("abs_mvd_greater0_flag[0]", ps_cabac->u4_range, ctxt_idx);
641
0
    abs_mvd_greater0_flag[0] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
642
0
    AEV_TRACE("abs_mvd_greater0_flag[0]", abs_mvd_greater0_flag[0], ps_cabac->u4_range);
643
644
    /* encode absmvd_y > 0 */
645
0
    TRACE_CABAC_CTXT("abs_mvd_greater0_flag[1]", ps_cabac->u4_range, ctxt_idx);
646
0
    abs_mvd_greater0_flag[1] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
647
0
    AEV_TRACE("abs_mvd_greater0_flag[1]", abs_mvd_greater0_flag[1], ps_cabac->u4_range);
648
649
0
    ctxt_idx  = IHEVC_CAB_MVD_GRT1;
650
0
    abs_mvd_greater1_flag[0] = 0;
651
0
    abs_mvd_greater1_flag[1] = 0;
652
653
0
    if(abs_mvd_greater0_flag[0])
654
0
    {
655
0
        TRACE_CABAC_CTXT("abs_mvd_greater1_flag[0]", ps_cabac->u4_range, ctxt_idx);
656
0
        abs_mvd_greater1_flag[0] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
657
0
        AEV_TRACE("abs_mvd_greater1_flag[0]", abs_mvd_greater1_flag[0], ps_cabac->u4_range);
658
0
    }
659
0
    if(abs_mvd_greater0_flag[1])
660
0
    {
661
0
        TRACE_CABAC_CTXT("abs_mvd_greater1_flag[1]", ps_cabac->u4_range, ctxt_idx);
662
0
        abs_mvd_greater1_flag[1] = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
663
0
        AEV_TRACE("abs_mvd_greater1_flag[1]", abs_mvd_greater1_flag[1], ps_cabac->u4_range);
664
0
    }
665
0
    abs_mvd = 0;
666
0
    if(abs_mvd_greater0_flag[0])
667
0
    {
668
0
        abs_mvd = 1;
669
0
        if(abs_mvd_greater1_flag[0])
670
0
        {
671
0
            value = ihevcd_cabac_decode_bypass_bins_egk(ps_cabac, ps_bitstrm, 1);
672
0
            AEV_TRACE("abs_mvd_minus2[0]", value, ps_cabac->u4_range);
673
0
            abs_mvd = value + 2;
674
0
        }
675
0
        value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm);
676
0
        AEV_TRACE("mvd_sign_flag[0]", value, ps_cabac->u4_range);
677
0
        if(value)
678
0
        {
679
0
            abs_mvd = -abs_mvd;
680
0
        }
681
682
0
    }
683
0
    ps_mv->i2_mvx = abs_mvd;
684
0
    abs_mvd = 0;
685
0
    if(abs_mvd_greater0_flag[1])
686
0
    {
687
0
        abs_mvd = 1;
688
0
        if(abs_mvd_greater1_flag[1])
689
0
        {
690
0
            value = ihevcd_cabac_decode_bypass_bins_egk(ps_cabac, ps_bitstrm, 1);
691
0
            AEV_TRACE("abs_mvd_minus2[1]", value, ps_cabac->u4_range);
692
0
            abs_mvd = value + 2;
693
694
0
        }
695
0
        value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm);
696
0
        AEV_TRACE("mvd_sign_flag[1]", value, ps_cabac->u4_range);
697
698
0
        if(value)
699
0
        {
700
0
            abs_mvd = -abs_mvd;
701
0
        }
702
0
    }
703
0
    ps_mv->i2_mvy = abs_mvd;
704
705
0
    return ret;
706
0
}
707
708
/**
709
 *******************************************************************************
710
 *
711
 * @brief
712
 *  Parses PCM sample
713
 *
714
 *
715
 * @par Description:
716
 *  Parses PCM sample as per Section:7.3.9.7 Pcm sample syntax
717
 *
718
 * @param[in] ps_codec
719
 *  Pointer to codec context
720
 *
721
 * @returns  Error from IHEVCD_ERROR_T
722
 *
723
 * @remarks
724
 *
725
 *
726
 *******************************************************************************
727
 */
728
729
IHEVCD_ERROR_T  ihevcd_parse_pcm_sample(codec_t *ps_codec,
730
                                        WORD32 x0,
731
                                        WORD32 y0,
732
                                        WORD32 log2_cb_size)
733
0
{
734
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
735
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
736
0
    sps_t *ps_sps;
737
738
0
    WORD32 value;
739
0
    WORD32 i;
740
741
0
    WORD32 num_bits;
742
0
    UWORD32 u4_sig_coeff_map;
743
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
744
0
    tu_t *ps_tu = ps_codec->s_parse.ps_tu;
745
0
    tu_sblk_coeff_data_t *ps_tu_sblk_coeff_data;
746
0
    UWORD8 *pu1_coeff_data;
747
0
    ps_sps = ps_codec->s_parse.ps_sps;
748
749
0
    UNUSED(value);
750
0
    UNUSED(ps_tu);
751
0
    UNUSED(ps_cabac);
752
0
    UNUSED(x0);
753
0
    UNUSED(y0);
754
755
0
    {
756
0
        WORD8 *pi1_scan_idx;
757
0
        WORD8 *pi1_buf = (WORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
758
0
        WORD8 *pi1_num_coded_subblks;
759
760
        /* First WORD8 gives number of coded subblocks */
761
0
        pi1_num_coded_subblks = pi1_buf++;
762
763
        /* Set number of coded subblocks in the current TU to zero */
764
        /* For PCM there will be only one subblock which is the same size as CU */
765
0
        *pi1_num_coded_subblks = 1;
766
767
        /* Second WORD8 gives (scan idx << 1) | trans_skip */
768
0
        pi1_scan_idx = pi1_buf++;
769
0
        *pi1_scan_idx = (0 << 1) | 1;
770
771
        /* Store the incremented pointer in pv_tu_coeff_data */
772
0
        ps_codec->s_parse.pv_tu_coeff_data = pi1_buf;
773
774
0
    }
775
776
0
    u4_sig_coeff_map = 0xFFFFFFFF;
777
0
    ps_tu_sblk_coeff_data = (tu_sblk_coeff_data_t *)ps_codec->s_parse.pv_tu_coeff_data;
778
0
    ps_tu_sblk_coeff_data->u2_sig_coeff_map = u4_sig_coeff_map;
779
0
    ps_tu_sblk_coeff_data->u2_subblk_pos = 0;
780
781
0
    pu1_coeff_data = (UWORD8 *)&ps_tu_sblk_coeff_data->ai2_level[0];
782
783
0
    num_bits = ps_sps->i1_pcm_sample_bit_depth_luma;
784
785
0
    WORD32 luma_samples = 1 << (log2_cb_size << 1);
786
0
    for(i = 0; i < luma_samples; i++)
787
0
    {
788
0
        TRACE_CABAC_CTXT("pcm_sample_luma", ps_cabac->u4_range, 0);
789
0
        BITS_PARSE("pcm_sample_luma", value, ps_bitstrm, num_bits);
790
791
        //ps_pcmsample_t->i1_pcm_sample_luma[i] = value;
792
0
        *pu1_coeff_data++ = value << (BIT_DEPTH_LUMA - num_bits);
793
0
    }
794
795
0
    if(CHROMA_FMT_IDC_MONOCHROME != ps_sps->i1_chroma_format_idc)
796
0
    {
797
0
        WORD32 chroma_samples = 0;
798
799
0
        if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
800
0
            chroma_samples = luma_samples << 1;
801
0
        else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
802
0
            chroma_samples = luma_samples;
803
0
        else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420)
804
0
            chroma_samples = luma_samples >> 1;
805
0
        num_bits = ps_sps->i1_pcm_sample_bit_depth_chroma;
806
0
        for(i = 0; i < chroma_samples; i++)
807
0
        {
808
0
            TRACE_CABAC_CTXT("pcm_sample_chroma", ps_cabac->u4_range, 0);
809
0
            BITS_PARSE("pcm_sample_chroma", value, ps_bitstrm, num_bits);
810
811
            // ps_pcmsample_t->i1_pcm_sample_chroma[i] = value;
812
0
            *pu1_coeff_data++ = value << (BIT_DEPTH_CHROMA - num_bits);
813
0
        }
814
0
    }
815
816
0
    ps_codec->s_parse.pv_tu_coeff_data = pu1_coeff_data;
817
818
0
    return ret;
819
0
}
820
/**
821
 *******************************************************************************
822
 *
823
 * @brief
824
 *  Parses Prediction unit
825
 *
826
 * @par Description:
827
 *  Parses Prediction unit as per Section:7.3.9.6
828
 *
829
 * @param[in] ps_codec
830
 *  Pointer to codec context
831
 *
832
 * @returns  Error from IHEVCD_ERROR_T
833
 *
834
 * @remarks
835
 *
836
 *
837
 *******************************************************************************
838
 */
839
840
IHEVCD_ERROR_T  ihevcd_parse_pu_mvp(codec_t *ps_codec, pu_t *ps_pu)
841
0
{
842
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
843
0
    WORD32 value;
844
0
    slice_header_t *ps_slice_hdr;
845
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
846
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
847
0
    WORD32 inter_pred_idc;
848
849
0
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
850
851
0
    if(ps_slice_hdr->i1_slice_type == BSLICE)
852
0
    {
853
0
        WORD32 pu_w_plus_pu_h;
854
0
        WORD32 ctxt_idx;
855
        /* required to check if w+h==12 case */
856
0
        pu_w_plus_pu_h = ((ps_pu->b4_wd + 1) << 2) + ((ps_pu->b4_ht + 1) << 2);
857
0
        if(12 == pu_w_plus_pu_h)
858
0
        {
859
0
            ctxt_idx = IHEVC_CAB_INTER_PRED_IDC + 4;
860
0
            TRACE_CABAC_CTXT("inter_pred_idc", ps_cabac->u4_range, ctxt_idx);
861
0
            inter_pred_idc = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm,
862
0
                                                     ctxt_idx);
863
0
        }
864
0
        else
865
0
        {
866
            /* larger PUs can be encoded as bi_pred/l0/l1 inter_pred_idc */
867
0
            WORD32 is_bipred;
868
869
0
            ctxt_idx = IHEVC_CAB_INTER_PRED_IDC + ps_codec->s_parse.i4_ct_depth;
870
0
            TRACE_CABAC_CTXT("inter_pred_idc", ps_cabac->u4_range, ctxt_idx);
871
0
            is_bipred = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
872
0
            inter_pred_idc = PRED_BI;
873
0
            if(!is_bipred)
874
0
            {
875
0
                ctxt_idx = IHEVC_CAB_INTER_PRED_IDC + 4;
876
0
                inter_pred_idc = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm,
877
0
                                                         ctxt_idx);
878
0
            }
879
0
        }
880
881
0
        AEV_TRACE("inter_pred_idc", inter_pred_idc, ps_cabac->u4_range);
882
0
    }
883
0
    else
884
0
        inter_pred_idc = PRED_L0;
885
0
    ps_pu->mv.i1_l0_ref_idx = 0;
886
0
    ps_pu->mv.i1_l1_ref_idx = 0;
887
    /* Decode MVD for L0 for PRED_L0 or PRED_BI */
888
0
    if(inter_pred_idc != PRED_L1)
889
0
    {
890
0
        WORD32 active_refs = ps_slice_hdr->i1_num_ref_idx_l0_active;
891
0
        WORD32 ref_idx = 0;
892
0
        WORD32 ctxt_idx;
893
894
0
        if(active_refs > 1)
895
0
        {
896
0
            ctxt_idx = IHEVC_CAB_INTER_REF_IDX;
897
            /* encode the context modelled first bin */
898
0
            TRACE_CABAC_CTXT("ref_idx", ps_cabac->u4_range, ctxt_idx);
899
0
            ref_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
900
901
0
            if((active_refs > 2) && ref_idx)
902
0
            {
903
0
                WORD32 value;
904
                /* encode the context modelled second bin */
905
0
                ctxt_idx++;
906
0
                value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
907
0
                ref_idx += value;
908
0
                if((active_refs > 3) && value)
909
0
                {
910
                    /* encode remaining bypass bins */
911
0
                    ref_idx = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac,
912
0
                                                                     ps_bitstrm,
913
0
                                                                     (active_refs - 3)
914
0
                    );
915
0
                    ref_idx += 2;
916
0
                }
917
0
            }
918
0
            AEV_TRACE("ref_idx", ref_idx, ps_cabac->u4_range);
919
0
        }
920
921
0
        ref_idx = CLIP3(ref_idx, 0, MAX_DPB_SIZE - 1);
922
0
        ps_pu->mv.i1_l0_ref_idx = ref_idx;
923
924
0
        ihevcd_parse_mvd(ps_codec, &ps_pu->mv.s_l0_mv);
925
926
0
        ctxt_idx = IHEVC_CAB_MVP_L0L1;
927
0
        value = ihevcd_cabac_decode_bin(ps_cabac,
928
0
                                        ps_bitstrm,
929
0
                                        ctxt_idx);
930
931
0
        AEV_TRACE("mvp_l0/l1_flag", value, ps_cabac->u4_range);
932
933
0
        ps_pu->b1_l0_mvp_idx = value;
934
935
0
    }
936
    /* Decode MVD for L1 for PRED_L1 or PRED_BI */
937
0
    if(inter_pred_idc != PRED_L0)
938
0
    {
939
0
        WORD32 active_refs = ps_slice_hdr->i1_num_ref_idx_l1_active;
940
0
        WORD32 ref_idx = 0;
941
0
        WORD32 ctxt_idx;
942
943
0
        if(active_refs > 1)
944
0
        {
945
946
0
            ctxt_idx = IHEVC_CAB_INTER_REF_IDX;
947
0
            TRACE_CABAC_CTXT("ref_idx", ps_cabac->u4_range, ctxt_idx);
948
            /* encode the context modelled first bin */
949
0
            ref_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
950
951
0
            if((active_refs > 2) && ref_idx)
952
0
            {
953
0
                WORD32 value;
954
                /* encode the context modelled second bin */
955
0
                ctxt_idx++;
956
0
                value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
957
0
                ref_idx += value;
958
0
                if((active_refs > 3) && value)
959
0
                {
960
                    /* encode remaining bypass bins */
961
0
                    ref_idx = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac,
962
0
                                                                     ps_bitstrm,
963
0
                                                                     (active_refs - 3)
964
0
                    );
965
0
                    ref_idx += 2;
966
0
                }
967
0
            }
968
969
0
            AEV_TRACE("ref_idx", ref_idx, ps_cabac->u4_range);
970
0
        }
971
972
0
        ref_idx = CLIP3(ref_idx, 0, MAX_DPB_SIZE - 1);
973
0
        ps_pu->mv.i1_l1_ref_idx = ref_idx;
974
975
0
        if(ps_slice_hdr->i1_mvd_l1_zero_flag && inter_pred_idc == PRED_BI)
976
0
        {
977
0
            ps_pu->mv.s_l1_mv.i2_mvx = 0;
978
0
            ps_pu->mv.s_l1_mv.i2_mvy = 0;
979
0
        }
980
0
        else
981
0
        {
982
0
            ihevcd_parse_mvd(ps_codec, &ps_pu->mv.s_l1_mv);
983
0
        }
984
985
0
        ctxt_idx = IHEVC_CAB_MVP_L0L1;
986
0
        value = ihevcd_cabac_decode_bin(ps_cabac,
987
0
                                        ps_bitstrm,
988
0
                                        ctxt_idx);
989
990
0
        AEV_TRACE("mvp_l0/l1_flag", value, ps_cabac->u4_range);
991
0
        ps_pu->b1_l1_mvp_idx = value;
992
993
0
    }
994
995
0
    ps_pu->b2_pred_mode = inter_pred_idc;
996
0
    return ret;
997
0
}
998
/**
999
 *******************************************************************************
1000
 *
1001
 * @brief
1002
 *  Parses Prediction unit
1003
 *
1004
 * @par Description:
1005
 *  Parses Prediction unit as per Section:7.3.9.6
1006
 *
1007
 * @param[in] ps_codec
1008
 *  Pointer to codec context
1009
 *
1010
 * @returns  Error from IHEVCD_ERROR_T
1011
 *
1012
 * @remarks
1013
 *
1014
 *
1015
 *******************************************************************************
1016
 */
1017
1018
IHEVCD_ERROR_T  ihevcd_parse_prediction_unit(codec_t *ps_codec,
1019
                                             WORD32 x0,
1020
                                             WORD32 y0,
1021
                                             WORD32 wd,
1022
                                             WORD32 ht)
1023
0
{
1024
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
1025
0
    slice_header_t *ps_slice_hdr;
1026
0
    sps_t *ps_sps;
1027
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
1028
0
    WORD32 ctb_x_base;
1029
0
    WORD32 ctb_y_base;
1030
1031
0
    pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1032
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
1033
1034
0
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1035
1036
    /* Set PU structure to default values */
1037
0
    memset(ps_pu, 0, sizeof(pu_t));
1038
1039
0
    ps_sps = ps_codec->s_parse.ps_sps;
1040
0
    ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size;
1041
0
    ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size;
1042
1043
0
    ps_pu->b4_pos_x = (x0 - ctb_x_base) >> 2;
1044
0
    ps_pu->b4_pos_y = (y0 - ctb_y_base) >> 2;
1045
0
    ps_pu->b4_wd = (wd >> 2) - 1;
1046
0
    ps_pu->b4_ht = (ht >> 2) - 1;
1047
1048
0
    ps_pu->b1_intra_flag = 0;
1049
0
    ps_pu->b3_part_mode = ps_codec->s_parse.s_cu.i4_part_mode;
1050
1051
0
    if(PRED_MODE_SKIP == ps_codec->s_parse.s_cu.i4_pred_mode)
1052
0
    {
1053
0
        WORD32 merge_idx = 0;
1054
0
        if(ps_slice_hdr->i1_max_num_merge_cand > 1)
1055
0
        {
1056
0
            WORD32 ctxt_idx = IHEVC_CAB_MERGE_IDX_EXT;
1057
0
            WORD32 bin;
1058
1059
0
            TRACE_CABAC_CTXT("merge_idx", ps_cabac->u4_range, ctxt_idx);
1060
0
            bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
1061
0
            if(bin)
1062
0
            {
1063
0
                if(ps_slice_hdr->i1_max_num_merge_cand > 2)
1064
0
                {
1065
0
                    merge_idx = ihevcd_cabac_decode_bypass_bins_tunary(
1066
0
                                    ps_cabac, ps_bitstrm,
1067
0
                                    (ps_slice_hdr->i1_max_num_merge_cand - 2));
1068
0
                }
1069
0
                merge_idx++;
1070
0
            }
1071
0
            AEV_TRACE("merge_idx", merge_idx, ps_cabac->u4_range);
1072
0
        }
1073
0
        ps_pu->b1_merge_flag = 1;
1074
0
        ps_pu->b3_merge_idx = merge_idx;
1075
1076
0
    }
1077
0
    else
1078
0
    {
1079
        /* MODE_INTER */
1080
0
        WORD32 merge_flag;
1081
0
        WORD32 ctxt_idx = IHEVC_CAB_MERGE_FLAG_EXT;
1082
0
        TRACE_CABAC_CTXT("merge_flag", ps_cabac->u4_range, ctxt_idx);
1083
0
        merge_flag = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
1084
0
        AEV_TRACE("merge_flag", merge_flag, ps_cabac->u4_range);
1085
1086
0
        ps_pu->b1_merge_flag = merge_flag;
1087
1088
0
        if(merge_flag)
1089
0
        {
1090
0
            WORD32 merge_idx = 0;
1091
0
            if(ps_slice_hdr->i1_max_num_merge_cand > 1)
1092
0
            {
1093
0
                WORD32 ctxt_idx = IHEVC_CAB_MERGE_IDX_EXT;
1094
0
                WORD32 bin;
1095
0
                TRACE_CABAC_CTXT("merge_idx", ps_cabac->u4_range, ctxt_idx);
1096
0
                bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
1097
0
                if(bin)
1098
0
                {
1099
0
                    if(ps_slice_hdr->i1_max_num_merge_cand > 2)
1100
0
                    {
1101
0
                        merge_idx = ihevcd_cabac_decode_bypass_bins_tunary(
1102
0
                                        ps_cabac, ps_bitstrm,
1103
0
                                        (ps_slice_hdr->i1_max_num_merge_cand - 2));
1104
0
                    }
1105
0
                    merge_idx++;
1106
0
                }
1107
0
                AEV_TRACE("merge_idx", merge_idx, ps_cabac->u4_range);
1108
0
            }
1109
1110
0
            ps_pu->b3_merge_idx = merge_idx;
1111
0
        }
1112
0
        else
1113
0
        {
1114
0
            ihevcd_parse_pu_mvp(ps_codec, ps_pu);
1115
0
        }
1116
1117
0
    }
1118
0
    STATS_UPDATE_PU_SIZE(ps_pu);
1119
    /* Increment PU pointer */
1120
0
    ps_codec->s_parse.ps_pu++;
1121
0
    ps_codec->s_parse.i4_pic_pu_idx++;
1122
0
    return ret;
1123
0
}
1124
1125
1126
WORD32 ihevcd_parse_part_mode_amp(cab_ctxt_t *ps_cabac, bitstrm_t *ps_bitstrm)
1127
0
{
1128
0
    WORD32 ctxt_idx = IHEVC_CAB_PART_MODE;
1129
0
    WORD32 part_mode_idx;
1130
0
    WORD32 part_mode;
1131
0
    WORD32 bin;
1132
1133
0
    part_mode = 0;
1134
0
    TRACE_CABAC_CTXT("part_mode", ps_cabac->u4_range, ctxt_idx);
1135
0
    bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx++);
1136
1137
0
    if(!bin)
1138
0
    {
1139
0
        bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx++);
1140
0
        part_mode_idx = bin;
1141
0
        part_mode_idx <<= 1;
1142
1143
        /* Following takes of handling context increment for 3rd bin in part_mode */
1144
        /* When AMP is enabled and the current is not min CB */
1145
        /* Context for 3rd bin is 3 and not 2 */
1146
0
        ctxt_idx += 1;
1147
1148
0
        bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
1149
0
        part_mode_idx |= bin;
1150
1151
0
        part_mode_idx <<= 1;
1152
0
        if(!bin)
1153
0
        {
1154
1155
0
            bin = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm);
1156
0
            part_mode_idx |= bin;
1157
0
        }
1158
0
        part_mode = gau1_part_mode_amp[part_mode_idx];
1159
0
    }
1160
0
    return part_mode;
1161
0
}
1162
IHEVCD_ERROR_T ihevcd_parse_coding_unit_intra(codec_t *ps_codec,
1163
                                              WORD32 x0,
1164
                                              WORD32 y0,
1165
                                              WORD32 log2_cb_size)
1166
0
{
1167
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
1168
0
    sps_t *ps_sps;
1169
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
1170
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
1171
0
    WORD32 pcm_flag;
1172
0
    WORD32 value;
1173
0
    WORD32 cb_size = 1 << log2_cb_size;
1174
0
    WORD32 part_mode =  ps_codec->s_parse.s_cu.i4_part_mode;
1175
0
    tu_t *ps_tu = ps_codec->s_parse.ps_tu;
1176
0
    pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1177
0
    WORD32 ctb_x_base;
1178
0
    WORD32 ctb_y_base;
1179
0
    ps_sps = ps_codec->s_parse.ps_sps;
1180
0
    ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size;
1181
0
    ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size;
1182
1183
0
    memset(ps_pu, 0, sizeof(pu_t));
1184
0
    ps_pu->b1_intra_flag = 1;
1185
0
    ps_pu->b4_wd = (cb_size >> 2) - 1;
1186
0
    ps_pu->b4_ht = (cb_size >> 2) - 1;
1187
0
    ps_pu->b4_pos_x = (x0 - ctb_x_base) >> 2;
1188
0
    ps_pu->b4_pos_y = (y0 - ctb_y_base) >> 2;
1189
1190
0
    pcm_flag = 0;
1191
0
    if((PART_2Nx2N == part_mode) && (ps_sps->i1_pcm_enabled_flag)
1192
0
                    && (log2_cb_size
1193
0
                                    >= ps_sps->i1_log2_min_pcm_coding_block_size)
1194
0
                    && (log2_cb_size
1195
0
                                    <= (ps_sps->i1_log2_min_pcm_coding_block_size + ps_sps->i1_log2_diff_max_min_pcm_coding_block_size)))
1196
0
    {
1197
0
        TRACE_CABAC_CTXT("pcm_flag", ps_cabac->u4_range, 0);
1198
0
        pcm_flag = ihevcd_cabac_decode_terminate(ps_cabac, ps_bitstrm);
1199
0
        AEV_TRACE("pcm_flag", pcm_flag, ps_cabac->u4_range);
1200
0
    }
1201
1202
0
    ps_codec->s_parse.i4_cu_pcm_flag = pcm_flag;
1203
0
    if(pcm_flag)
1204
0
    {
1205
0
        UWORD8 *pu1_luma_intra_pred_mode_top, *pu1_luma_intra_pred_mode_left;
1206
0
        WORD32 i,  num_pred_blocks;
1207
1208
0
        if(ps_codec->s_parse.s_bitstrm.u4_bit_ofst % 8)
1209
0
        {
1210
0
            TRACE_CABAC_CTXT("pcm_alignment_zero_bit", ps_cabac->u4_range, 0);
1211
0
            ihevcd_bits_flush_to_byte_boundary(&ps_codec->s_parse.s_bitstrm);
1212
0
            AEV_TRACE("pcm_alignment_zero_bit", 0, ps_cabac->u4_range);
1213
0
        }
1214
1215
0
        ihevcd_parse_pcm_sample(ps_codec, x0, y0, log2_cb_size);
1216
1217
0
        ihevcd_cabac_reset(&ps_codec->s_parse.s_cabac,
1218
0
                           &ps_codec->s_parse.s_bitstrm);
1219
1220
0
        ps_tu = ps_codec->s_parse.ps_tu;
1221
0
        ps_tu->b1_cb_cbf = 1;
1222
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1223
0
        ps_tu->b1_cb_cbf_subtu1 = 1;
1224
0
#endif
1225
0
        ps_tu->b1_cr_cbf = 1;
1226
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1227
0
        ps_tu->b1_cr_cbf_subtu1 = 1;
1228
0
#endif
1229
0
        ps_tu->b1_y_cbf = 1;
1230
0
        ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2);
1231
0
        ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2);
1232
0
        ps_tu->b1_transquant_bypass = 1;
1233
0
        ps_tu->b3_size = (log2_cb_size - 2);
1234
0
        ps_tu->b7_qp = ps_codec->s_parse.u4_qp;
1235
0
        ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE;
1236
0
        ps_tu->b6_luma_intra_mode   = INTRA_PRED_NONE;
1237
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1238
0
        ps_tu->b3_cb_log2_res_scale_abs_plus1 = 0;
1239
0
        ps_tu->b1_cb_log2_res_sign = 0;
1240
0
        ps_tu->b3_cr_log2_res_scale_abs_plus1 = 0;
1241
0
        ps_tu->b1_cr_log2_res_sign = 0;
1242
0
#endif
1243
1244
        /* Set the first TU in CU flag */
1245
0
        {
1246
0
            if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) &&
1247
0
                            (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2))
1248
0
            {
1249
0
                ps_tu->b1_first_tu_in_cu = 1;
1250
0
            }
1251
0
            else
1252
0
            {
1253
0
                ps_tu->b1_first_tu_in_cu = 0;
1254
0
            }
1255
0
        }
1256
1257
        /* Update the intra pred mode for PCM to INTRA_DC(default mode) */
1258
0
        pu1_luma_intra_pred_mode_top = ps_codec->s_parse.pu1_luma_intra_pred_mode_top
1259
0
                        + (ps_codec->s_parse.s_cu.i4_pos_x * 2);
1260
1261
0
        pu1_luma_intra_pred_mode_left = ps_codec->s_parse.pu1_luma_intra_pred_mode_left
1262
0
                        + (ps_codec->s_parse.s_cu.i4_pos_y * 2);
1263
1264
0
        num_pred_blocks = 1; /* Because PCM part mode will be 2Nx2N */
1265
1266
0
        memset(pu1_luma_intra_pred_mode_left, INTRA_DC, (cb_size / num_pred_blocks) / MIN_PU_SIZE);
1267
0
        memset(pu1_luma_intra_pred_mode_top, INTRA_DC, (cb_size / num_pred_blocks) / MIN_PU_SIZE);
1268
1269
1270
        /* Set no_loop_filter appropriately */
1271
0
        if(1 == ps_sps->i1_pcm_loop_filter_disable_flag)
1272
0
        {
1273
0
            UWORD8 *pu1_pic_no_loop_filter_flag;
1274
0
            WORD32 numbytes_row;
1275
0
            UWORD32 u4_mask;
1276
1277
0
            pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1278
0
            numbytes_row =  (ps_sps->i2_pic_width_in_luma_samples + 63) / 64;
1279
0
            pu1_pic_no_loop_filter_flag += (y0 / 8) * numbytes_row;
1280
0
            pu1_pic_no_loop_filter_flag += (x0 / 64);
1281
            /* Generate (cb_size / 8) number of 1s */
1282
            /* i.e (log2_cb_size - 2) number of 1s */
1283
0
            u4_mask = LSB_ONES((cb_size >> 3));
1284
0
            for(i = 0; i < (cb_size / 8); i++)
1285
0
            {
1286
0
                *pu1_pic_no_loop_filter_flag |= (u4_mask << (((x0) / 8) % 8));
1287
0
                pu1_pic_no_loop_filter_flag += numbytes_row;
1288
0
            }
1289
0
        }
1290
        /* Increment ps_tu and tu_idx */
1291
0
        ps_codec->s_parse.ps_tu++;
1292
0
        ps_codec->s_parse.s_cu.i4_tu_cnt++;
1293
0
        ps_codec->s_parse.i4_pic_tu_idx++;
1294
1295
0
    }
1296
0
    else
1297
0
    {
1298
0
        WORD32 cnt = 0;
1299
0
        WORD32 i;
1300
0
        WORD32 part_cnt;
1301
1302
0
        part_cnt = (part_mode == PART_NxN) ? 4 : 1;
1303
1304
0
        for(i = 0; i < part_cnt; i++)
1305
0
        {
1306
0
            TRACE_CABAC_CTXT("prev_intra_pred_luma_flag", ps_cabac->u4_range, IHEVC_CAB_INTRA_LUMA_PRED_FLAG);
1307
0
            value = ihevcd_cabac_decode_bin(ps_cabac,
1308
0
                                            ps_bitstrm,
1309
0
                                            IHEVC_CAB_INTRA_LUMA_PRED_FLAG);
1310
1311
0
            ps_codec->s_parse.s_cu.ai4_prev_intra_luma_pred_flag[i] =
1312
0
                            value;
1313
0
            AEV_TRACE("prev_intra_pred_luma_flag", value, ps_cabac->u4_range);
1314
0
        }
1315
1316
0
        for(i = 0; i < part_cnt; i++)
1317
0
        {
1318
0
            if(ps_codec->s_parse.s_cu.ai4_prev_intra_luma_pred_flag[cnt])
1319
0
            {
1320
0
                value = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac, ps_bitstrm, 2);
1321
0
                AEV_TRACE("mpm_idx", value, ps_cabac->u4_range);
1322
0
                ps_codec->s_parse.s_cu.ai4_mpm_idx[cnt] = value;
1323
0
            }
1324
0
            else
1325
0
            {
1326
0
                value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 5);
1327
0
                AEV_TRACE("rem_intra_luma_pred_mode", value,
1328
0
                          ps_cabac->u4_range);
1329
0
                ps_codec->s_parse.s_cu.ai4_rem_intra_luma_pred_mode[cnt] =
1330
0
                                value;
1331
0
            }
1332
0
            cnt++;
1333
0
        }
1334
0
        if(CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc)
1335
0
        {
1336
0
            for(i = 0; i < part_cnt; i++)
1337
0
            {
1338
0
                TRACE_CABAC_CTXT("intra_chroma_pred_mode", ps_cabac->u4_range, IHEVC_CAB_CHROMA_PRED_MODE);
1339
0
                value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm,
1340
0
                                                IHEVC_CAB_CHROMA_PRED_MODE);
1341
0
                ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[i] = 4;
1342
0
                if(value)
1343
0
                {
1344
0
                    ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[i] =
1345
0
                                    ihevcd_cabac_decode_bypass_bins(ps_cabac,
1346
0
                                                                    ps_bitstrm,
1347
0
                                                                    2);
1348
0
                }
1349
0
                AEV_TRACE("intra_chroma_pred_mode",
1350
0
                        ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[i],
1351
0
                        ps_cabac->u4_range);
1352
0
            }
1353
0
        }
1354
0
        else if(CHROMA_FMT_IDC_MONOCHROME != ps_sps->i1_chroma_format_idc)
1355
0
        {
1356
0
            TRACE_CABAC_CTXT("intra_chroma_pred_mode", ps_cabac->u4_range, IHEVC_CAB_CHROMA_PRED_MODE);
1357
0
            value = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm,
1358
0
                    IHEVC_CAB_CHROMA_PRED_MODE);
1359
0
            ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[0] = 4;
1360
0
            if (value) {
1361
0
                ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[0] =
1362
0
                        ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm,
1363
0
                                2);
1364
0
            }
1365
0
            AEV_TRACE("intra_chroma_pred_mode",
1366
0
                    ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[0],
1367
0
                    ps_cabac->u4_range);
1368
1369
0
        }
1370
0
        ihevcd_intra_pred_mode_prediction(ps_codec, log2_cb_size, x0, y0);
1371
1372
0
        if(CHROMA_FMT_IDC_MONOCHROME != ps_sps->i1_chroma_format_idc && part_mode != PART_NxN)
1373
0
        {
1374
            // Only required for YUV444, but done for all formats to simplify calling arguments for ihevcd_parse_transform_tree
1375
0
            parse_cu_t *ps_cu = &ps_codec->s_parse.s_cu;
1376
0
            ps_cu->ai4_intra_chroma_pred_mode_idx[1] = ps_cu->ai4_intra_chroma_pred_mode_idx[0];
1377
0
            ps_cu->ai4_intra_chroma_pred_mode_idx[2] = ps_cu->ai4_intra_chroma_pred_mode_idx[0];
1378
0
            ps_cu->ai4_intra_chroma_pred_mode_idx[3] = ps_cu->ai4_intra_chroma_pred_mode_idx[0];
1379
0
        }
1380
0
    }
1381
0
    STATS_UPDATE_PU_SIZE(ps_pu);
1382
    /* Increment PU pointer */
1383
0
    ps_codec->s_parse.ps_pu++;
1384
0
    ps_codec->s_parse.i4_pic_pu_idx++;
1385
1386
0
    return ret;
1387
0
}
1388
/**
1389
 *******************************************************************************
1390
 *
1391
 * @brief
1392
 *  Parses coding unit
1393
 *
1394
 * @par Description:
1395
 *  Parses coding unit as per Section:7.3.9.5
1396
 *
1397
 * @param[in] ps_codec
1398
 *  Pointer to codec context
1399
 *
1400
 * @returns  Error from IHEVCD_ERROR_T
1401
 *
1402
 * @remarks
1403
 *
1404
 *
1405
 *******************************************************************************
1406
 */
1407
1408
IHEVCD_ERROR_T  ihevcd_parse_coding_unit(codec_t *ps_codec,
1409
                                         WORD32 x0,
1410
                                         WORD32 y0,
1411
                                         WORD32 log2_cb_size)
1412
0
{
1413
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
1414
0
    sps_t *ps_sps;
1415
0
    pps_t *ps_pps;
1416
0
    WORD32 cb_size;
1417
0
    slice_header_t *ps_slice_hdr;
1418
0
    WORD32 skip_flag;
1419
0
    WORD32 pcm_flag;
1420
0
    UWORD32 *pu4_skip_top = ps_codec->s_parse.pu4_skip_cu_top;
1421
0
    UWORD32 u4_skip_left = ps_codec->s_parse.u4_skip_cu_left;
1422
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
1423
0
    tu_t *ps_tu = ps_codec->s_parse.ps_tu;
1424
1425
0
    WORD32 cu_pos_x;
1426
0
    WORD32 cu_pos_y;
1427
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
1428
1429
0
    ASSERT(0 == (x0 % 8));
1430
0
    ASSERT(0 == (y0 % 8));
1431
1432
0
    ps_codec->s_parse.s_cu.i4_tu_cnt = 0;
1433
0
    ps_sps = ps_codec->s_parse.ps_sps;
1434
0
    ps_pps = ps_codec->s_parse.ps_pps;
1435
1436
0
    cu_pos_x = ps_codec->s_parse.s_cu.i4_pos_x;
1437
0
    cu_pos_y = ps_codec->s_parse.s_cu.i4_pos_y;
1438
1439
1440
1441
0
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1442
1443
1444
0
    cb_size = 1 << log2_cb_size;
1445
1446
0
    ps_codec->s_parse.s_cu.i4_cu_transquant_bypass = 0;
1447
1448
0
    if(ps_pps->i1_transquant_bypass_enable_flag)
1449
0
    {
1450
0
        TRACE_CABAC_CTXT("cu_transquant_bypass_flag", ps_cabac->u4_range, IHEVC_CAB_CU_TQ_BYPASS_FLAG);
1451
0
        ps_codec->s_parse.s_cu.i4_cu_transquant_bypass =
1452
0
                        ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm,
1453
0
                                                IHEVC_CAB_CU_TQ_BYPASS_FLAG);
1454
        /* Update transquant_bypass in ps_tu */
1455
1456
0
        AEV_TRACE("cu_transquant_bypass_flag", ps_codec->s_parse.s_cu.i4_cu_transquant_bypass,
1457
0
                  ps_cabac->u4_range);
1458
1459
0
        if(ps_codec->s_parse.s_cu.i4_cu_transquant_bypass)
1460
0
        {
1461
0
            UWORD8 *pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1462
0
            UWORD32 u4_mask;
1463
0
            WORD32 i;
1464
0
            WORD32 numbytes_row;
1465
0
            numbytes_row =  (ps_sps->i2_pic_width_in_luma_samples + 63) / 64;
1466
0
            pu1_pic_no_loop_filter_flag += (y0 / 8) * numbytes_row;
1467
0
            pu1_pic_no_loop_filter_flag += (x0 / 64);
1468
1469
            /* Generate (cb_size / 8) number of 1s */
1470
            /* i.e (log2_cb_size - 2) number of 1s */
1471
0
            u4_mask = LSB_ONES((cb_size >> 3));
1472
0
            for(i = 0; i < (cb_size / 8); i++)
1473
0
            {
1474
0
                *pu1_pic_no_loop_filter_flag |= (u4_mask << (((x0) / 8) % 8));
1475
0
                pu1_pic_no_loop_filter_flag += numbytes_row;
1476
0
            }
1477
0
        }
1478
0
    }
1479
1480
0
    {
1481
0
        UWORD32 u4_skip_top = 0;
1482
0
        UWORD32 u4_mask;
1483
0
        UWORD32 u4_top_mask, u4_left_mask;
1484
0
        UWORD32 u4_min_cu_x = x0 / 8;
1485
0
        UWORD32 u4_min_cu_y = y0 / 8;
1486
1487
0
        pu4_skip_top += (u4_min_cu_x / 32);
1488
1489
1490
0
        if(ps_slice_hdr->i1_slice_type != ISLICE)
1491
0
        {
1492
0
            WORD32 ctx_idx_inc;
1493
0
            ctx_idx_inc = 0;
1494
1495
0
            if((0 != cu_pos_y) ||
1496
0
                            ((0 != ps_codec->s_parse.i4_ctb_slice_y) &&
1497
0
                                            (0 != ps_codec->s_parse.i4_ctb_tile_y)))
1498
0
            {
1499
0
                u4_skip_top = *pu4_skip_top;
1500
0
                u4_skip_top >>= (u4_min_cu_x % 32);
1501
0
                if(u4_skip_top & 1)
1502
0
                    ctx_idx_inc++;
1503
0
            }
1504
1505
            /*****************************************************************/
1506
            /* If cu_pos_x is non-zero then left is available                */
1507
            /* If cu_pos_x is zero then ensure both the following are true   */
1508
            /*    Current CTB is not the first CTB in a tile row             */
1509
            /*    Current CTB is not the first CTB in a slice                */
1510
            /*****************************************************************/
1511
0
            if((0 != cu_pos_x) ||
1512
0
                            (((0 != ps_codec->s_parse.i4_ctb_slice_x) || (0 != ps_codec->s_parse.i4_ctb_slice_y)) &&
1513
0
                                            (0 != ps_codec->s_parse.i4_ctb_tile_x)))
1514
0
            {
1515
0
                u4_skip_left >>= (u4_min_cu_y % 32);
1516
0
                if(u4_skip_left & 1)
1517
0
                    ctx_idx_inc++;
1518
0
            }
1519
0
            TRACE_CABAC_CTXT("cu_skip_flag", ps_cabac->u4_range, (IHEVC_CAB_SKIP_FLAG + ctx_idx_inc));
1520
0
            skip_flag = ihevcd_cabac_decode_bin(ps_cabac,
1521
0
                                                ps_bitstrm,
1522
0
                                                (IHEVC_CAB_SKIP_FLAG + ctx_idx_inc));
1523
1524
0
            AEV_TRACE("cu_skip_flag", skip_flag, ps_cabac->u4_range);
1525
0
        }
1526
0
        else
1527
0
            skip_flag = 0;
1528
1529
        /* Update top skip_flag */
1530
0
        u4_skip_top = *pu4_skip_top;
1531
        /* Since Max cb_size is 64, maximum of 8 bits will be set or reset */
1532
        /* Also since Coding block will be within 64x64 grid, only 8bits within a WORD32
1533
         * need to be updated. These 8 bits will not cross 8 bit boundaries
1534
         */
1535
0
        u4_mask = LSB_ONES(cb_size / 8);
1536
0
        u4_top_mask = u4_mask << (u4_min_cu_x % 32);
1537
1538
1539
0
        if(skip_flag)
1540
0
        {
1541
0
            u4_skip_top |= u4_top_mask;
1542
0
        }
1543
0
        else
1544
0
        {
1545
0
            u4_skip_top &= ~u4_top_mask;
1546
0
        }
1547
0
        *pu4_skip_top = u4_skip_top;
1548
1549
        /* Update left skip_flag */
1550
0
        u4_skip_left = ps_codec->s_parse.u4_skip_cu_left;
1551
0
        u4_mask = LSB_ONES(cb_size / 8);
1552
0
        u4_left_mask = u4_mask << (u4_min_cu_y % 32);
1553
1554
0
        if(skip_flag)
1555
0
        {
1556
0
            u4_skip_left |= u4_left_mask;
1557
0
        }
1558
0
        else
1559
0
        {
1560
0
            u4_skip_left &= ~u4_left_mask;
1561
0
        }
1562
0
        ps_codec->s_parse.u4_skip_cu_left = u4_skip_left;
1563
0
    }
1564
0
    ps_codec->s_parse.i4_cu_pcm_flag = 0;
1565
1566
0
    if(skip_flag)
1567
0
    {
1568
0
        WORD32 ctb_x_base;
1569
0
        WORD32 ctb_y_base;
1570
1571
0
        ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size;
1572
0
        ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size;
1573
1574
0
        ps_tu->b1_cb_cbf = 0;
1575
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1576
0
        ps_tu->b1_cb_cbf_subtu1 = 0;
1577
0
#endif
1578
0
        ps_tu->b1_cr_cbf = 0;
1579
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1580
0
        ps_tu->b1_cr_cbf_subtu1 = 0;
1581
0
#endif
1582
0
        ps_tu->b1_y_cbf = 0;
1583
0
        ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2);
1584
0
        ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2);
1585
0
        ps_tu->b1_transquant_bypass = 0;
1586
0
        ps_tu->b3_size = (log2_cb_size - 2);
1587
0
        ps_tu->b7_qp = ps_codec->s_parse.u4_qp;
1588
0
        ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE;
1589
0
        ps_tu->b6_luma_intra_mode   = INTRA_PRED_NONE;
1590
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1591
0
        ps_tu->b3_cb_log2_res_scale_abs_plus1 = 0;
1592
0
        ps_tu->b1_cb_log2_res_sign = 0;
1593
0
        ps_tu->b3_cr_log2_res_scale_abs_plus1 = 0;
1594
0
        ps_tu->b1_cr_log2_res_sign = 0;
1595
0
#endif
1596
1597
        /* Set the first TU in CU flag */
1598
0
        {
1599
0
            if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) &&
1600
0
                            (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2))
1601
0
            {
1602
0
                ps_tu->b1_first_tu_in_cu = 1;
1603
0
            }
1604
0
            else
1605
0
            {
1606
0
                ps_tu->b1_first_tu_in_cu = 0;
1607
0
            }
1608
0
        }
1609
1610
0
        ps_codec->s_parse.ps_tu++;
1611
0
        ps_codec->s_parse.s_cu.i4_tu_cnt++;
1612
0
        ps_codec->s_parse.i4_pic_tu_idx++;
1613
1614
0
        ps_codec->s_parse.s_cu.i4_pred_mode = PRED_MODE_SKIP;
1615
0
        ps_codec->s_parse.s_cu.i4_part_mode = PART_2Nx2N;
1616
0
        {
1617
0
            pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1618
0
            ps_pu->b2_part_idx = 0;
1619
0
            ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size);
1620
0
            STATS_UPDATE_PU_SKIP_SIZE(ps_pu);
1621
0
        }
1622
0
    }
1623
0
    else
1624
0
    {
1625
0
        WORD32 pred_mode;
1626
0
        WORD32 part_mode;
1627
0
        WORD32 intra_split_flag;
1628
0
        WORD32 is_mincb;
1629
0
        cb_size = (1 << log2_cb_size);
1630
0
        is_mincb = (cb_size == (1 << ps_sps->i1_log2_min_coding_block_size));
1631
0
        pcm_flag = 0;
1632
0
        if(ps_slice_hdr->i1_slice_type != ISLICE)
1633
0
        {
1634
0
            TRACE_CABAC_CTXT("pred_mode_flag", ps_cabac->u4_range, IHEVC_CAB_PRED_MODE);
1635
0
            pred_mode = ihevcd_cabac_decode_bin(ps_cabac,
1636
0
                                                ps_bitstrm,
1637
0
                                                IHEVC_CAB_PRED_MODE);
1638
1639
0
            AEV_TRACE("pred_mode_flag", pred_mode, ps_cabac->u4_range);
1640
0
        }
1641
0
        else
1642
0
        {
1643
0
            pred_mode = PRED_MODE_INTRA;
1644
0
        }
1645
1646
        /* If current CU is intra then set corresponging bit in picture level intra map */
1647
0
        if(PRED_MODE_INTRA == pred_mode)
1648
0
        {
1649
0
            UWORD8 *pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
1650
0
            UWORD32 u4_mask;
1651
0
            WORD32 i;
1652
0
            WORD32 numbytes_row;
1653
0
            numbytes_row =  (ps_sps->i2_pic_width_in_luma_samples + 63) / 64;
1654
0
            pu1_pic_intra_flag += (y0 / 8) * numbytes_row;
1655
0
            pu1_pic_intra_flag += (x0 / 64);
1656
1657
            /* Generate (cb_size / 8) number of 1s */
1658
            /* i.e (log2_cb_size - 2) number of 1s */
1659
0
            u4_mask = LSB_ONES((cb_size >> 3));
1660
0
            for(i = 0; i < (cb_size / 8); i++)
1661
0
            {
1662
0
                *pu1_pic_intra_flag |= (u4_mask << (((x0) / 8) % 8));
1663
0
                pu1_pic_intra_flag += numbytes_row;
1664
0
            }
1665
0
        }
1666
1667
0
        ps_codec->s_parse.s_cu.i4_pred_mode = pred_mode;
1668
0
        intra_split_flag = 0;
1669
0
        if((PRED_MODE_INTRA != pred_mode) ||
1670
0
                        is_mincb)
1671
0
        {
1672
0
            UWORD32 bin;
1673
0
            if(PRED_MODE_INTRA == pred_mode)
1674
0
            {
1675
0
                TRACE_CABAC_CTXT("part_mode", ps_cabac->u4_range, IHEVC_CAB_PART_MODE);
1676
0
                bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, IHEVC_CAB_PART_MODE);
1677
0
                part_mode = (bin) ? PART_2Nx2N : PART_NxN;
1678
0
            }
1679
0
            else
1680
0
            {
1681
0
                WORD32 amp_enabled = ps_sps->i1_amp_enabled_flag;
1682
1683
0
                UWORD32 u4_max_bin_cnt = 0;
1684
1685
1686
1687
0
                if(amp_enabled && !is_mincb)
1688
0
                {
1689
0
                    part_mode = ihevcd_parse_part_mode_amp(ps_cabac, ps_bitstrm);
1690
0
                }
1691
0
                else
1692
0
                {
1693
0
                    WORD32 ctxt_inc = IHEVC_CAB_PART_MODE;
1694
1695
0
                    u4_max_bin_cnt = 2;
1696
0
                    if((is_mincb) && (cb_size > 8))
1697
0
                    {
1698
0
                        u4_max_bin_cnt++;
1699
0
                    }
1700
1701
0
                    part_mode = -1;
1702
0
                    TRACE_CABAC_CTXT("part_mode", ps_cabac->u4_range, IHEVC_CAB_PART_MODE);
1703
0
                    do
1704
0
                    {
1705
0
                        bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm,
1706
0
                                                      ctxt_inc++);
1707
0
                        part_mode++;
1708
0
                    }while(--u4_max_bin_cnt && !bin);
1709
1710
                    /* If the last bin was zero, then increment part mode by 1 */
1711
0
                    if(!bin)
1712
0
                        part_mode++;
1713
0
                }
1714
1715
1716
0
            }
1717
1718
0
            AEV_TRACE("part_mode", part_mode, ps_cabac->u4_range);
1719
1720
0
        }
1721
0
        else
1722
0
        {
1723
0
            part_mode = 0;
1724
0
            intra_split_flag = 0;
1725
0
        }
1726
0
        ps_codec->s_parse.s_cu.i4_part_mode = part_mode;
1727
1728
0
        if((PRED_MODE_INTRA == ps_codec->s_parse.s_cu.i4_pred_mode) &&
1729
0
                        (PART_NxN == ps_codec->s_parse.s_cu.i4_part_mode))
1730
0
        {
1731
0
            intra_split_flag = 1;
1732
0
        }
1733
0
        ps_codec->s_parse.s_cu.i4_part_mode = part_mode;
1734
0
        ps_codec->s_parse.s_cu.i4_intra_split_flag = intra_split_flag;
1735
0
        if(pred_mode == PRED_MODE_INTRA)
1736
0
        {
1737
0
            ps_codec->s_parse.i4_cu_pcm_flag = 0;
1738
0
            ihevcd_parse_coding_unit_intra(ps_codec, x0, y0, log2_cb_size);
1739
0
            pcm_flag = ps_codec->s_parse.i4_cu_pcm_flag;
1740
1741
0
        }
1742
0
        else
1743
0
        {
1744
0
            if(part_mode == PART_2Nx2N)
1745
0
            {
1746
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1747
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size);
1748
0
                ps_pu->b2_part_idx = 0;
1749
0
            }
1750
0
            else if(part_mode == PART_2NxN)
1751
0
            {
1752
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1753
1754
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size / 2);
1755
0
                ps_pu->b2_part_idx = 0;
1756
1757
0
                ps_pu = ps_codec->s_parse.ps_pu;
1758
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size / 2), cb_size, cb_size / 2);
1759
1760
0
                ps_pu->b2_part_idx = 1;
1761
0
            }
1762
0
            else if(part_mode == PART_Nx2N)
1763
0
            {
1764
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1765
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size / 2, cb_size);
1766
0
                ps_pu->b2_part_idx = 0;
1767
0
                ps_pu = ps_codec->s_parse.ps_pu;
1768
0
                ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 2), y0, cb_size / 2, cb_size);
1769
1770
0
                ps_pu->b2_part_idx = 1;
1771
0
            }
1772
0
            else if(part_mode == PART_2NxnU)
1773
0
            {
1774
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1775
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size / 4);
1776
0
                ps_pu->b2_part_idx = 0;
1777
0
                ps_pu = ps_codec->s_parse.ps_pu;
1778
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size / 4), cb_size, cb_size * 3 / 4);
1779
1780
0
                ps_pu->b2_part_idx = 1;
1781
0
            }
1782
0
            else if(part_mode == PART_2NxnD)
1783
0
            {
1784
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1785
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size, cb_size * 3 / 4);
1786
0
                ps_pu->b2_part_idx = 0;
1787
0
                ps_pu = ps_codec->s_parse.ps_pu;
1788
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size * 3 / 4), cb_size, cb_size / 4);
1789
1790
0
                ps_pu->b2_part_idx = 1;
1791
0
            }
1792
0
            else if(part_mode == PART_nLx2N)
1793
0
            {
1794
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1795
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size / 4, cb_size);
1796
0
                ps_pu->b2_part_idx = 0;
1797
0
                ps_pu = ps_codec->s_parse.ps_pu;
1798
0
                ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 4), y0, cb_size * 3 / 4, cb_size);
1799
1800
0
                ps_pu->b2_part_idx = 1;
1801
0
            }
1802
0
            else if(part_mode == PART_nRx2N)
1803
0
            {
1804
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1805
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size * 3 / 4, cb_size);
1806
0
                ps_pu->b2_part_idx = 0;
1807
0
                ps_pu = ps_codec->s_parse.ps_pu;
1808
0
                ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size * 3 / 4), y0, cb_size / 4, cb_size);
1809
0
                ps_pu->b2_part_idx = 1;
1810
0
            }
1811
0
            else
1812
0
            { /* PART_NxN */
1813
0
                pu_t *ps_pu = ps_codec->s_parse.ps_pu;
1814
1815
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0, cb_size / 2, cb_size / 2);
1816
0
                ps_pu->b2_part_idx = 0;
1817
0
                ps_pu = ps_codec->s_parse.ps_pu;
1818
0
                ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 2), y0, cb_size / 2, cb_size / 2);
1819
1820
0
                ps_pu->b2_part_idx = 1;
1821
0
                ps_pu = ps_codec->s_parse.ps_pu;
1822
0
                ihevcd_parse_prediction_unit(ps_codec, x0, y0 + (cb_size / 2), cb_size / 2, cb_size / 2);
1823
1824
0
                ps_pu->b2_part_idx = 2;
1825
0
                ps_pu = ps_codec->s_parse.ps_pu;
1826
0
                ihevcd_parse_prediction_unit(ps_codec, x0 + (cb_size / 2), y0 + (cb_size / 2), cb_size / 2, cb_size / 2);
1827
1828
0
                ps_pu->b2_part_idx = 3;
1829
0
            }
1830
0
        }
1831
1832
0
        if(!pcm_flag)
1833
0
        {
1834
0
            WORD32 no_residual_syntax_flag = 0;
1835
0
            pu_t *ps_pu;
1836
            /* Since ps_pu is incremented for each PU parsed, decrement by 1 to
1837
             *  access last decoded PU
1838
             */
1839
0
            ps_pu = ps_codec->s_parse.ps_pu - 1;
1840
0
            if((PRED_MODE_INTRA != pred_mode) &&
1841
0
                            (!((part_mode == PART_2Nx2N) && ps_pu->b1_merge_flag)))
1842
0
            {
1843
1844
0
                TRACE_CABAC_CTXT("rqt_root_cbf", ps_cabac->u4_range, IHEVC_CAB_NORES_IDX);
1845
0
                no_residual_syntax_flag = ihevcd_cabac_decode_bin(ps_cabac,
1846
0
                                                                  ps_bitstrm,
1847
0
                                                                  IHEVC_CAB_NORES_IDX);
1848
1849
0
                AEV_TRACE("rqt_root_cbf", no_residual_syntax_flag,
1850
0
                          ps_cabac->u4_range);
1851
                /* TODO: HACK FOR COMPLIANCE WITH HM REFERENCE DECODER */
1852
                /*********************************************************/
1853
                /* currently the HM decoder expects qtroot cbf instead of */
1854
                /* no_residue_flag which has opposite meaning             */
1855
                /* This will be fixed once the software / spec is fixed   */
1856
                /*********************************************************/
1857
0
                no_residual_syntax_flag = 1 - no_residual_syntax_flag;
1858
0
            }
1859
1860
0
            if(!no_residual_syntax_flag)
1861
0
            {
1862
1863
0
                ps_codec->s_parse.s_cu.i4_max_trafo_depth = (pred_mode == PRED_MODE_INTRA) ?
1864
0
                                (ps_sps->i1_max_transform_hierarchy_depth_intra + intra_split_flag) :
1865
0
                                (ps_sps->i1_max_transform_hierarchy_depth_inter);
1866
0
                ret = ihevcd_parse_transform_tree(ps_codec, x0, y0, x0, y0,
1867
0
                                                  log2_cb_size, 0, 0,
1868
0
                                                  ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0],
1869
0
                                                  ps_codec->s_parse.s_cu.ai4_intra_chroma_pred_mode_idx[0]);
1870
0
                RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
1871
0
            }
1872
0
            else
1873
0
            {
1874
0
                WORD32 ctb_x_base;
1875
0
                WORD32 ctb_y_base;
1876
1877
0
                ctb_x_base = ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size;
1878
0
                ctb_y_base = ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size;
1879
1880
0
                ps_tu = ps_codec->s_parse.ps_tu;
1881
0
                ps_tu->b1_cb_cbf = 0;
1882
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1883
0
                ps_tu->b1_cb_cbf_subtu1 = 0;
1884
0
#endif
1885
0
                ps_tu->b1_cr_cbf = 0;
1886
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1887
0
                ps_tu->b1_cr_cbf_subtu1 = 0;
1888
0
#endif
1889
0
                ps_tu->b1_y_cbf = 0;
1890
0
                ps_tu->b4_pos_x = ((x0 - ctb_x_base) >> 2);
1891
0
                ps_tu->b4_pos_y = ((y0 - ctb_y_base) >> 2);
1892
0
                ps_tu->b1_transquant_bypass = 0;
1893
0
                ps_tu->b3_size = (log2_cb_size - 2);
1894
0
                ps_tu->b7_qp = ps_codec->s_parse.u4_qp;
1895
0
                ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE;
1896
0
                ps_tu->b6_luma_intra_mode   = ps_codec->s_parse.s_cu.ai4_intra_luma_pred_mode[0];
1897
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1898
0
                ps_tu->b3_cb_log2_res_scale_abs_plus1 = 0;
1899
0
                ps_tu->b1_cb_log2_res_sign = 0;
1900
0
                ps_tu->b3_cr_log2_res_scale_abs_plus1 = 0;
1901
0
                ps_tu->b1_cr_log2_res_sign = 0;
1902
0
#endif
1903
1904
                /* Set the first TU in CU flag */
1905
0
                {
1906
0
                    if((ps_codec->s_parse.s_cu.i4_pos_x << 3) == (ps_tu->b4_pos_x << 2) &&
1907
0
                                    (ps_codec->s_parse.s_cu.i4_pos_y << 3) == (ps_tu->b4_pos_y << 2))
1908
0
                    {
1909
0
                        ps_tu->b1_first_tu_in_cu = 1;
1910
0
                    }
1911
0
                    else
1912
0
                    {
1913
0
                        ps_tu->b1_first_tu_in_cu = 0;
1914
0
                    }
1915
0
                }
1916
0
                ps_codec->s_parse.ps_tu++;
1917
0
                ps_codec->s_parse.s_cu.i4_tu_cnt++;
1918
0
                ps_codec->s_parse.i4_pic_tu_idx++;
1919
1920
0
            }
1921
0
        }
1922
1923
0
    }
1924
1925
1926
1927
1928
0
    return ret;
1929
0
}
1930
1931
1932
1933
1934
/**
1935
 *******************************************************************************
1936
 *
1937
 * @brief
1938
 *  Parses Coding Quad Tree
1939
 *
1940
 * @par Description:
1941
 *  Parses Coding Quad Tree as per Section:7.3.9.4
1942
 *
1943
 * @param[in] ps_codec
1944
 *  Pointer to codec context
1945
 *
1946
 * @returns  Error from IHEVCD_ERROR_T
1947
 *
1948
 * @remarks
1949
 *
1950
 *
1951
 *******************************************************************************
1952
 */
1953
IHEVCD_ERROR_T ihevcd_parse_coding_quadtree(codec_t *ps_codec,
1954
                                            WORD32 x0,
1955
                                            WORD32 y0,
1956
                                            WORD32 log2_cb_size,
1957
                                            WORD32 ct_depth)
1958
0
{
1959
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
1960
0
    sps_t *ps_sps;
1961
0
    pps_t *ps_pps;
1962
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1963
0
    slice_header_t *ps_slice_hdr;
1964
0
#endif
1965
0
    WORD32 split_cu_flag;
1966
0
    WORD32 x1, y1;
1967
0
    WORD32 cu_pos_x;
1968
0
    WORD32 cu_pos_y;
1969
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
1970
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
1971
0
    WORD32 cb_size = 1 << log2_cb_size;
1972
0
    ps_sps = ps_codec->s_parse.ps_sps;
1973
0
    ps_pps = ps_codec->s_parse.ps_pps;
1974
0
#ifdef ENABLE_MAIN_REXT_PROFILE
1975
0
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1976
0
#endif
1977
1978
    /* Compute CU position with respect to current CTB in (8x8) units */
1979
0
    cu_pos_x = (x0 - (ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size)) >> 3;
1980
0
    cu_pos_y = (y0 - (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size)) >> 3;
1981
1982
0
    ps_codec->s_parse.s_cu.i4_pos_x = cu_pos_x;
1983
0
    ps_codec->s_parse.s_cu.i4_pos_y = cu_pos_y;
1984
1985
0
    ps_codec->s_parse.s_cu.i4_log2_cb_size = log2_cb_size;
1986
1987
0
    ps_codec->s_parse.i4_ct_depth = ct_depth;
1988
0
    {
1989
0
        UWORD32 *pu4_ct_depth_top = ps_codec->s_parse.pu4_ct_depth_top;
1990
0
        UWORD32 u4_ct_depth_left = ps_codec->s_parse.u4_ct_depth_left;
1991
0
        UWORD32 u4_ct_depth_top = 0;
1992
0
        UWORD32 u4_mask;
1993
0
        UWORD32 u4_top_mask, u4_left_mask;
1994
0
        WORD32  ctxt_idx;
1995
0
        UWORD32 u4_min_cu_x = x0 / 8;
1996
0
        UWORD32 u4_min_cu_y = y0 / 8;
1997
1998
0
        pu4_ct_depth_top += (u4_min_cu_x / 16);
1999
2000
2001
2002
2003
0
        if(((x0 + (1 << log2_cb_size)) <= ps_sps->i2_pic_width_in_luma_samples) &&
2004
0
                        ((y0 + (1 << log2_cb_size)) <= ps_sps->i2_pic_height_in_luma_samples) &&
2005
0
                        (log2_cb_size > ps_sps->i1_log2_min_coding_block_size))
2006
0
        {
2007
2008
0
            ctxt_idx = IHEVC_CAB_SPLIT_CU_FLAG;
2009
            /* Split cu context increment is decided based on left and top Coding tree
2010
             * depth which is stored at frame level
2011
             */
2012
            /* Check if the CTB is in first row in the current slice or tile */
2013
0
            if((0 != cu_pos_y) ||
2014
0
                            ((0 != ps_codec->s_parse.i4_ctb_slice_y) &&
2015
0
                                            (0 != ps_codec->s_parse.i4_ctb_tile_y)))
2016
0
            {
2017
0
                u4_ct_depth_top = *pu4_ct_depth_top;
2018
0
                u4_ct_depth_top >>= ((u4_min_cu_x % 16) * 2);
2019
0
                u4_ct_depth_top &= 3;
2020
2021
0
                if((WORD32)u4_ct_depth_top > ct_depth)
2022
0
                    ctxt_idx++;
2023
0
            }
2024
2025
            /* Check if the CTB is in first column in the current slice or tile */
2026
            /*****************************************************************/
2027
            /* If cu_pos_x is non-zero then left is available                */
2028
            /* If cu_pos_x is zero then ensure both the following are true   */
2029
            /*    Current CTB is not the first CTB in a tile row             */
2030
            /*    Current CTB is not the first CTB in a slice                */
2031
            /*****************************************************************/
2032
0
            if((0 != cu_pos_x) ||
2033
0
                            (((0 != ps_codec->s_parse.i4_ctb_slice_x) || (0 != ps_codec->s_parse.i4_ctb_slice_y)) &&
2034
0
                                            (0 != ps_codec->s_parse.i4_ctb_tile_x)))
2035
0
            {
2036
0
                u4_ct_depth_left >>= ((u4_min_cu_y % 16) * 2);
2037
0
                u4_ct_depth_left &= 3;
2038
0
                if((WORD32)u4_ct_depth_left > ct_depth)
2039
0
                    ctxt_idx++;
2040
0
            }
2041
0
            TRACE_CABAC_CTXT("split_cu_flag", ps_cabac->u4_range, ctxt_idx);
2042
0
            split_cu_flag = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
2043
0
            AEV_TRACE("split_cu_flag", split_cu_flag, ps_cabac->u4_range);
2044
0
        }
2045
0
        else
2046
0
        {
2047
0
            if(log2_cb_size > ps_sps->i1_log2_min_coding_block_size)
2048
0
                split_cu_flag = 1;
2049
0
            else
2050
0
                split_cu_flag = 0;
2051
0
        }
2052
2053
0
        if(0 == split_cu_flag)
2054
0
        {
2055
            /* Update top ct_depth */
2056
0
            u4_ct_depth_top = *pu4_ct_depth_top;
2057
            /* Since Max cb_size is 64, maximum of 8 bits will be set or reset */
2058
            /* Also since Coding block will be within 64x64 grid, only 8bits within a WORD32
2059
             * need to be updated. These 8 bits will not cross 8 bit boundaries
2060
             */
2061
0
            u4_mask = DUP_LSB_11(cb_size / 8);
2062
2063
0
            u4_top_mask = u4_mask << ((u4_min_cu_x % 16) * 2);
2064
0
            u4_ct_depth_top &= ~u4_top_mask;
2065
2066
0
            if(ct_depth)
2067
0
            {
2068
0
                u4_top_mask = gau4_ct_depth_mask[ct_depth] & u4_mask;
2069
2070
0
                u4_top_mask = u4_top_mask << ((u4_min_cu_x % 16) * 2);
2071
0
                u4_ct_depth_top |= u4_top_mask;
2072
0
            }
2073
2074
0
            *pu4_ct_depth_top = u4_ct_depth_top;
2075
2076
            /* Update left ct_depth */
2077
0
            u4_ct_depth_left = ps_codec->s_parse.u4_ct_depth_left;
2078
2079
0
            u4_left_mask = u4_mask << ((u4_min_cu_y % 16) * 2);
2080
2081
0
            u4_ct_depth_left &= ~u4_left_mask;
2082
0
            if(ct_depth)
2083
0
            {
2084
0
                u4_left_mask = gau4_ct_depth_mask[ct_depth] & u4_mask;
2085
2086
0
                u4_left_mask = u4_left_mask << ((u4_min_cu_y % 16) * 2);
2087
0
                u4_ct_depth_left |= u4_left_mask;
2088
0
            }
2089
2090
0
            ps_codec->s_parse.u4_ct_depth_left = u4_ct_depth_left;
2091
0
        }
2092
0
    }
2093
0
    if((ps_pps->i1_cu_qp_delta_enabled_flag) &&
2094
0
                    (log2_cb_size >= ps_pps->i1_log2_min_cu_qp_delta_size))
2095
0
    {
2096
0
        ps_codec->s_parse.i4_is_cu_qp_delta_coded = 0;
2097
0
        ps_codec->s_parse.i4_cu_qp_delta = 0;
2098
0
    }
2099
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2100
0
    if(ps_slice_hdr->i1_cu_chroma_qp_offset_enabled_flag
2101
0
        && log2_cb_size >= (ps_sps->i1_log2_ctb_size
2102
0
                        - ps_pps->i4_diff_cu_chroma_qp_offset_depth))
2103
0
    {
2104
0
        ps_codec->s_parse.i4_is_cu_chroma_qp_offset_coded = 0;
2105
0
        ps_codec->s_parse.i4_cu_chroma_qp_offset_flag = 0;
2106
0
        ps_codec->s_parse.i4_cu_chroma_qp_offset_idx = 0;
2107
0
    }
2108
0
#endif
2109
0
    if(split_cu_flag)
2110
0
    {
2111
0
        x1 = x0 + ((1 << log2_cb_size) >> 1);
2112
0
        y1 = y0 + ((1 << log2_cb_size) >> 1);
2113
2114
0
        ret = ihevcd_parse_coding_quadtree(ps_codec, x0, y0, log2_cb_size - 1, ct_depth + 1);
2115
0
        RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
2116
2117
        /* At frame boundaries coding quadtree nodes are sent only if they fall within the frame */
2118
0
        if(x1 < ps_sps->i2_pic_width_in_luma_samples)
2119
0
        {
2120
0
            ret = ihevcd_parse_coding_quadtree(ps_codec, x1, y0, log2_cb_size - 1, ct_depth + 1);
2121
0
            RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
2122
0
        }
2123
2124
0
        if(y1 < ps_sps->i2_pic_height_in_luma_samples)
2125
0
        {
2126
0
            ret = ihevcd_parse_coding_quadtree(ps_codec, x0, y1, log2_cb_size - 1, ct_depth + 1);
2127
0
            RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
2128
0
        }
2129
2130
0
        if((x1 < ps_sps->i2_pic_width_in_luma_samples) &&
2131
0
                        (y1 < ps_sps->i2_pic_height_in_luma_samples))
2132
0
        {
2133
0
            ret = ihevcd_parse_coding_quadtree(ps_codec, x1, y1, log2_cb_size - 1, ct_depth + 1);
2134
0
            RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
2135
0
        }
2136
0
    }
2137
0
    else
2138
0
    {
2139
0
        WORD32 qp = ps_codec->s_parse.u4_qp;
2140
        /* Set current group QP if current CU is aligned with the group */
2141
0
        {
2142
0
            WORD32 cu_pos_x = ps_codec->s_parse.s_cu.i4_pos_x << 3;
2143
0
            WORD32 cu_pos_y = ps_codec->s_parse.s_cu.i4_pos_y << 3;
2144
2145
0
            WORD32 qpg_x = (cu_pos_x - (cu_pos_x & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1)));
2146
0
            WORD32 qpg_y = (cu_pos_y - (cu_pos_y & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1)));
2147
2148
0
            if((cu_pos_x == qpg_x) &&
2149
0
                            (cu_pos_y == qpg_y))
2150
0
            {
2151
0
                ps_codec->s_parse.u4_qpg = ps_codec->s_parse.u4_qp;
2152
2153
0
                ps_codec->s_parse.s_cu.i4_cu_qp_delta = 0;
2154
2155
0
            }
2156
0
        }
2157
2158
0
        ret = ihevcd_parse_coding_unit(ps_codec, x0, y0, log2_cb_size);
2159
0
        RETURN_IF((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret, ret);
2160
2161
0
        if(ps_pps->i1_cu_qp_delta_enabled_flag)
2162
0
        {
2163
0
            WORD32 qp_pred, qp_left, qp_top;
2164
0
            WORD32 cu_pos_x;
2165
0
            WORD32 cu_pos_y;
2166
0
            WORD32 qpg_x;
2167
0
            WORD32 qpg_y;
2168
0
            WORD32 i, j;
2169
0
            WORD32 cur_cu_offset;
2170
0
            tu_t *ps_tu = ps_codec->s_parse.ps_tu;
2171
0
            WORD32 cb_size = 1 << ps_codec->s_parse.s_cu.i4_log2_cb_size;
2172
2173
0
            cu_pos_x = ps_codec->s_parse.s_cu.i4_pos_x << 3;
2174
0
            cu_pos_y = ps_codec->s_parse.s_cu.i4_pos_y << 3;
2175
2176
0
            qpg_x = (cu_pos_x - (cu_pos_x & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1))) >> 3;
2177
0
            qpg_y = (cu_pos_y - (cu_pos_y & ((1 << ps_pps->i1_log2_min_cu_qp_delta_size) - 1))) >> 3;
2178
2179
            /*previous coded Qp*/
2180
0
            qp_left = ps_codec->s_parse.u4_qpg;
2181
0
            qp_top = ps_codec->s_parse.u4_qpg;
2182
2183
0
            if(qpg_x > 0)
2184
0
            {
2185
0
                qp_left = ps_codec->s_parse.ai1_8x8_cu_qp[qpg_x - 1 + (qpg_y * 8)];
2186
0
            }
2187
0
            if(qpg_y > 0)
2188
0
            {
2189
0
                qp_top = ps_codec->s_parse.ai1_8x8_cu_qp[qpg_x + ((qpg_y - 1) * 8)];
2190
0
            }
2191
2192
0
            qp_pred = (qp_left + qp_top + 1) >> 1;
2193
            /* Since qp_pred + ps_codec->s_parse.s_cu.i4_cu_qp_delta can be negative,
2194
            52 is added before taking modulo 52 */
2195
0
            qp = (qp_pred + ps_codec->s_parse.s_cu.i4_cu_qp_delta + 52) % 52;
2196
2197
0
            cur_cu_offset = (cu_pos_x >> 3) + cu_pos_y;
2198
0
            for(i = 0; i < (cb_size >> 3); i++)
2199
0
            {
2200
0
                for(j = 0; j < (cb_size >> 3); j++)
2201
0
                {
2202
0
                    ps_codec->s_parse.ai1_8x8_cu_qp[cur_cu_offset + (i * 8) + j] = qp;
2203
0
                }
2204
0
            }
2205
2206
0
            ps_codec->s_parse.u4_qp = qp;
2207
0
            ps_codec->s_parse.s_cu.i4_qp = qp;
2208
2209
2210
            /* When change in QP is signaled, update the QP in TUs that are already parsed in the CU */
2211
0
            {
2212
0
                tu_t *ps_tu_tmp;
2213
0
                ps_tu_tmp = ps_tu - ps_codec->s_parse.s_cu.i4_tu_cnt;
2214
0
                ps_tu->b7_qp = ps_codec->s_parse.u4_qp;
2215
0
                while(ps_tu_tmp != ps_tu)
2216
0
                {
2217
0
                    ps_tu_tmp->b7_qp = ps_codec->s_parse.u4_qp;
2218
2219
0
                    ps_tu_tmp++;
2220
0
                }
2221
0
            }
2222
0
            if(ps_codec->s_parse.s_cu.i4_cu_qp_delta)
2223
0
            {
2224
0
                WORD32 ctb_indx;
2225
0
                ctb_indx = ps_codec->s_parse.i4_ctb_x + ps_sps->i2_pic_wd_in_ctb * ps_codec->s_parse.i4_ctb_y;
2226
0
                ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb[ctb_indx >> 3] &= (~(1 << (ctb_indx & 7)));
2227
0
            }
2228
2229
0
        }
2230
        /* Populate CU_info maps for current CU*/
2231
0
        if(ps_codec->u1_enable_cu_info)
2232
0
        {
2233
0
            WORD32 cu_info_map_stride = ALIGN64(ps_codec->i4_wd) >> 3;
2234
0
            UWORD8 num_8x8_blks = 1 << (log2_cb_size - 3);
2235
0
            WORD32 vert_8x8, horz_8x8;
2236
0
            UWORD8 *pu1_cur_cu_type_map =
2237
0
                ps_codec->as_buf_id_info_map[ps_codec->as_process[0].
2238
0
                    i4_cur_pic_buf_id].pu1_cu_type_map;
2239
0
            UWORD8 *pu1_cur_qp_map =
2240
0
                ps_codec->as_buf_id_info_map[ps_codec->as_process[0].i4_cur_pic_buf_id].pu1_qp_map;
2241
0
            UWORD8 *pu1_cur_type_cu = pu1_cur_cu_type_map + (x0 >> 3) +
2242
0
                (y0 >> 3) * cu_info_map_stride;
2243
0
            UWORD8 *pu1_cur_qp_cu = pu1_cur_qp_map + (x0 >> 3) +
2244
0
                (y0 >> 3) * cu_info_map_stride;
2245
0
            for(vert_8x8 = 0; vert_8x8 < num_8x8_blks; vert_8x8++)
2246
0
            {
2247
0
                for(horz_8x8 = 0; horz_8x8 < num_8x8_blks; horz_8x8++)
2248
0
                {
2249
0
                    pu1_cur_qp_cu[horz_8x8] = qp;
2250
0
                    pu1_cur_type_cu[horz_8x8] = ps_codec->s_parse.s_cu.i4_pred_mode;
2251
0
                }
2252
0
                pu1_cur_qp_cu += cu_info_map_stride;
2253
0
                pu1_cur_type_cu += cu_info_map_stride;
2254
0
            }
2255
0
        }
2256
2257
0
    }
2258
2259
2260
2261
2262
0
    return ret;
2263
0
}
2264
2265
2266
/**
2267
 *******************************************************************************
2268
 *
2269
 * @brief
2270
 *  Parses SAO (Sample adaptive offset syntax)
2271
 *
2272
 * @par Description:
2273
 *  Parses SAO (Sample adaptive offset syntax) as per  Section:7.3.9.3
2274
 *
2275
 * @param[in] ps_codec
2276
 *  Pointer to codec context
2277
 *
2278
 * @returns  Error from IHEVCD_ERROR_T
2279
 *
2280
 * @remarks
2281
 *
2282
 *
2283
 *******************************************************************************
2284
 */
2285
IHEVCD_ERROR_T  ihevcd_parse_sao(codec_t *ps_codec)
2286
0
{
2287
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
2288
0
    sps_t *ps_sps;
2289
0
    sao_t *ps_sao;
2290
0
    WORD32 rx;
2291
0
    WORD32 ry;
2292
0
    WORD32 value;
2293
0
    bitstrm_t *ps_bitstrm = &ps_codec->s_parse.s_bitstrm;
2294
0
    WORD32 sao_merge_left_flag;
2295
0
    WORD32 sao_merge_up_flag;
2296
0
    slice_header_t *ps_slice_hdr;
2297
0
    cab_ctxt_t *ps_cabac = &ps_codec->s_parse.s_cabac;
2298
0
    WORD32 ctxt_idx;
2299
2300
0
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr_base;
2301
0
    ps_slice_hdr += (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1));
2302
2303
0
    ps_sps = (ps_codec->s_parse.ps_sps);
2304
0
    rx = ps_codec->s_parse.i4_ctb_x;
2305
0
    ry = ps_codec->s_parse.i4_ctb_y;
2306
2307
0
    ps_sao = ps_codec->s_parse.ps_pic_sao + rx + ry * ps_sps->i2_pic_wd_in_ctb;
2308
2309
    /* Default values */
2310
0
    ps_sao->b3_y_type_idx = 0;
2311
0
    ps_sao->b3_cb_type_idx = 0;
2312
0
    ps_sao->b3_cr_type_idx = 0;
2313
2314
0
    UNUSED(value);
2315
0
    ctxt_idx = IHEVC_CAB_SAO_MERGE;
2316
0
    sao_merge_left_flag = 0;
2317
0
    sao_merge_up_flag = 0;
2318
0
    if(rx > 0)
2319
0
    {
2320
        /*TODO:Implemented only for slice. condition for tile is not tested*/
2321
0
        if(((0 != ps_codec->s_parse.i4_ctb_slice_x) || (0 != ps_codec->s_parse.i4_ctb_slice_y)) &&
2322
0
                        (0 != ps_codec->s_parse.i4_ctb_tile_x))
2323
0
        {
2324
2325
0
            TRACE_CABAC_CTXT("sao_merge_flag", ps_cabac->u4_range, ctxt_idx);
2326
0
            sao_merge_left_flag = ihevcd_cabac_decode_bin(ps_cabac,
2327
0
                                                          ps_bitstrm,
2328
0
                                                          ctxt_idx);
2329
0
            AEV_TRACE("sao_merge_flag", sao_merge_left_flag, ps_cabac->u4_range);
2330
0
        }
2331
2332
0
    }
2333
0
    if(ry > 0 && !sao_merge_left_flag)
2334
0
    {
2335
0
        if((ps_codec->s_parse.i4_ctb_slice_y > 0) && (ps_codec->s_parse.i4_ctb_tile_y > 0))
2336
0
        {
2337
0
            TRACE_CABAC_CTXT("sao_merge_flag", ps_cabac->u4_range, ctxt_idx);
2338
0
            sao_merge_up_flag = ihevcd_cabac_decode_bin(ps_cabac,
2339
0
                                                        ps_bitstrm,
2340
0
                                                        ctxt_idx);
2341
0
            AEV_TRACE("sao_merge_flag", sao_merge_up_flag, ps_cabac->u4_range);
2342
0
        }
2343
0
    }
2344
0
    ctxt_idx = IHEVC_CAB_SAO_TYPE;
2345
2346
0
    if(sao_merge_left_flag)
2347
0
    {
2348
0
        *ps_sao = *(ps_sao - 1);
2349
0
    }
2350
0
    else if(sao_merge_up_flag)
2351
0
    {
2352
0
        *ps_sao = *(ps_sao - ps_sps->i2_pic_wd_in_ctb);
2353
0
    }
2354
0
    else // if(!sao_merge_up_flag && !sao_merge_left_flag)
2355
0
    {
2356
0
        WORD32 c_idx;
2357
0
        WORD32 sao_type_idx = 0;
2358
0
        for(c_idx = 0; c_idx < (CHROMA_FMT_IDC_MONOCHROME != ps_sps->i1_chroma_format_idc ? 3 : 1); c_idx++)
2359
0
        {
2360
0
            if((ps_slice_hdr->i1_slice_sao_luma_flag && c_idx == 0) || (ps_slice_hdr->i1_slice_sao_chroma_flag && c_idx > 0))
2361
0
            {
2362
2363
2364
                /* sao_type_idx will be same for c_idx == 1 and c_idx == 2 - hence not initialized to zero for c_idx == 2*/
2365
2366
0
                if(c_idx == 0)
2367
0
                {
2368
0
                    sao_type_idx = 0;
2369
0
                    TRACE_CABAC_CTXT("sao_type_idx", ps_cabac->u4_range, ctxt_idx);
2370
0
                    sao_type_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
2371
2372
0
                    if(sao_type_idx)
2373
0
                    {
2374
0
                        sao_type_idx += ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm);
2375
0
                    }
2376
0
                    AEV_TRACE("sao_type_idx", sao_type_idx,  ps_cabac->u4_range);
2377
2378
0
                    ps_sao->b3_y_type_idx = sao_type_idx;
2379
0
                }
2380
0
                if(c_idx == 1)
2381
0
                {
2382
0
                    sao_type_idx = 0;
2383
0
                    TRACE_CABAC_CTXT("sao_type_idx", ps_cabac->u4_range, ctxt_idx);
2384
0
                    sao_type_idx = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_idx);
2385
0
                    if(sao_type_idx)
2386
0
                    {
2387
0
                        sao_type_idx += ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm);
2388
0
                    }
2389
2390
0
                    AEV_TRACE("sao_type_idx", sao_type_idx,  ps_cabac->u4_range);
2391
2392
0
                    ps_sao->b3_cb_type_idx = sao_type_idx;
2393
0
                    ps_sao->b3_cr_type_idx = sao_type_idx;
2394
0
                }
2395
2396
0
                if(sao_type_idx != 0)
2397
0
                {
2398
0
                    WORD32 i;
2399
0
                    WORD32 sao_offset[4];
2400
0
                    WORD32 sao_band_position = 0;
2401
0
                    WORD32 c_max =  (1 << (MIN(BIT_DEPTH, 10) - 5)) - 1;
2402
0
                    for(i = 0; i < 4; i++)
2403
0
                    {
2404
0
                        sao_offset[i] = ihevcd_cabac_decode_bypass_bins_tunary(ps_cabac, ps_bitstrm, c_max);
2405
0
                        AEV_TRACE("sao_offset_abs", sao_offset[i], ps_cabac->u4_range);
2406
2407
0
                        if((2 == sao_type_idx) && (i > 1))
2408
0
                        {
2409
0
                            sao_offset[i] = -sao_offset[i];
2410
0
                        }
2411
0
                    }
2412
2413
0
                    if(sao_type_idx == 1)
2414
0
                    {
2415
0
                        for(i = 0; i < 4; i++)
2416
0
                        {
2417
0
                            if(sao_offset[i] != 0)
2418
0
                            {
2419
0
                                value = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm);
2420
0
                                AEV_TRACE("sao_offset_sign", value, ps_cabac->u4_range);
2421
2422
0
                                if(value)
2423
0
                                {
2424
0
                                    sao_offset[i] = -sao_offset[i];
2425
0
                                }
2426
0
                            }
2427
0
                        }
2428
0
                        value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 5);
2429
0
                        AEV_TRACE("sao_band_position", value, ps_cabac->u4_range);
2430
2431
0
                        sao_band_position = value;
2432
0
                    }
2433
0
                    else
2434
0
                    {
2435
0
                        if(c_idx == 0)
2436
0
                        {
2437
0
                            value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 2);
2438
0
                            AEV_TRACE("sao_eo_class", value, ps_cabac->u4_range);
2439
2440
0
                            ps_sao->b3_y_type_idx += value;
2441
0
                        }
2442
2443
0
                        if(c_idx == 1)
2444
0
                        {
2445
0
                            value = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, 2);
2446
0
                            AEV_TRACE("sao_eo_class", value, ps_cabac->u4_range);
2447
2448
0
                            ps_sao->b3_cb_type_idx += value;
2449
0
                            ps_sao->b3_cr_type_idx += value;
2450
0
                        }
2451
0
                    }
2452
2453
0
                    if(0 == c_idx)
2454
0
                    {
2455
0
                        ps_sao->b4_y_offset_1 = sao_offset[0];
2456
0
                        ps_sao->b4_y_offset_2 = sao_offset[1];
2457
0
                        ps_sao->b4_y_offset_3 = sao_offset[2];
2458
0
                        ps_sao->b4_y_offset_4 = sao_offset[3];
2459
2460
0
                        ps_sao->b5_y_band_pos = sao_band_position;
2461
0
                    }
2462
0
                    else if(1 == c_idx)
2463
0
                    {
2464
0
                        ps_sao->b4_cb_offset_1 = sao_offset[0];
2465
0
                        ps_sao->b4_cb_offset_2 = sao_offset[1];
2466
0
                        ps_sao->b4_cb_offset_3 = sao_offset[2];
2467
0
                        ps_sao->b4_cb_offset_4 = sao_offset[3];
2468
2469
0
                        ps_sao->b5_cb_band_pos = sao_band_position;
2470
0
                    }
2471
0
                    else // 2 == c_idx
2472
0
                    {
2473
0
                        ps_sao->b4_cr_offset_1 = sao_offset[0];
2474
0
                        ps_sao->b4_cr_offset_2 = sao_offset[1];
2475
0
                        ps_sao->b4_cr_offset_3 = sao_offset[2];
2476
0
                        ps_sao->b4_cr_offset_4 = sao_offset[3];
2477
2478
0
                        ps_sao->b5_cr_band_pos = sao_band_position;
2479
0
                    }
2480
0
                }
2481
0
            }
2482
0
        }
2483
0
    }
2484
2485
0
    return ret;
2486
0
}
2487
/**
2488
 *******************************************************************************
2489
 *
2490
 * @brief
2491
 *  Set ctb skip
2492
 *
2493
 * @par Description:
2494
 *  During error, sets tu and pu params of a ctb as skip.
2495
 *
2496
 * @param[in] ps_codec
2497
 *  Pointer to codec context
2498
 *
2499
 * @returns  None
2500
 *
2501
 * @remarks
2502
 *
2503
 *
2504
 *******************************************************************************
2505
 */
2506
void ihevcd_set_ctb_skip(codec_t *ps_codec)
2507
0
{
2508
0
    tu_t *ps_tu;
2509
0
    pu_t *ps_pu;
2510
0
    sps_t *ps_sps = ps_codec->s_parse.ps_sps;
2511
0
    WORD32 ctb_size = 1 << ps_sps->i1_log2_ctb_size;
2512
0
    WORD32 ctb_skip_wd, ctb_skip_ht;
2513
0
    WORD32 rows_remaining, cols_remaining;
2514
0
    WORD32 tu_abs_x, tu_abs_y;
2515
0
    WORD32 numbytes_row =  (ps_sps->i2_pic_width_in_luma_samples + 63) / 64;
2516
0
    UWORD8 *pu1_pic_intra_flag;
2517
0
    UWORD32 u4_mask;
2518
0
    WORD32 pu_x,pu_y;
2519
2520
    /* Set pu wd and ht based on whether the ctb is complete or not */
2521
0
    rows_remaining = ps_sps->i2_pic_height_in_luma_samples
2522
0
                    - (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size);
2523
0
    ctb_skip_ht = MIN(ctb_size, rows_remaining);
2524
2525
0
    cols_remaining = ps_sps->i2_pic_width_in_luma_samples
2526
0
                    - (ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size);
2527
0
    ctb_skip_wd = MIN(ctb_size, cols_remaining);
2528
2529
0
    ps_codec->s_parse.s_cu.i4_pred_mode = PRED_MODE_SKIP;
2530
0
    ps_codec->s_parse.s_cu.i4_part_mode = PART_2Nx2N;
2531
2532
0
    for (pu_y = 0; pu_y < ctb_skip_ht ; pu_y += MIN_CU_SIZE)
2533
0
    {
2534
0
        for (pu_x = 0; pu_x < ctb_skip_wd ; pu_x += MIN_CU_SIZE)
2535
0
        {
2536
0
            ps_tu = ps_codec->s_parse.ps_tu;
2537
0
            ps_tu->b1_cb_cbf = 0;
2538
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2539
0
            ps_tu->b1_cb_cbf_subtu1 = 0;
2540
0
#endif
2541
0
            ps_tu->b1_cr_cbf = 0;
2542
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2543
0
            ps_tu->b1_cr_cbf_subtu1 = 0;
2544
0
#endif
2545
0
            ps_tu->b1_y_cbf = 0;
2546
0
            ps_tu->b4_pos_x = pu_x >> 2;
2547
0
            ps_tu->b4_pos_y = pu_y >> 2;
2548
0
            ps_tu->b1_transquant_bypass = 0;
2549
0
            ps_tu->b3_size = 1;
2550
0
            ps_tu->b7_qp = ps_codec->s_parse.u4_qp;
2551
0
            ps_tu->b3_chroma_intra_mode_idx = INTRA_PRED_CHROMA_IDX_NONE;
2552
0
            ps_tu->b6_luma_intra_mode   = INTRA_PRED_NONE;
2553
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2554
0
            ps_tu->b3_cb_log2_res_scale_abs_plus1 = 0;
2555
0
            ps_tu->b1_cb_log2_res_sign = 0;
2556
0
            ps_tu->b3_cr_log2_res_scale_abs_plus1 = 0;
2557
0
            ps_tu->b1_cr_log2_res_sign = 0;
2558
0
#endif
2559
0
            ps_tu->b1_first_tu_in_cu = 1;
2560
2561
0
            ps_codec->s_parse.ps_tu++;
2562
0
            ps_codec->s_parse.s_cu.i4_tu_cnt++;
2563
0
            ps_codec->s_parse.i4_pic_tu_idx++;
2564
2565
0
            tu_abs_x = (ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size) + pu_x;
2566
0
            tu_abs_y = (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size) + pu_y;
2567
0
            pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
2568
0
            pu1_pic_intra_flag += (tu_abs_y >> 3) * numbytes_row;
2569
0
            pu1_pic_intra_flag += (tu_abs_x >> 6);
2570
0
            u4_mask = (LSB_ONES((MIN_CU_SIZE >> 3)) << (((tu_abs_x) / 8) % 8));
2571
0
            u4_mask = ~u4_mask;
2572
0
            *pu1_pic_intra_flag &= u4_mask;
2573
2574
0
            ps_pu = ps_codec->s_parse.ps_pu;
2575
0
            ps_pu->b2_part_idx = 0;
2576
0
            ps_pu->b4_pos_x = pu_x >> 2;
2577
0
            ps_pu->b4_pos_y = pu_y >> 2;
2578
0
            ps_pu->b4_wd = 1;
2579
0
            ps_pu->b4_ht = 1;
2580
0
            ps_pu->b1_intra_flag = 0;
2581
0
            ps_pu->b3_part_mode = ps_codec->s_parse.s_cu.i4_part_mode;
2582
0
            ps_pu->b1_merge_flag = 1;
2583
0
            ps_pu->b3_merge_idx = 0;
2584
2585
0
            ps_codec->s_parse.ps_pu++;
2586
0
            ps_codec->s_parse.i4_pic_pu_idx++;
2587
0
        }
2588
0
    }
2589
0
}
2590
2591
/**
2592
 *******************************************************************************
2593
 *
2594
 * @brief
2595
 *  Parses Slice data syntax
2596
 *
2597
 * @par Description:
2598
 *  Parses Slice data syntax as per Section:7.3.9.1
2599
 *
2600
 * @param[in] ps_codec
2601
 *  Pointer to codec context
2602
 *
2603
 * @returns  Error from IHEVCD_ERROR_T
2604
 *
2605
 * @remarks
2606
 *
2607
 *
2608
 *******************************************************************************
2609
 */
2610
IHEVCD_ERROR_T ihevcd_parse_slice_data(codec_t *ps_codec)
2611
0
{
2612
2613
0
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
2614
0
    WORD32 end_of_slice_flag = 0;
2615
0
    sps_t *ps_sps;
2616
0
    pps_t *ps_pps;
2617
0
    slice_header_t *ps_slice_hdr;
2618
0
    WORD32 end_of_pic;
2619
0
    tile_t *ps_tile, *ps_tile_prev;
2620
0
    WORD32 i;
2621
0
    WORD32 ctb_addr;
2622
0
    WORD32 tile_idx;
2623
0
    WORD32 cabac_init_idc;
2624
0
    WORD32 ctb_size;
2625
0
    WORD32 num_ctb_in_row;
2626
0
    WORD32 num_min4x4_in_ctb;
2627
0
    WORD32 slice_qp;
2628
0
    WORD32 slice_start_ctb_idx;
2629
0
    WORD32 tile_start_ctb_idx;
2630
2631
2632
0
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr_base;
2633
0
    ps_pps = ps_codec->s_parse.ps_pps_base;
2634
0
    ps_sps = ps_codec->s_parse.ps_sps_base;
2635
2636
    /* Get current slice header, pps and sps */
2637
0
    ps_slice_hdr += (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1));
2638
0
    ps_pps  += ps_slice_hdr->i1_pps_id;
2639
0
    ps_sps  += ps_pps->i1_sps_id;
2640
2641
0
    if(0 != ps_codec->s_parse.i4_cur_slice_idx)
2642
0
    {
2643
0
        if(!ps_slice_hdr->i1_dependent_slice_flag)
2644
0
        {
2645
0
            ps_codec->s_parse.i4_cur_independent_slice_idx =
2646
0
                    ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1);
2647
0
        }
2648
0
    }
2649
2650
2651
0
    ctb_size = 1 << ps_sps->i1_log2_ctb_size;
2652
0
    num_min4x4_in_ctb = (ctb_size / 4) * (ctb_size / 4);
2653
0
    num_ctb_in_row = ps_sps->i2_pic_wd_in_ctb;
2654
2655
    /* Update the parse context */
2656
0
    if(0 == ps_codec->i4_slice_error)
2657
0
    {
2658
0
        ps_codec->s_parse.i4_ctb_x = ps_slice_hdr->i2_ctb_x;
2659
0
        ps_codec->s_parse.i4_ctb_y = ps_slice_hdr->i2_ctb_y;
2660
0
    }
2661
0
    ps_codec->s_parse.ps_pps = ps_pps;
2662
0
    ps_codec->s_parse.ps_sps = ps_sps;
2663
0
    ps_codec->s_parse.ps_slice_hdr = ps_slice_hdr;
2664
2665
    /* Derive Tile positions for the current CTB */
2666
    /* Change this to lookup if required */
2667
0
    ihevcd_get_tile_pos(ps_pps, ps_sps, ps_codec->s_parse.i4_ctb_x,
2668
0
                        ps_codec->s_parse.i4_ctb_y,
2669
0
                        &ps_codec->s_parse.i4_ctb_tile_x,
2670
0
                        &ps_codec->s_parse.i4_ctb_tile_y,
2671
0
                        &tile_idx);
2672
0
    ps_codec->s_parse.ps_tile = ps_pps->ps_tile + tile_idx;
2673
0
    ps_codec->s_parse.i4_cur_tile_idx = tile_idx;
2674
0
    ps_tile = ps_codec->s_parse.ps_tile;
2675
0
    if(tile_idx)
2676
0
        ps_tile_prev = ps_tile - 1;
2677
0
    else
2678
0
        ps_tile_prev = ps_tile;
2679
2680
    /* If the present slice is dependent, then store the previous
2681
     * independent slices' ctb x and y values for decoding process */
2682
0
    if(0 == ps_codec->i4_slice_error)
2683
0
    {
2684
0
        if(1 == ps_slice_hdr->i1_dependent_slice_flag)
2685
0
        {
2686
            /*If slice is present at the start of a new tile*/
2687
0
            if((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y))
2688
0
            {
2689
0
                ps_codec->s_parse.i4_ctb_slice_x = 0;
2690
0
                ps_codec->s_parse.i4_ctb_slice_y = 0;
2691
0
            }
2692
0
        }
2693
2694
0
        if(!ps_slice_hdr->i1_dependent_slice_flag)
2695
0
        {
2696
0
            ps_codec->s_parse.i4_ctb_slice_x = 0;
2697
0
            ps_codec->s_parse.i4_ctb_slice_y = 0;
2698
0
        }
2699
0
    }
2700
2701
    /* Frame level initializations */
2702
0
    if((0 == ps_codec->s_parse.i4_ctb_y) &&
2703
0
                    (0 == ps_codec->s_parse.i4_ctb_x))
2704
0
    {
2705
0
        ret = ihevcd_parse_pic_init(ps_codec);
2706
0
        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
2707
2708
0
        ps_codec->s_parse.pu4_pic_tu_idx[0] = 0;
2709
0
        ps_codec->s_parse.pu4_pic_pu_idx[0] = 0;
2710
0
        ps_codec->s_parse.i4_cur_independent_slice_idx = 0;
2711
0
        ps_codec->s_parse.i4_ctb_tile_x = 0;
2712
0
        ps_codec->s_parse.i4_ctb_tile_y = 0;
2713
0
    }
2714
2715
0
    {
2716
        /* Updating the poc list of current slice to ps_mv_buf */
2717
0
        mv_buf_t *ps_mv_buf = ps_codec->s_parse.ps_cur_mv_buf;
2718
2719
0
        if(ps_slice_hdr->i1_num_ref_idx_l1_active != 0)
2720
0
        {
2721
0
            for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l1_active; i++)
2722
0
            {
2723
0
                ps_mv_buf->ai4_l1_collocated_poc[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_pic_buf)->i4_abs_poc;
2724
0
                ps_mv_buf->ai1_l1_collocated_poc_lt[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_pic_buf)->u1_used_as_ref;
2725
0
            }
2726
0
        }
2727
2728
0
        if(ps_slice_hdr->i1_num_ref_idx_l0_active != 0)
2729
0
        {
2730
0
            for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l0_active; i++)
2731
0
            {
2732
0
                ps_mv_buf->ai4_l0_collocated_poc[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_pic_buf)->i4_abs_poc;
2733
0
                ps_mv_buf->ai1_l0_collocated_poc_lt[(ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1))][i] = ((pic_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_pic_buf)->u1_used_as_ref;
2734
0
            }
2735
0
        }
2736
0
    }
2737
2738
    /*Initialize the low delay flag at the beginning of every slice*/
2739
0
    if((0 == ps_codec->s_parse.i4_ctb_slice_x) || (0 == ps_codec->s_parse.i4_ctb_slice_y))
2740
0
    {
2741
        /* Lowdelay flag */
2742
0
        WORD32 cur_poc, ref_list_poc, flag = 1;
2743
0
        cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
2744
0
        for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l0_active; i++)
2745
0
        {
2746
0
            ref_list_poc = ((mv_buf_t *)ps_slice_hdr->as_ref_pic_list0[i].pv_mv_buf)->i4_abs_poc;
2747
0
            if(ref_list_poc > cur_poc)
2748
0
            {
2749
0
                flag = 0;
2750
0
                break;
2751
0
            }
2752
0
        }
2753
0
        if(flag && (ps_slice_hdr->i1_slice_type == BSLICE))
2754
0
        {
2755
0
            for(i = 0; i < ps_slice_hdr->i1_num_ref_idx_l1_active; i++)
2756
0
            {
2757
0
                ref_list_poc = ((mv_buf_t *)ps_slice_hdr->as_ref_pic_list1[i].pv_mv_buf)->i4_abs_poc;
2758
0
                if(ref_list_poc > cur_poc)
2759
0
                {
2760
0
                    flag = 0;
2761
0
                    break;
2762
0
                }
2763
0
            }
2764
0
        }
2765
0
        ps_slice_hdr->i1_low_delay_flag = flag;
2766
0
    }
2767
2768
    /* initialize the cabac init idc based on slice type */
2769
0
    if(ps_slice_hdr->i1_slice_type == ISLICE)
2770
0
    {
2771
0
        cabac_init_idc = 0;
2772
0
    }
2773
0
    else if(ps_slice_hdr->i1_slice_type == PSLICE)
2774
0
    {
2775
0
        cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 2 : 1;
2776
0
    }
2777
0
    else
2778
0
    {
2779
0
        cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 1 : 2;
2780
0
    }
2781
2782
0
    slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp;
2783
0
    slice_qp = CLIP3(slice_qp, 0, 51);
2784
2785
    /*Update QP value for every indepndent slice or for every dependent slice that begins at the start of a new tile*/
2786
0
    if((0 == ps_slice_hdr->i1_dependent_slice_flag) ||
2787
0
                    ((1 == ps_slice_hdr->i1_dependent_slice_flag) && ((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y))))
2788
0
    {
2789
0
        ps_codec->s_parse.u4_qp = slice_qp;
2790
0
    }
2791
2792
    /*Cabac init at the beginning of a slice*/
2793
    //If the slice is a dependent slice, not present at the start of a tile
2794
0
    if(0 == ps_codec->i4_slice_error)
2795
0
    {
2796
0
        if((1 == ps_slice_hdr->i1_dependent_slice_flag) && (!((ps_codec->s_parse.i4_ctb_tile_x == 0) && (ps_codec->s_parse.i4_ctb_tile_y == 0))))
2797
0
        {
2798
0
            if((0 == ps_pps->i1_entropy_coding_sync_enabled_flag) || (ps_pps->i1_entropy_coding_sync_enabled_flag && (0 != ps_codec->s_parse.i4_ctb_x)))
2799
0
            {
2800
0
                ihevcd_cabac_reset(&ps_codec->s_parse.s_cabac,
2801
0
                                   &ps_codec->s_parse.s_bitstrm);
2802
0
            }
2803
0
        }
2804
0
        else if((0 == ps_pps->i1_entropy_coding_sync_enabled_flag) || (ps_pps->i1_entropy_coding_sync_enabled_flag && (0 != ps_codec->s_parse.i4_ctb_x)))
2805
0
        {
2806
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2807
0
            WORD32 ai4_stats[4] = {0};
2808
0
#endif
2809
0
            ret = ihevcd_cabac_init(&ps_codec->s_parse.s_cabac,
2810
0
                                    &ps_codec->s_parse.s_bitstrm,
2811
0
                                    slice_qp,
2812
0
                                    cabac_init_idc,
2813
0
                                    &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0]
2814
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2815
0
                                    ,
2816
0
                                    ps_sps->i1_persistent_rice_adaptation_enabled_flag ? ai4_stats : NULL
2817
0
#endif
2818
0
                                    );
2819
0
            if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
2820
0
            {
2821
0
                ps_codec->i4_slice_error = 1;
2822
0
                end_of_slice_flag = 1;
2823
0
                ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
2824
0
            }
2825
0
        }
2826
0
    }
2827
2828
2829
0
    do
2830
0
    {
2831
2832
0
        {
2833
0
            WORD32 cur_ctb_idx = ps_codec->s_parse.i4_ctb_x
2834
0
                            + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb);
2835
0
            if(1 == ps_codec->i4_num_cores && 0 == cur_ctb_idx % RESET_TU_BUF_NCTB)
2836
0
            {
2837
0
                ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
2838
0
                ps_codec->s_parse.i4_pic_tu_idx = 0;
2839
0
            }
2840
0
        }
2841
2842
0
        end_of_pic = 0;
2843
        /* Section:7.3.7 Coding tree unit syntax */
2844
        /* coding_tree_unit() inlined here */
2845
        /* If number of cores is greater than 1, then add job to the queue */
2846
        //TODO: Dual core implementation might need a different algo for better load balancing
2847
        /* At the start of ctb row parsing in a tile, queue a job for processing the current tile row */
2848
0
        ps_codec->s_parse.i4_ctb_num_pcm_blks = 0;
2849
2850
2851
        /*At the beginning of each tile-which is not the beginning of a slice, cabac context must be initialized.
2852
         * Hence, check for the tile beginning here */
2853
0
        if(((0 == ps_codec->s_parse.i4_ctb_tile_x) && (0 == ps_codec->s_parse.i4_ctb_tile_y))
2854
0
                        && (!((ps_tile->u1_pos_x == 0) && (ps_tile->u1_pos_y == 0)))
2855
0
                        && (!((0 == ps_codec->s_parse.i4_ctb_slice_x) && (0 == ps_codec->s_parse.i4_ctb_slice_y))))
2856
0
        {
2857
0
            slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp;
2858
0
            slice_qp = CLIP3(slice_qp, 0, 51);
2859
0
            ps_codec->s_parse.u4_qp = slice_qp;
2860
2861
0
            ihevcd_get_tile_pos(ps_pps, ps_sps, ps_codec->s_parse.i4_ctb_x,
2862
0
                                ps_codec->s_parse.i4_ctb_y,
2863
0
                                &ps_codec->s_parse.i4_ctb_tile_x,
2864
0
                                &ps_codec->s_parse.i4_ctb_tile_y,
2865
0
                                &tile_idx);
2866
2867
0
            ps_codec->s_parse.ps_tile = ps_pps->ps_tile + tile_idx;
2868
0
            ps_codec->s_parse.i4_cur_tile_idx = tile_idx;
2869
0
            ps_tile_prev = ps_tile - 1;
2870
2871
0
            tile_start_ctb_idx = ps_tile->u1_pos_x
2872
0
                            + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb);
2873
2874
0
            slice_start_ctb_idx =  ps_slice_hdr->i2_ctb_x
2875
0
                            + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb);
2876
2877
            /*For slices that span across multiple tiles*/
2878
0
            if(slice_start_ctb_idx < tile_start_ctb_idx)
2879
0
            {       /* 2 Cases
2880
             * 1 - slice spans across frame-width- but does not start from 1st column
2881
             * 2 - Slice spans across multiple tiles anywhere is a frame
2882
             */
2883
0
                ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y - ps_slice_hdr->i2_ctb_y;
2884
0
                if(!(((ps_slice_hdr->i2_ctb_x + ps_tile_prev->u2_wd) % ps_sps->i2_pic_wd_in_ctb) == ps_tile->u1_pos_x)) //Case 2
2885
0
                {
2886
0
                    if(ps_slice_hdr->i2_ctb_y <= ps_tile->u1_pos_y)
2887
0
                    {
2888
                        //Check if ctb x is before or after
2889
0
                        if(ps_slice_hdr->i2_ctb_x > ps_tile->u1_pos_x)
2890
0
                        {
2891
0
                            ps_codec->s_parse.i4_ctb_slice_y -= 1;
2892
0
                        }
2893
0
                    }
2894
0
                }
2895
                /*ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y - ps_slice_hdr->i2_ctb_y;
2896
                if (ps_slice_hdr->i2_ctb_y <= ps_tile->u1_pos_y)
2897
                {
2898
                    //Check if ctb x is before or after
2899
                    if (ps_slice_hdr->i2_ctb_x > ps_tile->u1_pos_x )
2900
                    {
2901
                        ps_codec->s_parse.i4_ctb_slice_y -= 1 ;
2902
                    }
2903
                }*/
2904
0
            }
2905
2906
            /* Cabac init is done unconditionally at the start of the tile irrespective
2907
             * of whether it is a dependent or an independent slice */
2908
0
            if(0 == ps_codec->i4_slice_error)
2909
0
            {
2910
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2911
0
            WORD32 ai4_stats[4] = {0};
2912
0
#endif
2913
0
                ret = ihevcd_cabac_init(&ps_codec->s_parse.s_cabac,
2914
0
                                        &ps_codec->s_parse.s_bitstrm,
2915
0
                                        slice_qp,
2916
0
                                        cabac_init_idc,
2917
0
                                        &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0]
2918
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2919
0
                                        ,
2920
0
                                        ps_sps->i1_persistent_rice_adaptation_enabled_flag ? ai4_stats : NULL
2921
0
#endif
2922
0
                                        );
2923
0
                if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
2924
0
                {
2925
0
                    ps_codec->i4_slice_error = 1;
2926
0
                    end_of_slice_flag = 1;
2927
0
                    ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
2928
0
                }
2929
2930
0
            }
2931
0
        }
2932
        /* If number of cores is greater than 1, then add job to the queue */
2933
        //TODO: Dual core implementation might need a different algo for better load balancing
2934
        /* At the start of ctb row parsing in a tile, queue a job for processing the current tile row */
2935
2936
0
        if(0 == ps_codec->s_parse.i4_ctb_tile_x)
2937
0
        {
2938
2939
0
            if(1 < ps_codec->i4_num_cores)
2940
0
            {
2941
0
                proc_job_t s_job;
2942
0
                IHEVCD_ERROR_T ret;
2943
0
                s_job.i4_cmd    = CMD_PROCESS;
2944
0
                s_job.i2_ctb_cnt = (WORD16)ps_tile->u2_wd;
2945
0
                s_job.i2_ctb_x = (WORD16)ps_codec->s_parse.i4_ctb_x;
2946
0
                s_job.i2_ctb_y = (WORD16)ps_codec->s_parse.i4_ctb_y;
2947
0
                s_job.i2_slice_idx = (WORD16)ps_codec->s_parse.i4_cur_slice_idx;
2948
0
                s_job.i4_tu_coeff_data_ofst = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data -
2949
0
                                (UWORD8 *)ps_codec->s_parse.pv_pic_tu_coeff_data;
2950
0
                ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq, &s_job, sizeof(proc_job_t), 1);
2951
2952
0
                if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
2953
0
                    return ret;
2954
0
            }
2955
0
            else
2956
0
            {
2957
0
                process_ctxt_t *ps_proc = &ps_codec->as_process[0];
2958
0
                WORD32 tu_coeff_data_ofst = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data -
2959
0
                                (UWORD8 *)ps_codec->s_parse.pv_pic_tu_coeff_data;
2960
2961
                /* If the codec is running in single core mode,
2962
                 * initialize zeroth process context
2963
                 * TODO: Dual core mode might need a different implementation instead of jobq
2964
                 */
2965
2966
0
                ps_proc->i4_ctb_cnt = ps_tile->u2_wd;
2967
0
                ps_proc->i4_ctb_x   = ps_codec->s_parse.i4_ctb_x;
2968
0
                ps_proc->i4_ctb_y   = ps_codec->s_parse.i4_ctb_y;
2969
0
                ps_proc->i4_cur_slice_idx = ps_codec->s_parse.i4_cur_slice_idx;
2970
2971
0
                ihevcd_init_proc_ctxt(ps_proc, tu_coeff_data_ofst);
2972
0
            }
2973
0
        }
2974
2975
2976
        /* Restore cabac context model from top right CTB if entropy sync is enabled */
2977
0
        if(ps_pps->i1_entropy_coding_sync_enabled_flag)
2978
0
        {
2979
            /*TODO Handle single CTB and top-right belonging to a different slice */
2980
0
            if(0 == ps_codec->s_parse.i4_ctb_x && 0 == ps_codec->i4_slice_error)
2981
0
            {
2982
                //WORD32 size = sizeof(ps_codec->s_parse.s_cabac.au1_ctxt_models);
2983
0
                WORD32 default_ctxt = 0;
2984
2985
0
                if((0 == ps_codec->s_parse.i4_ctb_slice_y) && (!ps_slice_hdr->i1_dependent_slice_flag))
2986
0
                    default_ctxt = 1;
2987
0
                if(1 == ps_sps->i2_pic_wd_in_ctb)
2988
0
                    default_ctxt = 1;
2989
2990
0
                ps_codec->s_parse.u4_qp = slice_qp;
2991
0
                if(default_ctxt)
2992
0
                {
2993
0
#ifdef ENABLE_MAIN_REXT_PROFILE
2994
0
                    WORD32 ai4_stats[4] = {0};
2995
0
#endif
2996
                    //memcpy(&ps_codec->s_parse.s_cabac.au1_ctxt_models, &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0], size);
2997
0
                    ret = ihevcd_cabac_init(&ps_codec->s_parse.s_cabac,
2998
0
                                            &ps_codec->s_parse.s_bitstrm,
2999
0
                                            slice_qp,
3000
0
                                            cabac_init_idc,
3001
0
                                            &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0]
3002
0
#ifdef ENABLE_MAIN_REXT_PROFILE
3003
0
                                            ,
3004
0
                                            ps_sps->i1_persistent_rice_adaptation_enabled_flag ? ai4_stats : NULL
3005
0
#endif
3006
0
                                            );
3007
3008
0
                    if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
3009
0
                    {
3010
0
                        ps_codec->i4_slice_error = 1;
3011
0
                        end_of_slice_flag = 1;
3012
0
                        ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
3013
0
                    }
3014
0
                }
3015
0
                else
3016
0
                {
3017
                    //memcpy(&ps_codec->s_parse.s_cabac.au1_ctxt_models, &ps_codec->s_parse.s_cabac.au1_ctxt_models_sync, size);
3018
0
                    ret = ihevcd_cabac_init(&ps_codec->s_parse.s_cabac,
3019
0
                                            &ps_codec->s_parse.s_bitstrm,
3020
0
                                            slice_qp,
3021
0
                                            cabac_init_idc,
3022
0
                                            (const UWORD8 *)&ps_codec->s_parse.s_cabac.au1_ctxt_models_sync
3023
0
#ifdef ENABLE_MAIN_REXT_PROFILE
3024
0
                                            ,
3025
0
                                            ps_sps->i1_persistent_rice_adaptation_enabled_flag ?
3026
0
                                                            ps_codec->s_parse.s_cabac.ai4_rice_stat_coeff_sync :
3027
0
                                                            NULL
3028
0
#endif
3029
0
                                            );
3030
3031
0
                    if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
3032
0
                    {
3033
0
                        ps_codec->i4_slice_error = 1;
3034
0
                        end_of_slice_flag = 1;
3035
0
                        ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
3036
0
                    }
3037
0
                }
3038
0
            }
3039
0
        }
3040
3041
3042
3043
0
        if(0 == ps_codec->i4_slice_error)
3044
0
        {
3045
0
            if(ps_slice_hdr->i1_slice_sao_luma_flag || ps_slice_hdr->i1_slice_sao_chroma_flag)
3046
0
                ihevcd_parse_sao(ps_codec);
3047
0
        }
3048
0
        else
3049
0
        {
3050
0
            sao_t *ps_sao = ps_codec->s_parse.ps_pic_sao +
3051
0
                            ps_codec->s_parse.i4_ctb_x +
3052
0
                            ps_codec->s_parse.i4_ctb_y * ps_sps->i2_pic_wd_in_ctb;
3053
3054
            /* Default values */
3055
0
            ps_sao->b3_y_type_idx = 0;
3056
0
            ps_sao->b3_cb_type_idx = 0;
3057
0
            ps_sao->b3_cr_type_idx = 0;
3058
0
        }
3059
3060
        //AEV_TRACE("CTB x", ps_codec->s_parse.i4_ctb_x, 0);
3061
        //AEV_TRACE("CTB y", ps_codec->s_parse.i4_ctb_y, 0);
3062
3063
0
        {
3064
0
            WORD32 ctb_indx;
3065
0
            ctb_indx = ps_codec->s_parse.i4_ctb_x + ps_sps->i2_pic_wd_in_ctb * ps_codec->s_parse.i4_ctb_y;
3066
0
            ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb[ctb_indx >> 3] |= (1 << (ctb_indx & 7));
3067
0
            {
3068
0
                UWORD16 *pu1_slice_idx = ps_codec->s_parse.pu1_slice_idx;
3069
0
                pu1_slice_idx[ctb_indx] = ps_codec->s_parse.i4_cur_independent_slice_idx;
3070
0
            }
3071
0
        }
3072
3073
0
        if(0 == ps_codec->i4_slice_error)
3074
0
        {
3075
0
            tu_t *ps_tu = ps_codec->s_parse.ps_tu;
3076
0
            WORD32 i4_tu_cnt = ps_codec->s_parse.s_cu.i4_tu_cnt;
3077
0
            WORD32 i4_pic_tu_idx = ps_codec->s_parse.i4_pic_tu_idx;
3078
3079
0
            pu_t *ps_pu = ps_codec->s_parse.ps_pu;
3080
0
            WORD32 i4_pic_pu_idx = ps_codec->s_parse.i4_pic_pu_idx;
3081
3082
0
            UWORD8 *pu1_tu_coeff_data = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data;
3083
3084
0
            ret = ihevcd_parse_coding_quadtree(ps_codec,
3085
0
                                               (ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size),
3086
0
                                               (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size),
3087
0
                                               ps_sps->i1_log2_ctb_size,
3088
0
                                               0);
3089
            /* Check for error */
3090
0
            if (ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
3091
0
            {
3092
                /* Reset tu and pu parameters, and signal current ctb as skip */
3093
0
                WORD32 tu_coeff_data_reset_size;
3094
3095
0
                ps_codec->s_parse.ps_tu = ps_tu;
3096
0
                ps_codec->s_parse.s_cu.i4_tu_cnt = i4_tu_cnt;
3097
0
                ps_codec->s_parse.i4_pic_tu_idx = i4_pic_tu_idx;
3098
3099
0
                ps_codec->s_parse.ps_pu = ps_pu;
3100
0
                ps_codec->s_parse.i4_pic_pu_idx = i4_pic_pu_idx;
3101
3102
0
                tu_coeff_data_reset_size = (UWORD8 *)ps_codec->s_parse.pv_tu_coeff_data - pu1_tu_coeff_data;
3103
0
                memset(pu1_tu_coeff_data, 0, tu_coeff_data_reset_size);
3104
0
                ps_codec->s_parse.pv_tu_coeff_data = (void *)pu1_tu_coeff_data;
3105
3106
0
                ihevcd_set_ctb_skip(ps_codec);
3107
3108
                /* Set slice error to suppress further parsing and
3109
                 * signal end of slice.
3110
                 */
3111
0
                ps_codec->i4_slice_error = 1;
3112
0
                end_of_slice_flag = 1;
3113
0
                ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
3114
0
            }
3115
0
        }
3116
0
        else
3117
0
        {
3118
0
            ihevcd_set_ctb_skip(ps_codec);
3119
0
        }
3120
3121
0
        if(0 == ps_codec->i4_slice_error)
3122
0
            end_of_slice_flag = ihevcd_cabac_decode_terminate(&ps_codec->s_parse.s_cabac, &ps_codec->s_parse.s_bitstrm);
3123
3124
0
        AEV_TRACE("end_of_slice_flag", end_of_slice_flag, ps_codec->s_parse.s_cabac.u4_range);
3125
3126
3127
        /* In case of tiles or entropy sync, terminate cabac and copy cabac context backed up at the end of top-right CTB */
3128
0
        if(ps_pps->i1_tiles_enabled_flag || ps_pps->i1_entropy_coding_sync_enabled_flag)
3129
0
        {
3130
0
            WORD32 end_of_tile = 0;
3131
0
            WORD32 end_of_tile_row = 0;
3132
3133
            /* Take a back up of cabac context models if entropy sync is enabled */
3134
0
            if(ps_pps->i1_entropy_coding_sync_enabled_flag || ps_pps->i1_tiles_enabled_flag)
3135
0
            {
3136
0
                if(1 == ps_codec->s_parse.i4_ctb_x)
3137
0
                {
3138
0
                    WORD32 size = sizeof(ps_codec->s_parse.s_cabac.au1_ctxt_models);
3139
0
                    memcpy(&ps_codec->s_parse.s_cabac.au1_ctxt_models_sync, &ps_codec->s_parse.s_cabac.au1_ctxt_models, size);
3140
3141
0
#ifdef ENABLE_MAIN_REXT_PROFILE
3142
0
                    size = sizeof(ps_codec->s_parse.s_cabac.ai4_rice_stat_coeff_sync);
3143
0
                    memcpy(&ps_codec->s_parse.s_cabac.ai4_rice_stat_coeff_sync, &ps_codec->s_parse.s_cabac.ai4_rice_stat_coeff, size);
3144
0
#endif
3145
0
                }
3146
0
            }
3147
3148
            /* Since tiles and entropy sync are not enabled simultaneously, the following will not result in any problems */
3149
0
            if((ps_codec->s_parse.i4_ctb_tile_x + 1) == (ps_tile->u2_wd))
3150
0
            {
3151
0
                end_of_tile_row = 1;
3152
0
                if((ps_codec->s_parse.i4_ctb_tile_y + 1) == ps_tile->u2_ht)
3153
0
                    end_of_tile = 1;
3154
0
            }
3155
0
            if((0 == end_of_slice_flag) && (0 == ps_codec->i4_slice_error) &&
3156
0
                            ((ps_pps->i1_tiles_enabled_flag && end_of_tile) ||
3157
0
                                            (ps_pps->i1_entropy_coding_sync_enabled_flag && end_of_tile_row)))
3158
0
            {
3159
0
                WORD32 end_of_sub_stream_one_bit;
3160
0
                end_of_sub_stream_one_bit = ihevcd_cabac_decode_terminate(&ps_codec->s_parse.s_cabac, &ps_codec->s_parse.s_bitstrm);
3161
0
                AEV_TRACE("end_of_sub_stream_one_bit", end_of_sub_stream_one_bit, ps_codec->s_parse.s_cabac.u4_range);
3162
3163
                /* TODO: Remove the check for offset when HM is updated to include a byte unconditionally even for aligned location */
3164
                /* For Ittiam streams this check should not be there, for HM9.1 streams this should be there */
3165
0
                if(ps_codec->s_parse.s_bitstrm.u4_bit_ofst % 8)
3166
0
                    ihevcd_bits_flush_to_byte_boundary(&ps_codec->s_parse.s_bitstrm);
3167
3168
0
                UNUSED(end_of_sub_stream_one_bit);
3169
0
            }
3170
0
        }
3171
0
        {
3172
0
            WORD32 ctb_indx;
3173
3174
0
            ctb_addr = ps_codec->s_parse.i4_ctb_y * num_ctb_in_row + ps_codec->s_parse.i4_ctb_x;
3175
3176
0
            ctb_indx = ++ctb_addr;
3177
3178
            /* Store pu_idx for next CTB in frame level pu_idx array */
3179
3180
            //In case of multiple tiles, if end-of-tile row is reached
3181
0
            if((ps_tile->u2_wd == (ps_codec->s_parse.i4_ctb_tile_x + 1)) && (ps_tile->u2_wd != ps_sps->i2_pic_wd_in_ctb))
3182
0
            {
3183
0
                ctb_indx = (ps_sps->i2_pic_wd_in_ctb * (ps_codec->s_parse.i4_ctb_tile_y + 1 + ps_tile->u1_pos_y)) + ps_tile->u1_pos_x; //idx is the beginning of next row in current tile.
3184
0
                if(ps_tile->u2_ht == (ps_codec->s_parse.i4_ctb_tile_y + 1))
3185
0
                {
3186
                    //If the current ctb is the last tile's last ctb
3187
0
                    if((ps_tile->u2_wd + ps_tile->u1_pos_x == ps_sps->i2_pic_wd_in_ctb) && ((ps_tile->u2_ht + ps_tile->u1_pos_y == ps_sps->i2_pic_ht_in_ctb)))
3188
0
                    {
3189
0
                        ctb_indx = ctb_addr; //Next continuous ctb address
3190
0
                    }
3191
0
                    else //Not last tile's end , but a tile end
3192
0
                    {
3193
0
                        tile_t *ps_next_tile = ps_codec->s_parse.ps_tile + 1;
3194
0
                        ctb_indx = ps_next_tile->u1_pos_x + (ps_next_tile->u1_pos_y * ps_sps->i2_pic_wd_in_ctb); //idx is the beginning of first row in next tile.
3195
0
                    }
3196
0
                }
3197
0
            }
3198
3199
0
            ps_codec->s_parse.pu4_pic_pu_idx[ctb_indx] = ps_codec->s_parse.i4_pic_pu_idx;
3200
0
            ps_codec->s_parse.i4_next_pu_ctb_cnt = ctb_indx;
3201
3202
0
            ps_codec->s_parse.pu1_pu_map += num_min4x4_in_ctb;
3203
3204
            /* Store tu_idx for next CTB in frame level tu_idx array */
3205
0
            if(1 == ps_codec->i4_num_cores)
3206
0
            {
3207
0
                ctb_indx = (0 == ctb_addr % RESET_TU_BUF_NCTB) ?
3208
0
                                RESET_TU_BUF_NCTB : ctb_addr % RESET_TU_BUF_NCTB;
3209
3210
                //In case of multiple tiles, if end-of-tile row is reached
3211
0
                if((ps_tile->u2_wd == (ps_codec->s_parse.i4_ctb_tile_x + 1)) && (ps_tile->u2_wd != ps_sps->i2_pic_wd_in_ctb))
3212
0
                {
3213
0
                    ctb_indx = (ps_sps->i2_pic_wd_in_ctb * (ps_codec->s_parse.i4_ctb_tile_y + 1 + ps_tile->u1_pos_y)) + ps_tile->u1_pos_x; //idx is the beginning of next row in current tile.
3214
0
                    if(ps_tile->u2_ht == (ps_codec->s_parse.i4_ctb_tile_y + 1))
3215
0
                    {
3216
                        //If the current ctb is the last tile's last ctb
3217
0
                        if((ps_tile->u2_wd + ps_tile->u1_pos_x == ps_sps->i2_pic_wd_in_ctb) && ((ps_tile->u2_ht + ps_tile->u1_pos_y == ps_sps->i2_pic_ht_in_ctb)))
3218
0
                        {
3219
0
                            ctb_indx = (0 == ctb_addr % RESET_TU_BUF_NCTB) ?
3220
0
                                            RESET_TU_BUF_NCTB : ctb_addr % RESET_TU_BUF_NCTB;
3221
0
                        }
3222
0
                        else  //Not last tile's end , but a tile end
3223
0
                        {
3224
0
                            tile_t *ps_next_tile = ps_codec->s_parse.ps_tile + 1;
3225
0
                            ctb_indx =  ps_next_tile->u1_pos_x + (ps_next_tile->u1_pos_y * ps_sps->i2_pic_wd_in_ctb); //idx is the beginning of first row in next tile.
3226
0
                        }
3227
0
                    }
3228
0
                }
3229
0
                ps_codec->s_parse.i4_next_tu_ctb_cnt = ctb_indx;
3230
0
                ps_codec->s_parse.pu4_pic_tu_idx[ctb_indx] = ps_codec->s_parse.i4_pic_tu_idx;
3231
0
            }
3232
0
            else
3233
0
            {
3234
0
                ctb_indx = ctb_addr;
3235
0
                if((ps_tile->u2_wd == (ps_codec->s_parse.i4_ctb_tile_x + 1)) && (ps_tile->u2_wd != ps_sps->i2_pic_wd_in_ctb))
3236
0
                {
3237
0
                    ctb_indx = (ps_sps->i2_pic_wd_in_ctb * (ps_codec->s_parse.i4_ctb_tile_y + 1 + ps_tile->u1_pos_y)) + ps_tile->u1_pos_x; //idx is the beginning of next row in current tile.
3238
0
                    if(ps_tile->u2_ht == (ps_codec->s_parse.i4_ctb_tile_y + 1))
3239
0
                    {
3240
                        //If the current ctb is the last tile's last ctb
3241
0
                        if((ps_tile->u2_wd + ps_tile->u1_pos_x == ps_sps->i2_pic_wd_in_ctb) && ((ps_tile->u2_ht + ps_tile->u1_pos_y == ps_sps->i2_pic_ht_in_ctb)))
3242
0
                        {
3243
0
                            ctb_indx = ctb_addr;
3244
0
                        }
3245
0
                        else  //Not last tile's end , but a tile end
3246
0
                        {
3247
0
                            tile_t *ps_next_tile = ps_codec->s_parse.ps_tile + 1;
3248
0
                            ctb_indx =  ps_next_tile->u1_pos_x + (ps_next_tile->u1_pos_y * ps_sps->i2_pic_wd_in_ctb); //idx is the beginning of first row in next tile.
3249
0
                        }
3250
0
                    }
3251
0
                }
3252
0
                ps_codec->s_parse.i4_next_tu_ctb_cnt = ctb_indx;
3253
0
                ps_codec->s_parse.pu4_pic_tu_idx[ctb_indx] = ps_codec->s_parse.i4_pic_tu_idx;
3254
0
            }
3255
0
            ps_codec->s_parse.pu1_tu_map += num_min4x4_in_ctb;
3256
0
        }
3257
3258
        /* QP array population has to be done if deblocking is enabled in the picture
3259
         * but some of the slices in the pic have it disabled */
3260
0
        if((0 != ps_codec->i4_disable_deblk_pic) &&
3261
0
                (1 == ps_slice_hdr->i1_slice_disable_deblocking_filter_flag))
3262
0
        {
3263
0
            bs_ctxt_t *ps_bs_ctxt = &ps_codec->s_parse.s_bs_ctxt;
3264
0
            WORD32 log2_ctb_size = ps_sps->i1_log2_ctb_size;
3265
0
            UWORD8 *pu1_qp;
3266
0
            WORD32 qp_strd;
3267
0
            WORD32 u4_qp_const_in_ctb;
3268
0
            WORD32 cur_ctb_idx;
3269
0
            WORD32 next_ctb_idx;
3270
0
            WORD32 cur_tu_idx;
3271
0
            WORD32 i4_ctb_tu_cnt;
3272
0
            tu_t *ps_tu;
3273
3274
0
            cur_ctb_idx = ps_codec->s_parse.i4_ctb_x + ps_sps->i2_pic_wd_in_ctb * ps_codec->s_parse.i4_ctb_y;
3275
            /* ctb_size/8 elements per CTB */
3276
0
            qp_strd = ps_sps->i2_pic_wd_in_ctb << (log2_ctb_size - 3);
3277
0
            pu1_qp = ps_bs_ctxt->pu1_pic_qp + ((ps_codec->s_parse.i4_ctb_x + ps_codec->s_parse.i4_ctb_y * qp_strd) << (log2_ctb_size - 3));
3278
3279
0
            u4_qp_const_in_ctb = ps_bs_ctxt->pu1_pic_qp_const_in_ctb[cur_ctb_idx >> 3] & (1 << (cur_ctb_idx & 7));
3280
3281
0
            next_ctb_idx = ps_codec->s_parse.i4_next_tu_ctb_cnt;
3282
0
            if(1 == ps_codec->i4_num_cores)
3283
0
            {
3284
0
                i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] -
3285
0
                                ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB];
3286
3287
0
                cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB];
3288
0
            }
3289
0
            else
3290
0
            {
3291
0
                i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] -
3292
0
                                ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx];
3293
3294
0
                cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx];
3295
0
            }
3296
3297
0
            ps_tu = &ps_codec->s_parse.ps_pic_tu[cur_tu_idx];
3298
3299
0
            if(u4_qp_const_in_ctb)
3300
0
            {
3301
0
                pu1_qp[0] = ps_tu->b7_qp;
3302
0
            }
3303
0
            else
3304
0
            {
3305
0
                for(i = 0; i < i4_ctb_tu_cnt; i++, ps_tu++)
3306
0
                {
3307
0
                    WORD32 start_pos_x;
3308
0
                    WORD32 start_pos_y;
3309
0
                    WORD32 tu_size;
3310
3311
                    /* start_pos_x and start_pos_y are in units of min TU size (4x4) */
3312
0
                    start_pos_x = ps_tu->b4_pos_x;
3313
0
                    start_pos_y = ps_tu->b4_pos_y;
3314
3315
0
                    tu_size = 1 << (ps_tu->b3_size + 2);
3316
0
                    tu_size >>= 2; /* TU size divided by 4 */
3317
3318
0
                    if(0 == (start_pos_x & 1) && 0 == (start_pos_y & 1))
3319
0
                    {
3320
0
                        WORD32 row, col;
3321
0
                        for(row = start_pos_y; row < start_pos_y + tu_size; row += 2)
3322
0
                        {
3323
0
                            for(col = start_pos_x; col < start_pos_x + tu_size; col += 2)
3324
0
                            {
3325
0
                                pu1_qp[(row >> 1) * qp_strd + (col >> 1)] = ps_tu->b7_qp;
3326
0
                            }
3327
0
                        }
3328
0
                    }
3329
0
                }
3330
0
            }
3331
0
        }
3332
3333
0
        if(ps_codec->i4_num_cores <= MV_PRED_NUM_CORES_THRESHOLD)
3334
0
        {
3335
            /*************************************************/
3336
            /****************   MV pred **********************/
3337
            /*************************************************/
3338
0
            WORD8 u1_top_ctb_avail = 1;
3339
0
            WORD8 u1_left_ctb_avail = 1;
3340
0
            WORD8 u1_top_lt_ctb_avail = 1;
3341
0
            WORD8 u1_top_rt_ctb_avail = 1;
3342
0
            WORD16 i2_wd_in_ctb;
3343
3344
0
            tile_start_ctb_idx = ps_tile->u1_pos_x
3345
0
                            + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb);
3346
3347
0
            slice_start_ctb_idx =  ps_slice_hdr->i2_ctb_x
3348
0
                            + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb);
3349
3350
0
            if((slice_start_ctb_idx < tile_start_ctb_idx))
3351
0
            {
3352
                //Slices span across multiple tiles.
3353
0
                i2_wd_in_ctb = ps_sps->i2_pic_wd_in_ctb;
3354
0
            }
3355
0
            else
3356
0
            {
3357
0
                i2_wd_in_ctb = ps_tile->u2_wd;
3358
0
            }
3359
            /* slice and tile boundaries */
3360
0
            if((0 == ps_codec->s_parse.i4_ctb_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y))
3361
0
            {
3362
0
                u1_top_ctb_avail = 0;
3363
0
                u1_top_lt_ctb_avail = 0;
3364
0
                u1_top_rt_ctb_avail = 0;
3365
0
            }
3366
3367
0
            if((0 == ps_codec->s_parse.i4_ctb_x) || (0 == ps_codec->s_parse.i4_ctb_tile_x))
3368
0
            {
3369
0
                u1_left_ctb_avail = 0;
3370
0
                u1_top_lt_ctb_avail = 0;
3371
0
                if((0 == ps_codec->s_parse.i4_ctb_slice_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y))
3372
0
                {
3373
0
                    u1_top_ctb_avail = 0;
3374
0
                    if((i2_wd_in_ctb - 1) != ps_codec->s_parse.i4_ctb_slice_x) //TODO: For tile, not implemented
3375
0
                    {
3376
0
                        u1_top_rt_ctb_avail = 0;
3377
0
                    }
3378
0
                }
3379
0
            }
3380
            /*For slices not beginning at start of a ctb row*/
3381
0
            else if(ps_codec->s_parse.i4_ctb_x > 0)
3382
0
            {
3383
0
                if((0 == ps_codec->s_parse.i4_ctb_slice_y) || (0 == ps_codec->s_parse.i4_ctb_tile_y))
3384
0
                {
3385
0
                    u1_top_ctb_avail = 0;
3386
0
                    u1_top_lt_ctb_avail = 0;
3387
0
                    if(0 == ps_codec->s_parse.i4_ctb_slice_x)
3388
0
                    {
3389
0
                        u1_left_ctb_avail = 0;
3390
0
                    }
3391
0
                    if((i2_wd_in_ctb - 1) != ps_codec->s_parse.i4_ctb_slice_x)
3392
0
                    {
3393
0
                        u1_top_rt_ctb_avail = 0;
3394
0
                    }
3395
0
                }
3396
0
                else if((1 == ps_codec->s_parse.i4_ctb_slice_y) && (0 == ps_codec->s_parse.i4_ctb_slice_x))
3397
0
                {
3398
0
                    u1_top_lt_ctb_avail = 0;
3399
0
                }
3400
0
            }
3401
3402
0
            if(((ps_sps->i2_pic_wd_in_ctb - 1) == ps_codec->s_parse.i4_ctb_x) || ((ps_tile->u2_wd - 1) == ps_codec->s_parse.i4_ctb_tile_x))
3403
0
            {
3404
0
                u1_top_rt_ctb_avail = 0;
3405
0
            }
3406
3407
0
            if(PSLICE == ps_slice_hdr->i1_slice_type
3408
0
                            || BSLICE == ps_slice_hdr->i1_slice_type)
3409
0
            {
3410
0
                mv_ctxt_t s_mv_ctxt;
3411
0
                process_ctxt_t *ps_proc;
3412
0
                UWORD32 *pu4_ctb_top_pu_idx;
3413
0
                UWORD32 *pu4_ctb_left_pu_idx;
3414
0
                UWORD32 *pu4_ctb_top_left_pu_idx;
3415
0
                WORD32 i4_ctb_pu_cnt;
3416
0
                WORD32 cur_ctb_idx;
3417
0
                WORD32 next_ctb_idx;
3418
0
                WORD32 cur_pu_idx;
3419
0
                ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)];
3420
0
                cur_ctb_idx = ps_codec->s_parse.i4_ctb_x
3421
0
                                + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb);
3422
0
                next_ctb_idx = ps_codec->s_parse.i4_next_pu_ctb_cnt;
3423
0
                i4_ctb_pu_cnt = ps_codec->s_parse.pu4_pic_pu_idx[next_ctb_idx]
3424
0
                                - ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx];
3425
3426
0
                cur_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx];
3427
3428
0
                pu4_ctb_top_pu_idx = ps_proc->pu4_pic_pu_idx_top
3429
0
                                + (ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE);
3430
0
                pu4_ctb_left_pu_idx = ps_proc->pu4_pic_pu_idx_left;
3431
0
                pu4_ctb_top_left_pu_idx = &ps_proc->u4_ctb_top_left_pu_idx;
3432
3433
                /* Initializing s_mv_ctxt */
3434
0
                {
3435
0
                    s_mv_ctxt.ps_pps = ps_pps;
3436
0
                    s_mv_ctxt.ps_sps = ps_sps;
3437
0
                    s_mv_ctxt.ps_slice_hdr = ps_slice_hdr;
3438
0
                    s_mv_ctxt.i4_ctb_x = ps_codec->s_parse.i4_ctb_x;
3439
0
                    s_mv_ctxt.i4_ctb_y = ps_codec->s_parse.i4_ctb_y;
3440
0
                    s_mv_ctxt.ps_pu = &ps_codec->s_parse.ps_pic_pu[cur_pu_idx];
3441
0
                    s_mv_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
3442
0
                    s_mv_ctxt.ps_tile = ps_tile;
3443
0
                    s_mv_ctxt.pu4_pic_pu_idx_map = ps_proc->pu4_pic_pu_idx_map;
3444
0
                    s_mv_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
3445
0
                    s_mv_ctxt.pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
3446
0
                    s_mv_ctxt.i4_ctb_pu_cnt = i4_ctb_pu_cnt;
3447
0
                    s_mv_ctxt.i4_ctb_start_pu_idx = cur_pu_idx;
3448
0
                    s_mv_ctxt.u1_top_ctb_avail = u1_top_ctb_avail;
3449
0
                    s_mv_ctxt.u1_top_rt_ctb_avail = u1_top_rt_ctb_avail;
3450
0
                    s_mv_ctxt.u1_top_lt_ctb_avail = u1_top_lt_ctb_avail;
3451
0
                    s_mv_ctxt.u1_left_ctb_avail = u1_left_ctb_avail;
3452
0
                }
3453
3454
0
                ihevcd_get_mv_ctb(&s_mv_ctxt, pu4_ctb_top_pu_idx,
3455
0
                                  pu4_ctb_left_pu_idx, pu4_ctb_top_left_pu_idx);
3456
3457
0
            }
3458
0
            else
3459
0
            {
3460
0
                WORD32 num_minpu_in_ctb = (ctb_size / MIN_PU_SIZE) * (ctb_size / MIN_PU_SIZE);
3461
0
                UWORD8 *pu1_pic_pu_map_ctb = ps_codec->s_parse.pu1_pic_pu_map +
3462
0
                                (ps_codec->s_parse.i4_ctb_x + ps_codec->s_parse.i4_ctb_y * ps_sps->i2_pic_wd_in_ctb) * num_minpu_in_ctb;
3463
0
                process_ctxt_t *ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)];
3464
0
                WORD32 row, col;
3465
0
                WORD32 pu_cnt;
3466
0
                WORD32 num_pu_per_ctb;
3467
0
                WORD32 cur_ctb_idx;
3468
0
                WORD32 next_ctb_idx;
3469
0
                WORD32 ctb_start_pu_idx;
3470
0
                UWORD32 *pu4_nbr_pu_idx = ps_proc->pu4_pic_pu_idx_map;
3471
0
                WORD32 nbr_pu_idx_strd = MAX_CTB_SIZE / MIN_PU_SIZE + 2;
3472
0
                pu_t *ps_pu;
3473
0
                WORD32 ctb_size_in_min_pu = (ctb_size / MIN_PU_SIZE);
3474
3475
                /* Neighbor PU idx update inside CTB */
3476
                /* 1byte per 4x4. Indicates the PU idx that 4x4 block belongs to */
3477
3478
0
                cur_ctb_idx = ps_codec->s_parse.i4_ctb_x
3479
0
                                + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb);
3480
0
                next_ctb_idx = ps_codec->s_parse.i4_next_pu_ctb_cnt;
3481
0
                num_pu_per_ctb = ps_codec->s_parse.pu4_pic_pu_idx[next_ctb_idx]
3482
0
                                - ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx];
3483
0
                ctb_start_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx];
3484
0
                ps_pu = &ps_codec->s_parse.ps_pic_pu[ctb_start_pu_idx];
3485
3486
0
                for(pu_cnt = 0; pu_cnt < num_pu_per_ctb; pu_cnt++, ps_pu++)
3487
0
                {
3488
0
                    UWORD32 cur_pu_idx;
3489
0
                    WORD32 pu_ht = (ps_pu->b4_ht + 1) << 2;
3490
0
                    WORD32 pu_wd = (ps_pu->b4_wd + 1) << 2;
3491
3492
0
                    cur_pu_idx = ctb_start_pu_idx + pu_cnt;
3493
3494
0
                    for(row = 0; row < pu_ht / MIN_PU_SIZE; row++)
3495
0
                        for(col = 0; col < pu_wd / MIN_PU_SIZE; col++)
3496
0
                            pu4_nbr_pu_idx[(1 + ps_pu->b4_pos_x + col)
3497
0
                                            + (1 + ps_pu->b4_pos_y + row)
3498
0
                                            * nbr_pu_idx_strd] =
3499
0
                                            cur_pu_idx;
3500
0
                }
3501
3502
                /* Updating Top and Left pointers */
3503
0
                {
3504
0
                    WORD32 rows_remaining = ps_sps->i2_pic_height_in_luma_samples
3505
0
                                    - (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size);
3506
0
                    WORD32 ctb_size_left = MIN(ctb_size, rows_remaining);
3507
3508
                    /* Top Left */
3509
                    /* saving top left before updating top ptr, as updating top ptr will overwrite the top left for the next ctb */
3510
0
                    ps_proc->u4_ctb_top_left_pu_idx = ps_proc->pu4_pic_pu_idx_top[(ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE) + ctb_size / MIN_PU_SIZE - 1];
3511
0
                    for(i = 0; i < ctb_size / MIN_PU_SIZE; i++)
3512
0
                    {
3513
                        /* Left */
3514
                        /* Last column of au4_nbr_pu_idx */
3515
0
                        ps_proc->pu4_pic_pu_idx_left[i] = pu4_nbr_pu_idx[(ctb_size / MIN_PU_SIZE)
3516
0
                                        + (i + 1) * nbr_pu_idx_strd];
3517
                        /* Top */
3518
                        /* Last row of au4_nbr_pu_idx */
3519
0
                        ps_proc->pu4_pic_pu_idx_top[(ps_codec->s_parse.i4_ctb_x * ctb_size / MIN_PU_SIZE) + i] =
3520
0
                                        pu4_nbr_pu_idx[(ctb_size_left / MIN_PU_SIZE) * nbr_pu_idx_strd + i + 1];
3521
3522
0
                    }
3523
0
                }
3524
3525
                /* Updating the CTB level PU idx (Used for collocated MV pred)*/
3526
0
                {
3527
0
                    WORD32 ctb_row, ctb_col, index_pic_map, index_nbr_map;
3528
0
                    WORD32 first_pu_of_ctb;
3529
0
                    first_pu_of_ctb = pu4_nbr_pu_idx[1 + nbr_pu_idx_strd];
3530
0
                    UWORD32 cur_ctb_ht_in_min_pu = MIN(((ps_sps->i2_pic_height_in_luma_samples
3531
0
                            - (ps_codec->s_parse.i4_ctb_y << ps_sps->i1_log2_ctb_size)) / MIN_PU_SIZE), ctb_size_in_min_pu);
3532
0
                    UWORD32 cur_ctb_wd_in_min_pu = MIN(((ps_sps->i2_pic_width_in_luma_samples
3533
0
                                - (ps_codec->s_parse.i4_ctb_x << ps_sps->i1_log2_ctb_size)) / MIN_PU_SIZE), ctb_size_in_min_pu);
3534
3535
0
                    index_pic_map = 0 * ctb_size_in_min_pu + 0;
3536
0
                    index_nbr_map = (0 + 1) * nbr_pu_idx_strd + (0 + 1);
3537
3538
0
                    for(ctb_row = 0; ctb_row < cur_ctb_ht_in_min_pu; ctb_row++)
3539
0
                    {
3540
0
                        for(ctb_col = 0; ctb_col < cur_ctb_wd_in_min_pu; ctb_col++)
3541
0
                        {
3542
0
                            pu1_pic_pu_map_ctb[index_pic_map + ctb_col] = pu4_nbr_pu_idx[index_nbr_map + ctb_col]
3543
0
                                            - first_pu_of_ctb;
3544
0
                        }
3545
0
                        index_pic_map += ctb_size_in_min_pu;
3546
0
                        index_nbr_map += nbr_pu_idx_strd;
3547
0
                    }
3548
0
                }
3549
0
            }
3550
3551
            /*************************************************/
3552
            /******************  BS, QP  *********************/
3553
            /*************************************************/
3554
            /* Check if deblock is disabled for the current slice or if it is disabled for the current picture
3555
             * because of disable deblock api
3556
             */
3557
0
            if(0 == ps_codec->i4_disable_deblk_pic)
3558
0
            {
3559
                /* Boundary strength calculation is done irrespective of whether deblocking is disabled
3560
                 * in the slice or not, to handle deblocking slice boundaries */
3561
0
                if((0 == ps_codec->i4_slice_error))
3562
0
                {
3563
0
                    WORD32 i4_ctb_tu_cnt;
3564
0
                    WORD32 cur_ctb_idx, next_ctb_idx;
3565
0
                    WORD32 cur_pu_idx;
3566
0
                    WORD32 cur_tu_idx;
3567
0
                    process_ctxt_t *ps_proc;
3568
3569
0
                    ps_proc = &ps_codec->as_process[(ps_codec->i4_num_cores == 1) ? 1 : (ps_codec->i4_num_cores - 1)];
3570
0
                    cur_ctb_idx = ps_codec->s_parse.i4_ctb_x
3571
0
                                    + ps_codec->s_parse.i4_ctb_y * (ps_sps->i2_pic_wd_in_ctb);
3572
3573
0
                    cur_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx[cur_ctb_idx];
3574
0
                    next_ctb_idx = ps_codec->s_parse.i4_next_tu_ctb_cnt;
3575
0
                    if(1 == ps_codec->i4_num_cores)
3576
0
                    {
3577
0
                        i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] -
3578
0
                                        ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB];
3579
3580
0
                        cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx % RESET_TU_BUF_NCTB];
3581
0
                    }
3582
0
                    else
3583
0
                    {
3584
0
                        i4_ctb_tu_cnt = ps_codec->s_parse.pu4_pic_tu_idx[next_ctb_idx] -
3585
0
                                        ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx];
3586
3587
0
                        cur_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx[cur_ctb_idx];
3588
0
                    }
3589
3590
0
                    ps_codec->s_parse.s_bs_ctxt.ps_pps = ps_codec->s_parse.ps_pps;
3591
0
                    ps_codec->s_parse.s_bs_ctxt.ps_sps = ps_codec->s_parse.ps_sps;
3592
0
                    ps_codec->s_parse.s_bs_ctxt.ps_codec = ps_codec;
3593
0
                    ps_codec->s_parse.s_bs_ctxt.i4_ctb_tu_cnt = i4_ctb_tu_cnt;
3594
0
                    ps_codec->s_parse.s_bs_ctxt.i4_ctb_x = ps_codec->s_parse.i4_ctb_x;
3595
0
                    ps_codec->s_parse.s_bs_ctxt.i4_ctb_y = ps_codec->s_parse.i4_ctb_y;
3596
0
                    ps_codec->s_parse.s_bs_ctxt.i4_ctb_tile_x = ps_codec->s_parse.i4_ctb_tile_x;
3597
0
                    ps_codec->s_parse.s_bs_ctxt.i4_ctb_tile_y = ps_codec->s_parse.i4_ctb_tile_y;
3598
0
                    ps_codec->s_parse.s_bs_ctxt.i4_ctb_slice_x = ps_codec->s_parse.i4_ctb_slice_x;
3599
0
                    ps_codec->s_parse.s_bs_ctxt.i4_ctb_slice_y = ps_codec->s_parse.i4_ctb_slice_y;
3600
0
                    ps_codec->s_parse.s_bs_ctxt.ps_tu = &ps_codec->s_parse.ps_pic_tu[cur_tu_idx];
3601
0
                    ps_codec->s_parse.s_bs_ctxt.ps_pu = &ps_codec->s_parse.ps_pic_pu[cur_pu_idx];
3602
0
                    ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx_map = ps_proc->pu4_pic_pu_idx_map;
3603
0
                    ps_codec->s_parse.s_bs_ctxt.i4_next_pu_ctb_cnt = ps_codec->s_parse.i4_next_pu_ctb_cnt;
3604
0
                    ps_codec->s_parse.s_bs_ctxt.i4_next_tu_ctb_cnt = ps_codec->s_parse.i4_next_tu_ctb_cnt;
3605
0
                    ps_codec->s_parse.s_bs_ctxt.pu1_slice_idx = ps_codec->s_parse.pu1_slice_idx;
3606
0
                    ps_codec->s_parse.s_bs_ctxt.ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
3607
0
                    ps_codec->s_parse.s_bs_ctxt.ps_tile = ps_codec->s_parse.ps_tile;
3608
3609
0
                    if(ISLICE == ps_slice_hdr->i1_slice_type)
3610
0
                    {
3611
0
                        ihevcd_ctb_boundary_strength_islice(&ps_codec->s_parse.s_bs_ctxt);
3612
0
                    }
3613
0
                    else
3614
0
                    {
3615
0
                        ihevcd_ctb_boundary_strength_pbslice(&ps_codec->s_parse.s_bs_ctxt);
3616
0
                    }
3617
0
                }
3618
3619
                /* Boundary strength is set to zero if deblocking is disabled for the current slice */
3620
0
                if(0 != ps_slice_hdr->i1_slice_disable_deblocking_filter_flag)
3621
0
                {
3622
0
                    WORD32 bs_strd = (ps_sps->i2_pic_wd_in_ctb + 1) * (ctb_size * ctb_size / 8 / 16);
3623
3624
0
                    UWORD32 *pu4_vert_bs = (UWORD32 *)((UWORD8 *)ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs +
3625
0
                                    ps_codec->s_parse.i4_ctb_x * (ctb_size * ctb_size / 8 / 16) +
3626
0
                                    ps_codec->s_parse.i4_ctb_y * bs_strd);
3627
0
                    UWORD32 *pu4_horz_bs = (UWORD32 *)((UWORD8 *)ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs +
3628
0
                                    ps_codec->s_parse.i4_ctb_x * (ctb_size * ctb_size / 8 / 16) +
3629
0
                                    ps_codec->s_parse.i4_ctb_y * bs_strd);
3630
3631
0
                    memset(pu4_vert_bs, 0, (ctb_size / 8) * (ctb_size / 4) / 8 * 2);
3632
0
                    memset(pu4_horz_bs, 0, (ctb_size / 8) * (ctb_size / 4) / 8 * 2);
3633
0
                }
3634
0
            }
3635
3636
0
        }
3637
3638
0
        DATA_SYNC();
3639
3640
        /* Update the parse status map */
3641
0
        {
3642
0
            sps_t *ps_sps = ps_codec->s_parse.ps_sps;
3643
0
            UWORD8 *pu1_buf;
3644
0
            WORD32 idx;
3645
0
            idx = (ps_codec->s_parse.i4_ctb_x);
3646
0
            idx += ((ps_codec->s_parse.i4_ctb_y) * ps_sps->i2_pic_wd_in_ctb);
3647
0
            pu1_buf = (ps_codec->pu1_parse_map + idx);
3648
0
            *pu1_buf = 1;
3649
0
        }
3650
3651
        /* Increment CTB x and y positions */
3652
0
        ps_codec->s_parse.i4_ctb_tile_x++;
3653
0
        ps_codec->s_parse.i4_ctb_x++;
3654
0
        ps_codec->s_parse.i4_ctb_slice_x++;
3655
3656
        /*If tiles are enabled, handle the slice counters differently*/
3657
0
        if(ps_pps->i1_tiles_enabled_flag)
3658
0
        {
3659
            //Indicates multiple tiles in a slice case
3660
0
            tile_start_ctb_idx = ps_tile->u1_pos_x
3661
0
                            + ps_tile->u1_pos_y * (ps_sps->i2_pic_wd_in_ctb);
3662
3663
0
            slice_start_ctb_idx =  ps_slice_hdr->i2_ctb_x
3664
0
                            + ps_slice_hdr->i2_ctb_y * (ps_sps->i2_pic_wd_in_ctb);
3665
3666
0
            if((slice_start_ctb_idx < tile_start_ctb_idx))
3667
0
            {
3668
0
                if(ps_codec->s_parse.i4_ctb_slice_x == (ps_tile->u1_pos_x + ps_tile->u2_wd))
3669
0
                {
3670
                    /* Reached end of slice row within a tile /frame */
3671
0
                    ps_codec->s_parse.i4_ctb_slice_y++;
3672
0
                    ps_codec->s_parse.i4_ctb_slice_x = ps_tile->u1_pos_x; //todo:Check
3673
0
                }
3674
0
            }
3675
            //Indicates multiple slices in a tile case - hence, reset slice_x
3676
0
            else if(ps_codec->s_parse.i4_ctb_slice_x == (ps_tile->u2_wd))
3677
0
            {
3678
0
                ps_codec->s_parse.i4_ctb_slice_y++;
3679
0
                ps_codec->s_parse.i4_ctb_slice_x = 0;
3680
0
            }
3681
0
        }
3682
0
        else
3683
0
        {
3684
0
            if(ps_codec->s_parse.i4_ctb_slice_x == ps_tile->u2_wd)
3685
0
            {
3686
                /* Reached end of slice row within a tile /frame */
3687
0
                ps_codec->s_parse.i4_ctb_slice_y++;
3688
0
                ps_codec->s_parse.i4_ctb_slice_x = 0;
3689
0
            }
3690
0
        }
3691
3692
3693
0
        if(ps_codec->s_parse.i4_ctb_tile_x == (ps_tile->u2_wd))
3694
0
        {
3695
            /* Reached end of tile row */
3696
0
            ps_codec->s_parse.i4_ctb_tile_x = 0;
3697
0
            ps_codec->s_parse.i4_ctb_x = ps_tile->u1_pos_x;
3698
3699
0
            ps_codec->s_parse.i4_ctb_tile_y++;
3700
0
            ps_codec->s_parse.i4_ctb_y++;
3701
3702
0
            if(ps_codec->s_parse.i4_ctb_tile_y == (ps_tile->u2_ht))
3703
0
            {
3704
                /* Reached End of Tile */
3705
0
                ps_codec->s_parse.i4_ctb_tile_y = 0;
3706
0
                ps_codec->s_parse.i4_ctb_tile_x = 0;
3707
0
                ps_codec->s_parse.ps_tile++;
3708
3709
0
                if((ps_tile->u2_ht + ps_tile->u1_pos_y  ==  ps_sps->i2_pic_ht_in_ctb) && (ps_tile->u2_wd + ps_tile->u1_pos_x  ==  ps_sps->i2_pic_wd_in_ctb))
3710
0
                {
3711
                    /* Reached end of frame */
3712
0
                    end_of_pic = 1;
3713
0
                    ps_codec->s_parse.i4_ctb_x = 0;
3714
0
                    ps_codec->s_parse.i4_ctb_y = ps_sps->i2_pic_ht_in_ctb;
3715
0
                }
3716
0
                else
3717
0
                {
3718
                    /* Initialize ctb_x and ctb_y to start of next tile */
3719
0
                    ps_tile = ps_codec->s_parse.ps_tile;
3720
0
                    ps_codec->s_parse.i4_ctb_x = ps_tile->u1_pos_x;
3721
0
                    ps_codec->s_parse.i4_ctb_y = ps_tile->u1_pos_y;
3722
0
                    ps_codec->s_parse.i4_ctb_tile_y = 0;
3723
0
                    ps_codec->s_parse.i4_ctb_tile_x = 0;
3724
0
                    ps_codec->s_parse.i4_ctb_slice_x = ps_tile->u1_pos_x;
3725
0
                    ps_codec->s_parse.i4_ctb_slice_y = ps_tile->u1_pos_y;
3726
3727
0
                }
3728
0
            }
3729
3730
0
        }
3731
3732
0
        ps_codec->s_parse.i4_next_ctb_indx = ps_codec->s_parse.i4_ctb_x +
3733
0
                        ps_codec->s_parse.i4_ctb_y * ps_sps->i2_pic_wd_in_ctb;
3734
3735
        /* If the current slice is in error, check if the next slice's address
3736
         * is reached and mark the end_of_slice flag */
3737
0
        if(ps_codec->i4_slice_error)
3738
0
        {
3739
0
            slice_header_t *ps_slice_hdr_next = ps_slice_hdr + 1;
3740
0
            WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
3741
0
                            ps_slice_hdr_next->i2_ctb_y * ps_sps->i2_pic_wd_in_ctb;
3742
3743
0
            if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
3744
0
                end_of_slice_flag = 1;
3745
0
        }
3746
3747
        /* If the codec is running in single core mode
3748
         * then call process function for current CTB
3749
         */
3750
0
        if((1 == ps_codec->i4_num_cores) && (ps_codec->s_parse.i4_ctb_tile_x == 0))
3751
0
        {
3752
0
            process_ctxt_t *ps_proc = &ps_codec->as_process[0];
3753
//          ps_proc->i4_ctb_cnt = ihevcd_nctb_cnt(ps_codec, ps_sps);
3754
0
            ps_proc->i4_ctb_cnt = ps_proc->ps_tile->u2_wd;
3755
0
            ihevcd_process(ps_proc);
3756
0
        }
3757
3758
        /* If the bytes for the current slice are exhausted
3759
         * set end_of_slice flag to 1
3760
         * This slice will be treated as incomplete */
3761
0
        if((UWORD8 *)ps_codec->s_parse.s_bitstrm.pu1_buf_max + BITSTRM_OFF_THRS <
3762
0
                                        ((UWORD8 *)ps_codec->s_parse.s_bitstrm.pu4_buf + (ps_codec->s_parse.s_bitstrm.u4_bit_ofst / 8)))
3763
0
        {
3764
            // end_of_slice_flag = ps_codec->i4_slice_error ? 0 : 1;
3765
3766
0
            if(0 == ps_codec->i4_slice_error)
3767
0
                end_of_slice_flag = 1;
3768
0
        }
3769
3770
3771
0
        if(end_of_pic)
3772
0
            break;
3773
0
    } while(!end_of_slice_flag);
3774
3775
    /* Reset slice error */
3776
0
    ps_codec->i4_slice_error = 0;
3777
3778
    /* Increment the slice index for parsing next slice */
3779
0
    if(0 == end_of_pic)
3780
0
    {
3781
0
        while(1)
3782
0
        {
3783
3784
0
            WORD32 parse_slice_idx;
3785
0
            parse_slice_idx = ps_codec->s_parse.i4_cur_slice_idx;
3786
0
            parse_slice_idx++;
3787
3788
0
            {
3789
                /* If the next slice header is not initialized, update cur_slice_idx and break */
3790
0
                if((1 == ps_codec->i4_num_cores) || (0 != (parse_slice_idx & (MAX_SLICE_HDR_CNT - 1))))
3791
0
                {
3792
0
                    ps_codec->s_parse.i4_cur_slice_idx = parse_slice_idx;
3793
0
                    break;
3794
0
                }
3795
3796
                /* If the next slice header is initialised, wait for the parsed slices to be processed */
3797
0
                else
3798
0
                {
3799
0
                    WORD32 ctb_indx = 0;
3800
3801
0
                    while(ctb_indx != ps_sps->i4_pic_size_in_ctb)
3802
0
                    {
3803
0
                        WORD32 parse_status = *(ps_codec->pu1_parse_map + ctb_indx);
3804
0
                        volatile WORD32 proc_status = *(ps_codec->pu1_proc_map + ctb_indx) & 1;
3805
3806
0
                        if(parse_status == proc_status)
3807
0
                            ctb_indx++;
3808
0
                    }
3809
0
                    ps_codec->s_parse.i4_cur_slice_idx = parse_slice_idx;
3810
0
                    break;
3811
0
                }
3812
3813
0
            }
3814
0
        }
3815
3816
0
    }
3817
0
    else
3818
0
    {
3819
3820
0
        ps_codec->s_parse.i4_end_of_frame = 1;
3821
0
    }
3822
0
    return ret;
3823
0
}
3824
3825
3826
3827
3828
3829
3830
3831