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