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