/******************************************************************************
*
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/**
*******************************************************************************
* @file
*  ihevcd_utils.c
*
* @brief
*  Contains miscellaneous utility functions such as init() etc
*
* @author
*  Harish
*
* @par List of Functions:
*
* @remarks
*  None
*
*******************************************************************************
*/
/*****************************************************************************/
/* File Includes                                                             */
/*****************************************************************************/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "ihevc_typedefs.h"
#include "iv.h"
#include "ivd.h"
#include "ihevcd_cxa.h"
#include "ithread.h"

#include "ihevc_defs.h"
#include "ihevc_debug.h"
#include "ihevc_defs.h"
#include "ihevc_error.h"
#include "ihevc_structs.h"
#include "ihevc_buf_mgr.h"
#include "ihevc_dpb_mgr.h"
#include "ihevc_macros.h"
#include "ihevc_platform_macros.h"

#include "ihevc_common_tables.h"
#include "ihevc_buf_mgr.h"
#include "ihevc_disp_mgr.h"
#include "ihevc_cabac_tables.h"

#include "ihevcd_defs.h"

#include "ihevcd_function_selector.h"
#include "ihevcd_structs.h"
#include "ihevcd_error.h"
#include "ihevcd_nal.h"
#include "ihevcd_bitstream.h"
#include "ihevcd_utils.h"
#include "ihevcd_trace.h"
#include "ihevcd_process_slice.h"
#include "ihevcd_job_queue.h"
#define MAX_DPB_PIC_BUF 6

/* Function declarations */
mv_buf_t* ihevcd_mv_mgr_get_poc(buf_mgr_t *ps_mv_buf_mgr, UWORD32 abs_poc);

/**
*******************************************************************************
*
* @brief
*  Used to get level index for a given level
*
* @par Description:
*  Converts from level_idc (which is multiplied by 30) to an index that can be
*  used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
*
* @param[in] level
*  Level of the stream
*
* @returns  Level index for a given level
*
* @remarks
*
*
*******************************************************************************
*/
WORD32 ihevcd_get_lvl_idx(WORD32 level)
{
    WORD32 lvl_idx = 0;

    if(level < IHEVC_LEVEL_20)
    {
        lvl_idx = 0;
    }
    else if(level >= IHEVC_LEVEL_20 && level < IHEVC_LEVEL_21)
    {
        lvl_idx = 1;
    }
    else if(level >= IHEVC_LEVEL_21 && level < IHEVC_LEVEL_30)
    {
        lvl_idx = 2;
    }
    else if(level >= IHEVC_LEVEL_30 && level < IHEVC_LEVEL_31)
    {
        lvl_idx = 3;
    }
    else if(level >= IHEVC_LEVEL_31 && level < IHEVC_LEVEL_40)
    {
        lvl_idx = 4;
    }
    else if(level >= IHEVC_LEVEL_40 && level < IHEVC_LEVEL_41)
    {
        lvl_idx = 5;
    }
    else if(level >= IHEVC_LEVEL_41 && level < IHEVC_LEVEL_50)
    {
        lvl_idx = 6;
    }
    else if(level >= IHEVC_LEVEL_50 && level < IHEVC_LEVEL_51)
    {
        lvl_idx = 7;
    }
    else if(level >= IHEVC_LEVEL_51 && level < IHEVC_LEVEL_52)
    {
        lvl_idx = 8;
    }
    else if(level >= IHEVC_LEVEL_52 && level < IHEVC_LEVEL_60)
    {
        lvl_idx = 9;
    }
    else if(level >= IHEVC_LEVEL_60 && level < IHEVC_LEVEL_61)
    {
        lvl_idx = 10;
    }
    else if(level >= IHEVC_LEVEL_61 && level < IHEVC_LEVEL_62)
    {
        lvl_idx = 11;
    }
    else if(level >= IHEVC_LEVEL_62)
    {
        lvl_idx = 12;
    }

    return (lvl_idx);
}

/**
*******************************************************************************
*
* @brief
*  Used to get reference picture buffer size for a given level and
*  and padding used
*
* @par Description:
*  Used to get reference picture buffer size for a given level and padding used
*  Each picture is padded on all four sides
*
* @param[in] pic_size
*  Mumber of luma samples (Width * Height)
*
* @param[in] level
*  Level
*
* @param[in] horz_pad
*  Total padding used in horizontal direction
*
* @param[in] vert_pad
*  Total padding used in vertical direction
*
* @returns  Total picture buffer size
*
* @remarks
*
*
*******************************************************************************
*/
WORD32 ihevcd_get_total_pic_buf_size(codec_t *ps_codec,
                                     WORD32 wd,
                                     WORD32 ht)
{
    WORD32 size;
    WORD32 num_luma_samples;
    WORD32 max_dpb_size;
    WORD32 num_samples;


    sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);

    /* Get maximum number of buffers for the current picture size */
    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];

    if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
        max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];

    max_dpb_size++;
    /* Allocation is required for
     * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
     */

    /* Account for padding area */
    num_luma_samples = (wd + PAD_WD) * (ht + PAD_HT);

    /* Account for chroma */
    num_samples = num_luma_samples * 3 / 2;

    /* Number of bytes in reference pictures */
    size = num_samples * max_dpb_size;


    return size;
}
/**
*******************************************************************************
*
* @brief
*  Used to get MV bank size for a given number of luma samples
*
* @par Description:
*  For given number of luma samples  one MV bank size is computed
*  Each MV bank includes pu_map and pu_t for all the min PUs(4x4) in a picture
*
* @param[in] num_luma_samples
*  Max number of luma pixels in the frame
*
* @returns  Total MV Bank size
*
* @remarks
*
*
*******************************************************************************
*/
WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)
{
    WORD32 size;

    WORD32 pic_size;

    WORD32 mv_bank_size;
    WORD32 num_pu;
    WORD32 num_ctb;
    pic_size = num_luma_samples;


    num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
    num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);

    mv_bank_size = 0;

    /* Size for storing pu_t start index each CTB */
    /* One extra entry is needed to compute number of PUs in the last CTB */
    mv_bank_size += (num_ctb + 1) * sizeof(WORD32);

    /* Size for pu_map */
    mv_bank_size += num_pu;

    /* Size for storing pu_t for each PU */
    mv_bank_size += num_pu * sizeof(pu_t);

    /* Size for storing slice_idx for each CTB */
    mv_bank_size += ALIGN4(num_ctb * sizeof(UWORD16));

    size =  mv_bank_size;
    return size;
}
/**
*******************************************************************************
*
* @brief
*  Used to get TU data size for a given number luma samples
*
* @par Description:
*  For a given number of luma samples TU data size is computed
*  Each TU data includes tu_map and tu_t and coeff data for all
*  the min TUs(4x4) in given CTB
*
* @param[in] num_luma_samples
*  Number of 64 x 64 CTBs for which TU data has to be allocated.
*
* @returns  Total TU data size
*
* @remarks Assumption is num_luma_samples will be at least
* 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well
*
*******************************************************************************
*/
WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples)
{


    WORD32 tu_data_size;
    WORD32 num_ctb;
    WORD32 num_luma_tu, num_chroma_tu, num_tu;
    num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE);

    num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE);
    num_chroma_tu = num_luma_tu >> 1;

    num_tu = num_luma_tu + num_chroma_tu;
    tu_data_size = 0;

    /* Size for storing tu_t start index each CTB */
    /* One extra entry is needed to compute number of TUs in the last CTB */
    tu_data_size += (num_ctb + 1) * sizeof(WORD32);

    /* Size for storing tu map */
    tu_data_size += num_luma_tu * sizeof(UWORD8);

    /* Size for storing tu_t for each TU */
    tu_data_size += num_tu * sizeof(tu_t);

    /* Size for storing number of coded subblocks and scan_idx for each TU */
    tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8));

    /* Size for storing coeff data for each TU */
    tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t);


    return tu_data_size;
}


WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps)
{
    WORD32 nctb = 1;
    UNUSED(ps_codec);
    //TODO: Currently set to 1
    /* If CTB size is less than 32 x 32 then set nCTB as 4 */
    if(ps_sps->i1_log2_ctb_size < 5)
        nctb = 1;

    return nctb;
}

IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps,
                                   sps_t *ps_sps,
                                   WORD32 ctb_x,
                                   WORD32 ctb_y,
                                   WORD32 *pi4_ctb_tile_x,
                                   WORD32 *pi4_ctb_tile_y,
                                   WORD32 *pi4_tile_idx)
{

    tile_t *ps_tile_tmp;
    WORD32 i;
    WORD32 tile_row, tile_col;

    if(ctb_x < 0 || ctb_y < 0)
    {
        *pi4_ctb_tile_x = 0;
        *pi4_ctb_tile_y = 0;
        *pi4_tile_idx = 0;

        return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    }

    tile_row = 0;
    tile_col = 0;
    ps_tile_tmp = ps_pps->ps_tile;
    if(0 == ps_pps->i1_tiles_enabled_flag)
    {
        *pi4_ctb_tile_x = ctb_x;
        *pi4_ctb_tile_y = ctb_y;
        *pi4_tile_idx = 0;
    }
    else
    {
        for(i = 0; i < ps_pps->i1_num_tile_columns; i++)
        {
            WORD16 next_tile_ctb_x;
            ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows;
            if((ps_pps->i1_num_tile_columns - 1) == i)
            {
                next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb;
            }
            else
            {
                tile_t *ps_tile_next_tmp;
                ps_tile_next_tmp = ps_pps->ps_tile + i + 1;
                next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x;
            }
            if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x))
            {
                tile_col = i;
                break;
            }
        }
        *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x;

        for(i = 0; i < ps_pps->i1_num_tile_rows; i++)
        {
            WORD16 next_tile_ctb_y;
            ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns;
            if((ps_pps->i1_num_tile_rows - 1) == i)
            {
                next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb;
            }
            else
            {
                tile_t *ps_tile_next_tmp;
                ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns);
                next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y;
            }
            if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y))
            {
                tile_row = i;
                break;
            }

        }
        *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y;
        *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns
                        + tile_col;
    }
    return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
}
/**
*******************************************************************************
*
* @brief
*  Function to initialize ps_pic_buf structs add pic buffers to
*  buffer manager in case of non-shared mode
*
* @par Description:
*  Function to initialize ps_pic_buf structs add pic buffers to
*  buffer manager in case of non-shared mode
*  To be called once per stream or for every reset
*
* @param[in] ps_codec
*  Pointer to codec context
*
* @returns  Error from IHEVCD_ERROR_T
*
* @remarks
*
*
*******************************************************************************
*/
IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
{
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    WORD32 i;
    WORD32 max_dpb_size;
    sps_t *ps_sps;
    UWORD8 *pu1_buf;
    pic_buf_t *ps_pic_buf;
    WORD32 pic_buf_size_allocated;




    /* Initialize Pic buffer manager */
    ps_sps = ps_codec->s_parse.ps_sps;

    /* Compute the number of Pic buffers needed */
    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];

    if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
        max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];

    /* Allocate one extra picture to handle current frame
     * In case of asynchronous parsing and processing, number of buffers should increase here
     * based on when parsing and processing threads are synchronized
     */
    max_dpb_size++;


    pu1_buf = (UWORD8 *)ps_codec->pu1_ref_pic_buf_base;

    ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;

    /* In case of non-shared mode, add picture buffers to buffer manager
     * In case of shared mode buffers are added in the run-time
     */
    if(0 == ps_codec->i4_share_disp_buf)
    {
        WORD32 buf_ret;
        WORD32 luma_samples;
        WORD32 chroma_samples;
        pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size;

        luma_samples = (ps_codec->i4_strd) *
                        (ps_sps->i2_pic_height_in_luma_samples + PAD_HT);

        chroma_samples = luma_samples / 2;

        /* Try to add as many buffers as possible since memory is already allocated */
        /* If the number of buffers that can be added is less than max_num_bufs
         * return with an error.
         */
        for(i = 0; i < max_dpb_size; i++)
        {
            pic_buf_size_allocated -= (luma_samples + chroma_samples);

            if(pic_buf_size_allocated < 0)
            {
                ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
                return IHEVCD_INSUFFICIENT_MEM_PICBUF;
            }

            ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
            pu1_buf += luma_samples;

            ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
            pu1_buf += chroma_samples;

            buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);


            if(0 != buf_ret)
            {
                ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
                return IHEVCD_BUF_MGR_ERROR;
            }
            ps_pic_buf++;
        }
    }
    else
    {
        /* In case of shared mode, buffers are added without adjusting for padding.
           Update luma and chroma pointers here to account for padding as per stride.
           In some cases stride might not be available when set_display_frame is called.
           Hence updated luma and chroma pointers here */

        for(i = 0; i < BUF_MGR_MAX_CNT; i++)
        {
            ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i);
            if((NULL == ps_pic_buf) ||
               (NULL == ps_pic_buf->pu1_luma) ||
               (NULL == ps_pic_buf->pu1_chroma))
            {
                break;
            }
            ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
            ps_pic_buf->pu1_chroma += ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
        }
    }

    return ret;
}
/**
*******************************************************************************
*
* @brief
*  Function to add buffers to MV Bank buffer manager
*
* @par Description:
*  Function to add buffers to MV Bank buffer manager
*  To be called once per stream or for every reset
*
* @param[in] ps_codec
*  Pointer to codec context
*
* @returns  Error from IHEVCD_ERROR_T
*
* @remarks
*
*
*******************************************************************************
*/
IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
{
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    WORD32 i;
    WORD32 max_dpb_size;
    WORD32 mv_bank_size_allocated;
    WORD32 pic_mv_bank_size;

    sps_t *ps_sps;
    UWORD8 *pu1_buf;
    mv_buf_t *ps_mv_buf;


    /* Initialize MV Bank buffer manager */
    ps_sps = ps_codec->s_parse.ps_sps;


    /* Compute the number of MV Bank buffers needed */
    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];

    /* Allocate one extra MV Bank to handle current frame
     * In case of asynchronous parsing and processing, number of buffers should increase here
     * based on when parsing and processing threads are synchronized
     */
    max_dpb_size++;

    pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;

    ps_mv_buf = (mv_buf_t *)pu1_buf;
    pu1_buf += max_dpb_size * sizeof(mv_buf_t);
    ps_codec->ps_mv_buf = ps_mv_buf;
    mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - max_dpb_size  * sizeof(mv_buf_t);

    /* Compute MV bank size per picture */
    pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
                                                   ALIGN64(ps_sps->i2_pic_height_in_luma_samples));

    for(i = 0; i < max_dpb_size; i++)
    {
        WORD32 buf_ret;
        WORD32 num_pu;
        WORD32 num_ctb;
        WORD32 pic_size;
        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);


        num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);


        mv_bank_size_allocated -= pic_mv_bank_size;

        if(mv_bank_size_allocated < 0)
        {
            ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
            return IHEVCD_INSUFFICIENT_MEM_MVBANK;
        }

        ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
        pu1_buf += (num_ctb + 1) * sizeof(WORD32);

        ps_mv_buf->pu1_pic_pu_map = pu1_buf;
        pu1_buf += num_pu;

        ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
        pu1_buf += ALIGN4(num_ctb * sizeof(UWORD16));

        ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
        pu1_buf += num_pu * sizeof(pu_t);

        buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);

        if(0 != buf_ret)
        {
            ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
            return IHEVCD_BUF_MGR_ERROR;
        }

        ps_mv_buf++;

    }
    return ret;
}
/**
*******************************************************************************
*
* @brief
*  Picture level initializations required during parsing
*
* @par Description:
*  Initialize picture level context variables during parsing Initialize mv
* bank buffer manager in the first init call
*
* @param[in] ps_codec
*  Pointer to codec context
*
* @returns  Error from IHEVCD_ERROR_T
*
* @remarks
*
*
*******************************************************************************
*/
IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
{
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    mv_buf_t *ps_mv_buf;
    sps_t *ps_sps;
    WORD32 num_min_cu;
    WORD32 cur_pic_buf_id;
    WORD32 cur_mv_bank_buf_id;
    pic_buf_t *ps_cur_pic;
    slice_header_t *ps_slice_hdr;
    UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
    WORD32 i;

    ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
    ps_sps = ps_codec->s_parse.ps_sps;
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
    /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
    ps_codec->i4_pic_present = 1;

    /* Memset picture level intra map and transquant bypass map to zero */
    num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
    memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
    memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);



    if(0 == ps_codec->s_parse.i4_first_pic_init)
    {
        ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);

        ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);

        ps_codec->s_parse.i4_first_pic_init = 1;
    }

    /* Initialize all the slice headers' slice addresses to zero */
    {
        WORD32 slice_idx;
        WORD32 slice_start_idx;

        slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;

        for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
        {
            slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
            ps_slice_hdr_tmp->i2_ctb_x = -1;
            ps_slice_hdr_tmp->i2_ctb_y = -1;

        }
    }

    /* Get free MV Bank to hold current picture's motion vector data */
    {
        ps_mv_buf = (mv_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, &cur_mv_bank_buf_id);

        /* If there are no free buffers then return with an error code.
         * If the buffer is to be freed by another thread , change the
         * following to call thread yield and wait for buffer to be freed
         */
        if(NULL == ps_mv_buf)
        {
            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
            ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
            return IHEVCD_NO_FREE_MVBANK;
        }

        ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf;
        /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
         * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
         * and getting a buffer id to free
         */
        ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
    }

    /* Get free picture buffer to hold current picture recon data */
    /* TODO: For asynchronous api the following initializations related to picture
     * buffer should be moved to processing side
     */
    {

        UWORD8 *pu1_buf;
        ps_cur_pic = (pic_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, &cur_pic_buf_id);

        /* If there are no free buffers then return with an error code.
         * TODO: If the buffer is to be freed by another thread , change the
         * following to call thread yield and wait for buffer to be freed
         */
        if(NULL == ps_cur_pic)
        {
            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
            ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
            return IHEVCD_NO_FREE_PICBUF;
        }

        /* Store input timestamp sent with input buffer */
        ps_cur_pic->u4_ts = ps_codec->u4_ts;
        ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
        ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
        pu1_buf = ps_cur_pic->pu1_luma;
        pu1_cur_pic_luma = pu1_buf;

        pu1_buf = ps_cur_pic->pu1_chroma;

        pu1_cur_pic_chroma = pu1_buf;
    }

    if(0 == ps_codec->u4_pic_cnt)
    {
        memset(ps_cur_pic->pu1_luma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples);
        memset(ps_cur_pic->pu1_chroma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples / 2);
    }

    /* Fill the remaining entries of the reference lists with the nearest POC
     * This is done to handle cases where there is a corruption in the reference index */
    {
        pic_buf_t *ps_pic_buf_ref;
        mv_buf_t *ps_mv_buf_ref;
        WORD32 r_idx;
        dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
        buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;

        ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
        if(NULL == ps_pic_buf_ref)
        {
            WORD32 size;

            WORD32 num_pu;
            WORD32 num_ctb;
            WORD32 pic_size;
            /* In case current mv buffer itself is being used as reference mv buffer for colocated
             * calculations, then memset all the buffers to zero.
             */
            pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
                            ALIGN64(ps_sps->i2_pic_height_in_luma_samples);

            num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
            num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);

            memset(ps_mv_buf->ai4_l0_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l0_collocated_poc));
            memset(ps_mv_buf->ai1_l0_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l0_collocated_poc_lt));
            memset(ps_mv_buf->ai4_l1_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l1_collocated_poc));
            memset(ps_mv_buf->ai1_l1_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l1_collocated_poc_lt));

            size = (num_ctb + 1) * sizeof(WORD32);
            memset(ps_mv_buf->pu4_pic_pu_idx, 0, size);

            size = num_pu;
            memset(ps_mv_buf->pu1_pic_pu_map, 0, size);
            size = ALIGN4(num_ctb * sizeof(UWORD16));
            memset(ps_mv_buf->pu1_pic_slice_map, 0, size);
            size = num_pu * sizeof(pu_t);
            memset(ps_mv_buf->ps_pic_pu, 0, size);

            ps_pic_buf_ref = ps_cur_pic;
            ps_mv_buf_ref = ps_mv_buf;
        }
        else
        {
            ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
        }

        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
        {
            if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
            {
                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
            }
        }

        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
        {
            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
        }

        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
        {
            if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
            {
                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
            }
        }

        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
        {
            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
        }
    }


    /* Reset the jobq to start of the jobq buffer */
    ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);

    ps_codec->s_parse.i4_pic_pu_idx = 0;
    ps_codec->s_parse.i4_pic_tu_idx = 0;

    ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
    ps_codec->s_parse.ps_pic_pu      = ps_mv_buf->ps_pic_pu;
    ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
    ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
    for(i = 0; i < MAX_PROCESS_THREADS; i++)
    {
        ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
    }
    ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
    ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;

    {
        UWORD8 *pu1_buf;
        WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
        WORD32 pic_size;
        WORD32 num_ctb;

        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);

        ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);

        ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;

        ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;

        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
        pu1_buf  = (UWORD8 *)ps_codec->pv_tu_data;
        ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
        pu1_buf += (num_ctb + 1) * sizeof(WORD32);

        ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
        pu1_buf += ctb_min_tu_cnt;

        ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
        pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);

        ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;

        ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
        ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
        ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
    }

    ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
    ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
    ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;


    /* Set number of CTBs to be processed simultaneously */
    ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);

    /* Memset Parse Map and process map at the start of frame */
    //TODO: In case of asynchronous API proc_map can not be set to zero here
    {
        WORD32 num_ctb;

        num_ctb = ps_sps->i4_pic_size_in_ctb;

        memset(ps_codec->pu1_parse_map, 0, num_ctb);

        memset(ps_codec->pu1_proc_map, 0, num_ctb);
    }



    /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
     * buffer to be displayed
     */
    ps_codec->i4_disp_buf_id = -1;
    ps_codec->ps_disp_buf = NULL;

    ps_codec->i4_disable_deblk_pic  = 0;
    ps_codec->i4_disable_sao_pic    = 0;
    ps_codec->i4_fullpel_inter_pred = 0;
    ps_codec->i4_mv_frac_mask       = 0x7FFFFFFF;

    /* If degrade is enabled, set the degrade flags appropriately */
    if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
    {
        WORD32 degrade_pic;
        ps_codec->i4_degrade_pic_cnt++;
        degrade_pic = 0;

        /* If degrade is to be done in all frames, then do not check further */
        switch(ps_codec->i4_degrade_pics)
        {
            case 4:
            {
                degrade_pic = 1;
                break;
            }
            case 3:
            {
                if(ps_slice_hdr->i1_slice_type != ISLICE)
                    degrade_pic = 1;

                break;
            }
            case 2:
            {

                /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
                if((ps_slice_hdr->i1_slice_type != ISLICE) &&
                   (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
                    degrade_pic = 1;

                break;
            }
            case 1:
            {
                /* Check if the current picture is non-ref */
                if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
                   (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
                {
                    degrade_pic = 1;
                }
                break;
            }


        }
        if(degrade_pic)
        {
            if(ps_codec->i4_degrade_type & 0x1)
                ps_codec->i4_disable_sao_pic = 1;

            if(ps_codec->i4_degrade_type & 0x2)
                ps_codec->i4_disable_deblk_pic = 1;

            /* MC degrading is done only for non-ref pictures */
            if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
               (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
            {
                if(ps_codec->i4_degrade_type & 0x4)
                    ps_codec->i4_mv_frac_mask = 0;

                if(ps_codec->i4_degrade_type & 0x8)
                    ps_codec->i4_mv_frac_mask = 0;
            }
        }
        else
            ps_codec->i4_degrade_pic_cnt = 0;
    }


    {
        WORD32 i;
        for(i = 0; i < MAX_PROCESS_THREADS; i++)
        {
            ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
            ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
            ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
            ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
            ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
            ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
            ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
            ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
            ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
            ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;

            /* TODO: For asynchronous api the following initializations related to picture
             * buffer should be moved to processing side
             */
            ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
            ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
            ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
            ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;

            ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
            if(1 < ps_codec->i4_num_cores)
            {
                ps_codec->as_process[i].i4_check_parse_status = 1;
                ps_codec->as_process[i].i4_check_proc_status = 1;
            }
            else
            {
                ps_codec->as_process[i].i4_check_parse_status = 0;
                ps_codec->as_process[i].i4_check_proc_status = 0;
            }
            ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
            ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
            ps_codec->as_process[i].i4_init_done = 0;

            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
            ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
            ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
            ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
            if(i < (ps_codec->i4_num_cores - 1))
            {
                ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
                               (void *)ihevcd_process_thread,
                               (void *)&ps_codec->as_process[i]);
                ps_codec->ai4_process_thread_created[i] = 1;
            }
            else
            {
                ps_codec->ai4_process_thread_created[i] = 0;
            }

        }
        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;

        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
    }
    /* Since any input bitstream buffer that contains slice data will be sent to output(even in
     * case of error, this buffer is added to display queue and next buffer in the display queue
     * will be returned as the display buffer.
     * Note: If format conversion (or frame copy) is used and is scheduled
     * in a different thread then it has to check if the processing for the current row is complete before
     * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
     * returned, which requires a status check to ensure that the current row is reconstructed before copying.
     */
    /* Add current picture to display manager */
    {
        WORD32 abs_poc;
        slice_header_t *ps_slice_hdr;
        ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
        abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
        ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
                           ps_codec->as_process[0].i4_cur_pic_buf_id,
                           abs_poc,
                           ps_codec->as_process[0].ps_cur_pic);
    }
    ps_codec->ps_disp_buf = NULL;
    /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
    /* Since the current will be decoded, check is fore >= instead of > */
    if(((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]) ||
       (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT))

    {
        ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
        ps_codec->u4_disp_cnt++;
    }

    ps_codec->s_fmt_conv.i4_cur_row = 0;
    /* Set number of rows to be processed at a time */
    ps_codec->s_fmt_conv.i4_num_rows = 4;

    if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
    {
        process_ctxt_t *ps_proc;

        /* i4_num_cores - 1 contexts are currently being used by other threads */
        ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];

        /* If the frame being decoded and displayed are different, schedule format conversion jobs
         * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
         * If the frame being decoded and displayed are same, then format conversion is scheduled later.
         */
        if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
           ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
        {

            for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
            {
                proc_job_t s_job;
                IHEVCD_ERROR_T ret;
                s_job.i4_cmd = CMD_FMTCONV;
                s_job.i2_ctb_cnt = 0;
                s_job.i2_ctb_x = 0;
                s_job.i2_ctb_y = i;
                s_job.i2_slice_idx = 0;
                s_job.i4_tu_coeff_data_ofst = 0;
                ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
                                        &s_job, sizeof(proc_job_t), 1);
                if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
                    return ret;
            }
        }
    }


    return ret;
}


