/******************************************************************************
 *
 * Copyright (C) 2021 The Android Open Source Project
 *
 * 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.
 *
 *****************************************************************************
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
 */

/*****************************************************************************/
/*                                                                           */
/*  File Name         : imvcd_nalu_parser.h                                  */
/*                                                                           */
/*  Description       : Functions for MVC NALU parsing                       */
/*                                                                           */
/*****************************************************************************/
#include <stdbool.h>

#include "ih264_typedefs.h"
#include "ih264d_error_handler.h"
#include "imvcd_dpb_manager.h"
#include "imvcd_structs.h"
#include "imvcd_utils.h"

void imvcd_dpb_set_display_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_num)
{
    ps_dpb_mgr->i4_cur_display_seq = i4_display_num;
}

void imvcd_dpb_set_max_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_pic_num)
{
    ps_dpb_mgr->i4_max_pic_num = i4_max_pic_num;
}

void imvcd_dpb_set_num_views(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_num_views)
{
    ps_dpb_mgr->u2_num_views = u2_num_views;
}

void imvcd_dpb_set_display_delay(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_delay)
{
    ps_dpb_mgr->i4_display_delay = i4_display_delay;
}

void imvcd_dpb_init_au_bufs(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_cur_au)
{
    WORD32 i;

    for(i = 0; i < 2; i++)
    {
        ps_dpb_mgr->as_init_dpb[i][0] = ps_cur_au[0];
    }
}

void imvcd_dpb_init_view_bufs(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_view_order_id,
                              UWORD16 u2_view_id)
{
    WORD32 i;

    for(i = 0; i < 2; i++)
    {
        imvcd_convert_au_buf_to_view_buf(&ps_dpb_mgr->as_init_dpb[i][0],
                                         &ps_dpb_mgr->as_view_init_dpb[i][0], u2_view_order_id,
                                         u2_view_id);
    }
}

void imvcd_dpb_init_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr, sps_mvc_ext_t *ps_sps_mvc_ext,
                             nalu_mvc_ext_t *ps_nalu_mvc_exts)
{
    ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts = ps_nalu_mvc_exts;
    ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext = ps_sps_mvc_ext;

    ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
}

void imvcd_dpb_reset_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr)
{
    UWORD32 i;

    for(i = 0; i < ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs; i++)
    {
        ih264_buf_mgr_release(ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt,
                              ps_dpb_mgr->s_dpb_ivp_ctxt.au1_au_buf_ids[i],
                              BUF_MGR_REF | BUF_MGR_IO);

        ih264_buf_mgr_release(ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
                              ps_dpb_mgr->s_dpb_ivp_ctxt.au1_mv_buf_ids[i],
                              BUF_MGR_REF | BUF_MGR_IO);
    }

    ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
}

pic_buffer_t **imvcd_dpb_get_view_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
                                               UWORD16 u2_view_order_id, UWORD16 u2_view_id,
                                               UWORD8 u1_pred_dir)
{
    WORD32 i;

    UWORD8 u1_num_ref_bufs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_dir] +
                             ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_dir];

    for(i = 0; i < u1_num_ref_bufs; i++)
    {
        imvcd_convert_au_buf_to_view_buf(ps_dpb_mgr->aps_mod_dpb[u1_pred_dir][i],
                                         &ps_dpb_mgr->as_view_init_dpb[u1_pred_dir][i],
                                         u2_view_order_id, u2_view_id);

        ps_dpb_mgr->aps_view_mod_dpb[u1_pred_dir][i] =
            &ps_dpb_mgr->as_view_init_dpb[u1_pred_dir][i];
    }

    return ps_dpb_mgr->aps_view_mod_dpb[u1_pred_dir];
}

void imvcd_init_dpb_mgr(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
                        mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr,
                        disp_mgr_t *ps_disp_buf_mgr)
{
    WORD32 i, j, k, l;

    mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;

    for(i = 0; i < 2; i++)
    {
        mvc_au_buffer_t *ps_init_dpb = ps_dpb_mgr->as_init_dpb[i];
        pic_buffer_t *ps_view_init_dpb = ps_dpb_mgr->as_view_init_dpb[i];

        for(j = 0; j < MVC_MAX_REF_PICS; j++)
        {
            for(k = 0; k < MAX_NUM_VIEWS; k++)
            {
                for(l = 0; l < NUM_COMPONENTS; l++)
                {
                    ps_init_dpb->as_view_buffers[k].as_component_bufs[l].pv_data = NULL;
                }
            }

            ps_view_init_dpb->pu1_buf1 = NULL;
            ps_view_init_dpb->pu1_buf2 = NULL;
            ps_view_init_dpb->pu1_buf3 = NULL;

            ps_dpb_mgr->aps_mod_dpb[i][j] = ps_init_dpb;
            ps_dpb_mgr->aps_view_mod_dpb[i][j] = ps_view_init_dpb;

            ps_init_dpb++;
            ps_view_init_dpb++;
        }
    }

    for(i = 0; i < MVC_MAX_REF_PICS; i++)
    {
        ps_dpb_info[i].b_used_as_ref = false;
        ps_dpb_info[i].ps_prev_short = NULL;
        ps_dpb_info[i].ps_prev_long = NULL;
        ps_dpb_info[i].ps_au_buf = NULL;
        ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
        ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
        ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
        ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
    }

    ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
    ps_dpb_mgr->ps_dpb_st_head = NULL;
    ps_dpb_mgr->ps_dpb_lt_head = NULL;
    ps_dpb_mgr->i1_gaps_deleted = 0;
    ps_dpb_mgr->i1_poc_buf_id_entries = 0;
    ps_dpb_mgr->u1_mmco_error_in_seq = 0;
    ps_dpb_mgr->u1_num_gaps = 0;
    ps_dpb_mgr->i4_display_delay = 0;
    ps_dpb_mgr->i4_cur_display_seq = 0;

    for(i = 0; i < MAX_FRAMES; i++)
    {
        ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
        ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
        ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
        ps_dpb_mgr->as_display_buf_info[i].i4_poc_buf_id = -1;
        ps_dpb_mgr->as_display_buf_info[i].i4_poc = INT32_MAX;
        ps_dpb_mgr->as_display_buf_info[i].i4_frame_num = 0;
    }

    ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
    ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts = NULL;
    ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext = NULL;

    ps_dpb_mgr->ps_mvc_au_buf_mgr = ps_mvc_au_buf_mgr;
    ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr = ps_mvc_au_mv_pred_buf_mgr;
    ps_dpb_mgr->ps_disp_buf_mgr = ps_disp_buf_mgr;
}

WORD32 imvcd_dpb_assign_display_seq(mvc_dpb_manager_t *ps_dpb_mgr)
{
    WORD32 i;

    display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;

    WORD32 i4_min_poc = INT32_MAX;
    WORD32 i4_min_poc_buf_id = -1;
    WORD32 i4_min_index = -1;

    if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_dpb_mgr->i4_display_delay)
    {
        for(i = 0; i < MAX_FRAMES; i++)
        {
            if((-1 != ps_display_buf_info[i].i4_poc_buf_id) &&
               (DO_NOT_DISP != ps_display_buf_info[i].i4_poc_buf_id))
            {
                /* Checking for <= is necessary to handle cases where there is one
                   valid buffer with poc set to 0x7FFFFFFF. */
                if(ps_display_buf_info[i].i4_poc <= i4_min_poc)
                {
                    i4_min_poc = ps_display_buf_info[i].i4_poc;
                    i4_min_poc_buf_id = ps_display_buf_info[i].i4_poc_buf_id;
                    i4_min_index = i;
                }
            }
        }

        if((i4_min_index != -1) && (DO_NOT_DISP != i4_min_poc_buf_id))
        {
            ps_dpb_mgr->i4_cur_display_seq++;

            ih264_disp_mgr_add(
                ps_dpb_mgr->ps_disp_buf_mgr, i4_min_poc_buf_id, ps_dpb_mgr->i4_cur_display_seq,
                ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_min_poc_buf_id]);

            ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
            ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;

            ps_dpb_mgr->i1_poc_buf_id_entries--;
        }
        else if(DO_NOT_DISP == i4_min_poc_buf_id)
        {
            return ERROR_GAPS_IN_FRM_NUM;
        }
    }

    return OK;
}

WORD32 imvcd_dpb_insert_pic_in_display_list(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_poc,
                                            UWORD32 u4_frame_num, WORD32 i4_buf_id)
{
    WORD32 i;

    display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;

    for(i = 0; i < MAX_FRAMES; i++)
    {
        /* Find an empty slot */
        if(ps_display_buf_info[i].i4_poc_buf_id == -1)
        {
            if(GAP_FRAME_NUM == ps_display_buf_info[i].i4_frame_num)
            {
                ps_dpb_mgr->i1_gaps_deleted--;
            }
            else
            {
                ps_dpb_mgr->i1_poc_buf_id_entries++;
            }

            ps_display_buf_info[i].i4_poc_buf_id = i4_buf_id;
            ps_display_buf_info[i].i4_poc = i4_display_poc;
            ps_display_buf_info[i].i4_frame_num = u4_frame_num;

            break;
        }
    }

    if(MAX_FRAMES == i)
    {
        return ERROR_GAPS_IN_FRM_NUM;
    }

    return OK;
}

static WORD32 imvcd_dpb_delete_gap_frm_sliding(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_pic_num,
                                               UWORD8 *pu1_del_node)
{
    WORD32 i, j, j_min;
    WORD8 i1_gap_idx;
    WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num;
    WORD32 i4_start_frm_num, i4_end_frm_num;
    WORD32 i4_max_pic_num;
    WORD32 i4_frm_num, i4_gap_frm_num_min;

    /* find the least frame num from gaps and current DPB node    */
    /* Delete the least one                                       */
    *pu1_del_node = 1;

    if(0 == ps_dpb_mgr->u1_num_gaps)
    {
        return OK;
    }

    pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
    pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num;
    i4_gap_frame_num = INVALID_FRAME_NUM;
    i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;

    i1_gap_idx = -1;

    if(INVALID_FRAME_NUM != i4_pic_num)
    {
        i4_gap_frame_num = i4_pic_num;

        for(i = 0; i < MAX_FRAMES; i++)
        {
            i4_start_frm_num = pi4_gaps_start_frm_num[i];

            if(INVALID_FRAME_NUM != i4_start_frm_num)
            {
                i4_end_frm_num = pi4_gaps_end_frm_num[i];

                if(i4_end_frm_num < i4_max_pic_num)
                {
                    if(i4_start_frm_num <= i4_gap_frame_num)
                    {
                        i4_gap_frame_num = i4_start_frm_num;
                        i1_gap_idx = i;
                    }
                }
                else
                {
                    if(((i4_start_frm_num <= i4_gap_frame_num) &&
                        (i4_gap_frame_num <= i4_max_pic_num)) ||
                       ((i4_start_frm_num >= i4_gap_frame_num) &&
                        ((i4_gap_frame_num + i4_max_pic_num) >= i4_end_frm_num)))
                    {
                        i4_gap_frame_num = i4_start_frm_num;
                        i1_gap_idx = i;
                    }
                }
            }
        }
    }
    else
    {
        /* no valid short term buffers, delete one gap from the least start */
        /* of gap sequence                                                  */
        i4_gap_frame_num = pi4_gaps_start_frm_num[0];
        i1_gap_idx = 0;

        for(i = 1; i < MAX_FRAMES; i++)
        {
            if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i])
            {
                if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num)
                {
                    i4_gap_frame_num = pi4_gaps_start_frm_num[i];
                    i1_gap_idx = i;
                }
            }
        }
        if(INVALID_FRAME_NUM == i4_gap_frame_num)
        {
            return ERROR_DBP_MANAGER_T;
        }
    }

    if(-1 != i1_gap_idx)
    {
        /* find least frame_num in the poc_map, which is in this range */
        i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx];

        if(i4_start_frm_num < 0)
        {
            i4_start_frm_num += i4_max_pic_num;
        }

        i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx];

        if(i4_end_frm_num < 0)
        {
            i4_end_frm_num += i4_max_pic_num;
        }

        i4_gap_frm_num_min = INT32_MIN;
        j_min = MAX_FRAMES;

        for(j = 0; j < MAX_FRAMES; j++)
        {
            i4_frm_num = ps_dpb_mgr->as_display_buf_info[j].i4_frame_num;

            if((i4_start_frm_num <= i4_frm_num) && (i4_end_frm_num >= i4_frm_num))
            {
                if(i4_frm_num < i4_gap_frm_num_min)
                {
                    j_min = j;
                    i4_gap_frm_num_min = i4_frm_num;
                }
            }
        }

        if(j_min != MAX_FRAMES)
        {
            ps_dpb_mgr->as_display_buf_info[j_min].i4_poc_buf_id = -1;
            ps_dpb_mgr->as_display_buf_info[j_min].i4_poc = 0x7fffffff;
            ps_dpb_mgr->as_display_buf_info[j_min].i4_frame_num = GAP_FRAME_NUM;

            ps_dpb_mgr->i1_gaps_deleted++;
            ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--;
            ps_dpb_mgr->u1_num_gaps--;
            *pu1_del_node = 0;

            if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx])
            {
                ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] = INVALID_FRAME_NUM;
                ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0;
            }
        }
    }

    return OK;
}

WORD32 imvcd_dpb_do_mmco_for_gaps(mvc_dpb_manager_t *ps_dpb_mgr, UWORD8 u1_num_ref_frames)
{
    mvc_dpb_info_t *ps_next_dpb;

    WORD32 i;
    WORD32 i4_error_code;
    UWORD8 u1_num_gaps;
    UWORD8 u1_num_st_ref_bufs, u1_num_lt_ref_bufs, u1_del_node;

    WORD32 i4_frame_gaps = 1;

    // Sliding window - implements 8.2.5.3, flush out buffers
    u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs;
    u1_num_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs;

    while(1)
    {
        u1_num_gaps = ps_dpb_mgr->u1_num_gaps;

        if((u1_num_st_ref_bufs + u1_num_lt_ref_bufs + u1_num_gaps + i4_frame_gaps) >
           u1_num_ref_frames)
        {
            if(0 == (u1_num_st_ref_bufs + u1_num_gaps))
            {
                i4_frame_gaps = 0;

                ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames - u1_num_lt_ref_bufs);
            }
            else
            {
                u1_del_node = 1;
                ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;

                if(u1_num_st_ref_bufs > 1)
                {
                    for(i = 1; i < (u1_num_st_ref_bufs - 1); i++)
                    {
                        if(ps_next_dpb == NULL)
                        {
                            return ERROR_DBP_MANAGER_T;
                        }

                        ps_next_dpb = ps_next_dpb->ps_prev_short;
                    }

                    if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    if(u1_num_gaps)
                    {
                        i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
                            ps_dpb_mgr, ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num,
                            &u1_del_node);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }
                    }

                    if(u1_del_node)
                    {
                        u1_num_st_ref_bufs--;
                        ps_next_dpb->ps_prev_short->b_used_as_ref = false;
                        ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = UNUSED_FOR_REF;
                        ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

                        imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                            ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                            ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_buf_id);

                        ps_next_dpb->ps_prev_short->ps_au_buf = NULL;
                        ps_next_dpb->ps_prev_short = NULL;
                    }
                }
                else
                {
                    if(u1_num_st_ref_bufs)
                    {
                        if(u1_num_gaps)
                        {
                            i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
                                ps_dpb_mgr, ps_next_dpb->ps_au_buf->i4_pic_num, &u1_del_node);

                            if(i4_error_code != OK)
                            {
                                return i4_error_code;
                            }
                        }

                        if(u1_del_node)
                        {
                            u1_num_st_ref_bufs--;
                            ps_next_dpb->b_used_as_ref = false;
                            ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
                            ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

                            imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                                ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                                ps_next_dpb->ps_au_buf->i4_pic_buf_id);

                            ps_next_dpb->ps_au_buf = NULL;
                            ps_next_dpb = NULL;
                            ps_dpb_mgr->ps_dpb_st_head = NULL;
                            ps_dpb_mgr->u1_num_st_ref_bufs = u1_num_st_ref_bufs;
                        }
                    }
                    else
                    {
                        i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
                            ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }

                        if(u1_del_node)
                        {
                            return ERROR_DBP_MANAGER_T;
                        }
                    }
                }
            }
        }
        else
        {
            ps_dpb_mgr->u1_num_gaps += i4_frame_gaps;

            break;
        }
    }

    ps_dpb_mgr->u1_num_st_ref_bufs = u1_num_st_ref_bufs;

    return OK;
}

void imvcd_dpb_delete_nonref_nondisplay_pics(mvc_dpb_manager_t *ps_dpb_mgr)
{
    WORD32 i;

    display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;

    /* remove all gaps marked as unused for ref */
    for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++)
    {
        if(GAP_FRAME_NUM == ps_display_buf_info[i].i4_frame_num)
        {
            ps_dpb_mgr->i1_gaps_deleted--;
            ps_dpb_mgr->i1_poc_buf_id_entries--;
            ps_display_buf_info[i].i4_poc_buf_id = -1;
            ps_display_buf_info[i].i4_poc = 0x7fffffff;
            ps_display_buf_info[i].i4_frame_num = 0;
        }
    }
}

void imvcd_reset_dpb(mvc_dpb_manager_t *ps_dpb_mgr)
{
    WORD32 i;

    mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;

    for(i = 0; i < MVC_MAX_REF_PICS; i++)
    {
        if(ps_dpb_info[i].b_used_as_ref)
        {
            imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                ps_dpb_info[i].ps_au_buf->i4_pic_buf_id);

            ps_dpb_info[i].b_used_as_ref = false;
            ps_dpb_info[i].ps_prev_short = NULL;
            ps_dpb_info[i].ps_prev_long = NULL;
            ps_dpb_info[i].ps_au_buf = NULL;
            ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
            ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
            ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
            ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
        }
    }

    ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
    ps_dpb_mgr->ps_dpb_st_head = NULL;
    ps_dpb_mgr->ps_dpb_lt_head = NULL;
    ps_dpb_mgr->u1_mmco_error_in_seq = 0;

    /* release all gaps */
    ps_dpb_mgr->u1_num_gaps = 0;

    for(i = 0; i < MAX_FRAMES; i++)
    {
        ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
        ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
        ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
    }
}

void imvcd_dpb_release_display_bufs(mvc_dpb_manager_t *ps_dpb_mgr)
{
    WORD32 i, j;

    display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;

    WORD32 i4_min_poc = 0x7fffffff;
    WORD32 i4_min_poc_buf_id = 0;
    WORD32 i4_min_index = 0;

    imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr);

    for(j = 0; j < ps_dpb_mgr->i1_poc_buf_id_entries; j++)
    {
        i4_min_poc = 0x7fffffff;

        for(i = 0; i < MAX_FRAMES; i++)
        {
            if(ps_display_buf_info[i].i4_poc_buf_id != -1)
            {
                /* Checking for <= is necessary to handle cases where there is one
                   valid buffer with poc set to 0x7FFFFFFF. */
                if(ps_display_buf_info[i].i4_poc <= i4_min_poc)
                {
                    i4_min_poc = ps_display_buf_info[i].i4_poc;
                    i4_min_poc_buf_id = ps_display_buf_info[i].i4_poc_buf_id;
                    i4_min_index = i;
                }
            }
        }

        if(DO_NOT_DISP != i4_min_poc_buf_id)
        {
            ps_dpb_mgr->i4_cur_display_seq++;

            ih264_disp_mgr_add(
                ps_dpb_mgr->ps_disp_buf_mgr, i4_min_poc_buf_id, ps_dpb_mgr->i4_cur_display_seq,
                ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_min_poc_buf_id]);

            ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
            ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
            ps_display_buf_info[i4_min_index].i4_frame_num = 0;
        }
        else
        {
            ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
            ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
            ps_display_buf_info[i4_min_index].i4_frame_num = 0;
        }
    }

    ps_dpb_mgr->i1_poc_buf_id_entries = 0;
}

void imvcd_assign_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_frame_num,
                          WORD32 i4_cur_frame_num, bool b_are_gaps_in_frame_num_value_allowed)
{
    mvc_dpb_info_t *ps_next_dpb;

    WORD32 i;
    WORD32 i4_ref_frame_num;

    /* Start from ST head */
    ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;

    for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
    {
        WORD32 i4_pic_num;

        i4_ref_frame_num = ps_next_dpb->ps_au_buf->i4_pic_num;

        if(i4_ref_frame_num > i4_cur_frame_num)
        {
            i4_pic_num = i4_ref_frame_num - i4_max_frame_num;
        }
        else
        {
            i4_pic_num = i4_ref_frame_num;
        }

        ps_next_dpb->ps_au_buf->i4_pic_num = i4_pic_num;

        ps_next_dpb = ps_next_dpb->ps_prev_short;
    }

    if(b_are_gaps_in_frame_num_value_allowed && ps_dpb_mgr->u1_num_gaps)
    {
        WORD32 i4_start_frm, i4_end_frm;

        /* Assign pic numbers for gaps */
        for(i = 0; i < MAX_FRAMES; i++)
        {
            i4_start_frm = ps_dpb_mgr->ai4_gaps_start_frm_num[i];

            if(i4_start_frm != INVALID_FRAME_NUM)
            {
                if(i4_start_frm > i4_cur_frame_num)
                {
                    /* gap's frame_num is before Current frame_num in
                     decode order */
                    i4_start_frm -= i4_max_frame_num;
                }

                ps_dpb_mgr->ai4_gaps_start_frm_num[i] = i4_start_frm;
                i4_end_frm = ps_dpb_mgr->ai4_gaps_end_frm_num[i];

                if(i4_end_frm > i4_cur_frame_num)
                {
                    /* gap's frame_num is before Current frame_num in
                     decode order */
                    i4_end_frm -= i4_max_frame_num;
                }

                ps_dpb_mgr->ai4_gaps_end_frm_num[i] = i4_end_frm;
            }
        }
    }
}

/* If there is common node in both lt_list and st_list, then delete it from */
/* st_list */
UWORD8 imvcd_dpb_st_lt_deduplicator(mvc_dpb_manager_t *ps_dpb_mgr)
{
    mvc_dpb_info_t *ps_dpb_lt_head = ps_dpb_mgr->ps_dpb_lt_head;
    mvc_dpb_info_t *ps_lt_curr_dpb = ps_dpb_mgr->ps_dpb_lt_head;
    mvc_dpb_info_t *ps_dpb_st_head = ps_dpb_mgr->ps_dpb_st_head;

    UWORD8 u1_no_of_nodes_deleted = 0;
    UWORD8 u1_num_lt_refs = ps_dpb_mgr->u1_num_lt_ref_bufs;
    UWORD8 u1_num_st_refs = ps_dpb_mgr->u1_num_st_ref_bufs;

    while(u1_num_lt_refs && ps_dpb_lt_head)
    {
        if(ps_dpb_st_head &&
           ((ps_dpb_lt_head->s_bot_field.u1_reference_info |
             ps_dpb_lt_head->s_top_field.u1_reference_info) == (IS_SHORT_TERM | IS_LONG_TERM)))
        {
            mvc_dpb_info_t *ps_st_next_dpb = ps_dpb_st_head;
            mvc_dpb_info_t *ps_st_curr_dpb = ps_dpb_st_head;

            while(u1_num_st_refs && ps_st_curr_dpb)
            {
                if(ps_st_curr_dpb == ps_lt_curr_dpb)
                {
                    if(u1_num_st_refs == ps_dpb_mgr->u1_num_st_ref_bufs)
                    {
                        ps_dpb_mgr->ps_dpb_st_head = ps_dpb_mgr->ps_dpb_st_head->ps_prev_short;
                        ps_st_curr_dpb = ps_dpb_mgr->ps_dpb_st_head;
                    }
                    else
                    {
                        ps_st_next_dpb->ps_prev_short = ps_st_curr_dpb->ps_prev_short;
                    }

                    ps_dpb_mgr->u1_num_st_ref_bufs--;
                    u1_no_of_nodes_deleted++;

                    break;
                }

                ps_st_next_dpb = ps_st_curr_dpb;
                ps_st_curr_dpb = ps_st_curr_dpb->ps_prev_short;
                u1_num_st_refs--;
            }
        }

        ps_lt_curr_dpb = ps_lt_curr_dpb->ps_prev_long;
        u1_num_lt_refs--;
    }

    return u1_no_of_nodes_deleted;
}

static int qsort_pic_num_compare(const void *pv_au1, const void *pv_au2)
{
    return ((mvc_au_buffer_t **) pv_au1)[0]->i4_pic_num -
           ((mvc_au_buffer_t **) pv_au2)[0]->i4_pic_num;
}

static int qsort_poc_compare(const void *pv_au1, const void *pv_au2)
{
    return ((mvc_au_buffer_t **) pv_au1)[0]->i4_poc - ((mvc_au_buffer_t **) pv_au2)[0]->i4_poc;
}

static int qsort_lt_idx_compare(const void *pv_au1, const void *pv_au2)
{
    return ((mvc_au_buffer_t **) pv_au1)[0]->u1_long_term_frm_idx -
           ((mvc_au_buffer_t **) pv_au2)[0]->u1_long_term_frm_idx;
}

WORD32 imvcd_init_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr, nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
                               mvc_au_buffer_t *ps_cur_au, UWORD16 u2_view_order_id)
{
    mvc_dpb_info_t *ps_ref_au_data;
    mvc_ivp_ref_data_t *ps_mvc_ivp_ref_data;

    WORD32 i, j;

    mvc_au_buffer_t *aps_st_au_bufs[MVC_MAX_REF_PICS] = {NULL};
    mvc_au_buffer_t *aps_lt_au_bufs[MVC_MAX_REF_PICS] = {NULL};
    mvc_au_buffer_t *aps_ref_pic_buf_lx[2] = {ps_dpb_mgr->as_init_dpb[0],
                                              ps_dpb_mgr->as_init_dpb[1]};
    sps_mvc_ext_t *ps_sps_mvc_ext = ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext;

    UWORD16 u2_view_id = ps_cur_nalu_mvc_ext->u2_view_id;
    WORD32 i4_cur_poc = ps_cur_au->i4_poc;
    bool b_is_b_pic = !!(ps_cur_au->au4_pack_slc_typ[u2_view_order_id] & B_SLC_BIT);
    UWORD8 *pu1_num_short_term_refs = ps_dpb_mgr->au1_num_active_st_refs;
    UWORD8 *pu1_num_long_term_refs = ps_dpb_mgr->au1_num_active_lt_refs;
    UWORD8 au1_total_num_refs[2] = {0};

    memset(pu1_num_short_term_refs, 0, 2 * sizeof(pu1_num_short_term_refs[0]));

    memset(pu1_num_long_term_refs, 0, 2 * sizeof(pu1_num_long_term_refs[0]));

    ps_ref_au_data = ps_dpb_mgr->ps_dpb_st_head;

    for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
    {
        aps_st_au_bufs[i] = ps_ref_au_data->ps_au_buf;
        ps_ref_au_data = ps_ref_au_data->ps_prev_short;
    }

    qsort(aps_st_au_bufs, ps_dpb_mgr->u1_num_st_ref_bufs, sizeof(aps_st_au_bufs[0]),
          b_is_b_pic ? qsort_poc_compare : qsort_pic_num_compare);

    ps_ref_au_data = ps_dpb_mgr->ps_dpb_lt_head;

    for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
    {
        aps_lt_au_bufs[i] = ps_ref_au_data->ps_au_buf;
        ps_ref_au_data = ps_ref_au_data->ps_prev_long;
    }

    qsort(aps_lt_au_bufs, ps_dpb_mgr->u1_num_lt_ref_bufs, sizeof(aps_lt_au_bufs[0]),
          qsort_lt_idx_compare);

    if(b_is_b_pic)
    {
        for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
        {
            if(aps_st_au_bufs[i]->i4_poc >= i4_cur_poc)
            {
                break;
            }
        }

        for(j = i - 1; j >= 0; j--)
        {
            aps_ref_pic_buf_lx[0][0] = aps_st_au_bufs[j][0];
            aps_ref_pic_buf_lx[0]++;
            pu1_num_short_term_refs[0]++;
        }

        for(j = i; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
        {
            aps_ref_pic_buf_lx[1][0] = aps_st_au_bufs[j][0];
            aps_ref_pic_buf_lx[1]++;
            pu1_num_short_term_refs[1]++;
        }
    }
    else
    {
        for(i = ps_dpb_mgr->u1_num_st_ref_bufs - 1; i >= 0; i--)
        {
            aps_ref_pic_buf_lx[0][0] = aps_st_au_bufs[i][0];
            aps_ref_pic_buf_lx[0]++;
            pu1_num_short_term_refs[0]++;
        }
    }

    for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
    {
        for(j = 0; j < 1 + ((WORD32) b_is_b_pic); j++)
        {
            aps_ref_pic_buf_lx[j][0] = aps_lt_au_bufs[i][0];
            aps_ref_pic_buf_lx[j]->u1_long_term_pic_num =
                aps_ref_pic_buf_lx[j]->u1_long_term_frm_idx;
            aps_ref_pic_buf_lx[j]++;
            pu1_num_long_term_refs[j]++;
        }
    }

    if(0 != u2_view_order_id)
    {
        ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;

        for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
        {
            WORD32 i4_num_refs;

            if(ps_cur_nalu_mvc_ext->u1_anchor_pic_flag)
            {
                ps_mvc_ivp_ref_data = &ps_sps_mvc_ext->as_anchor_ref_data[i][u2_view_order_id];
            }
            else
            {
                ps_mvc_ivp_ref_data = &ps_sps_mvc_ext->as_non_anchor_ref_data[i][u2_view_order_id];
            }

            i4_num_refs = ps_mvc_ivp_ref_data->u1_num_refs;

            for(j = 0; j < i4_num_refs; j++)
            {
                mvc_au_buffer_t *ps_au_buf;
                mvc_au_mv_pred_t *ps_au_mv_data;
                nalu_mvc_ext_t *ps_ref_nalu_mvc_ext;

                WORD32 i4_pic_buf_id;
                WORD32 i4_mv_buf_id;

                UWORD16 u2_ref_view_id = ps_mvc_ivp_ref_data->au2_ref_view_ids[j];

                ps_ref_nalu_mvc_ext = imvcd_get_nalu_mvc_ext(
                    ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts, u2_view_order_id, u2_ref_view_id);

                if(!ps_ref_nalu_mvc_ext->u1_inter_view_flag)
                {
                    continue;
                }

                ps_au_buf = ih264_buf_mgr_get_next_free(
                    ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt, &i4_pic_buf_id);

                if(NULL == ps_au_buf)
                {
                    return ERROR_UNAVAIL_PICBUF_T;
                }
                else
                {
                    ih264_buf_mgr_set_status(ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt,
                                             i4_pic_buf_id, BUF_MGR_REF);
                }

                ps_au_mv_data = ih264_buf_mgr_get_next_free(
                    ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt, &i4_mv_buf_id);

                if(NULL == ps_au_mv_data)
                {
                    return ERROR_UNAVAIL_PICBUF_T;
                }
                else
                {
                    ih264_buf_mgr_set_status(ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
                                             i4_mv_buf_id, BUF_MGR_REF);
                }

                ps_au_buf->i4_pic_buf_id = i4_pic_buf_id;
                ps_au_buf->i4_mv_buf_id = i4_mv_buf_id;
                ps_au_buf->s_ivp_data.b_is_ivp_ref = true;
                ps_au_buf->s_ivp_data.u2_ref_view_id = u2_ref_view_id;

                imvcd_ivp_buf_copier(ps_cur_au, ps_au_buf, ps_cur_au->ps_au_mv_data, ps_au_mv_data,
                                     u2_ref_view_id, u2_view_id);

                ps_dpb_mgr->ps_mvc_au_buf_mgr->au1_au_buf_id_to_mv_buf_id_map[i4_pic_buf_id] =
                    i4_mv_buf_id;
                ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_pic_buf_id] = ps_au_buf;
                ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->aps_buf_id_to_mv_pred_buf_map[i4_mv_buf_id] =
                    ps_au_mv_data;

                ps_dpb_mgr->s_dpb_ivp_ctxt
                    .au1_au_buf_ids[ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs] = i4_pic_buf_id;
                ps_dpb_mgr->s_dpb_ivp_ctxt
                    .au1_mv_buf_ids[ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs] = i4_mv_buf_id;

                aps_ref_pic_buf_lx[i][0] = ps_au_buf[0];

                aps_ref_pic_buf_lx[i]++;
                pu1_num_short_term_refs[i]++;
                ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs++;
            }
        }
    }

    for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
    {
        au1_total_num_refs[i] = pu1_num_short_term_refs[i] + pu1_num_long_term_refs[i];

        if(pu1_num_short_term_refs[i] > MVC_MAX_REF_PICS)
        {
            return ERROR_NUM_REF;
        }

        if(au1_total_num_refs[i] > MVC_MAX_REF_PICS)
        {
            return ERROR_NUM_REF;
        }

        if(0 == au1_total_num_refs[i])
        {
            return ERROR_NUM_REF;
        }
    }

    /* If list0 and list1 entries are same then swap the 0th and 1st entry */
    /* of list 1 */
    {
        mvc_au_buffer_t *aps_ref_pic_bufs_lx[2] = {ps_dpb_mgr->as_init_dpb[0],
                                                   ps_dpb_mgr->as_init_dpb[1]};

        if((au1_total_num_refs[0] == au1_total_num_refs[1]) && (au1_total_num_refs[0] > 1))
        {
            bool b_swap;

            b_swap = true;

            for(i = 0; i < au1_total_num_refs[0]; i++)
            {
                if(aps_ref_pic_bufs_lx[0][i]
                       .as_view_buffers[u2_view_id]
                       .as_component_bufs[Y]
                       .pv_data != aps_ref_pic_bufs_lx[1][i]
                                       .as_view_buffers[u2_view_id]
                                       .as_component_bufs[Y]
                                       .pv_data)
                {
                    b_swap = false;

                    break;
                }
            }

            if(b_swap)
            {
                SWAP(aps_ref_pic_bufs_lx[1][0], aps_ref_pic_bufs_lx[1][1], mvc_au_buffer_t);
            }
        }
    }

    return OK;
}

void imvcd_dpb_set_missing_refs_to_default(mvc_dpb_manager_t *ps_dpb_mgr,
                                           ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
                                           mvc_au_buffer_t *ps_cur_au, UWORD8 u1_pred_lx)
{
    UWORD8 u1_num_refs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx] +
                         ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_lx];

    while(u1_num_refs < ps_ref_pic_list_mod_data->au1_num_active_refs[u1_pred_lx])
    {
        ps_dpb_mgr->as_init_dpb[u1_pred_lx][u1_num_refs] = ps_cur_au[0];
        ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx]++;
        u1_num_refs++;
    }
}

void imvcd_dpb_normalise_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_buf_mod_bitfield,
                                      UWORD8 u1_num_bufs_modified, UWORD8 u1_pred_lx)
{
    WORD32 i;

    UWORD8 u1_num_ref_bufs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx] +
                             ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_lx];

    for(i = 0; i < u1_num_ref_bufs; i++)
    {
        if(u1_num_bufs_modified >= MVC_MAX_REF_PICS)
        {
            return;
        }

        if(!(u2_buf_mod_bitfield & (1 << i)))
        {
            ps_dpb_mgr->aps_mod_dpb[u1_pred_lx][u1_num_bufs_modified++] =
                &ps_dpb_mgr->as_init_dpb[u1_pred_lx][i];
        }
    }
}

WORD32 imvcd_dpb_reorder_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
                                      nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
                                      mvc_au_buffer_t *ps_cur_au,
                                      ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
                                      UWORD16 u2_view_order_id)
{
    WORD32 i, j;

    sps_mvc_ext_t *ps_sps_mvc_ext = ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext;

    UWORD8 u1_anchor_pic_flag = ps_cur_nalu_mvc_ext->u1_anchor_pic_flag;
    WORD32 i4_cur_pic_num = ps_cur_au->i4_pic_num;
    WORD32 i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
    bool b_is_b_pic = !!(ps_cur_au->au4_pack_slc_typ[u2_view_order_id] & B_SLC_BIT);

    for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
    {
        mvc_ivp_ref_data_t *ps_mvc_ivp_ref_data;

        UWORD16 u2_max_view_idx;

        WORD32 i4_pred_pic_num = i4_cur_pic_num;
        WORD16 i2_pred_view_order_id = 0;  // -1; Need to check spec and JMVM implementation match
        UWORD8 *pu1_modification_of_pic_nums_idc =
            ps_ref_pic_list_mod_data->au1_modification_of_pic_nums_idc[i];
        WORD32 *pi4_abs_diff_pic_num_minus1 =
            ps_ref_pic_list_mod_data->ai4_abs_diff_pic_num_minus1[i];
        WORD32 *pi4_long_term_pic_num = ps_ref_pic_list_mod_data->ai4_long_term_pic_num[i];
        WORD32 *pi4_abs_diff_view_idx_minus1 =
            ps_ref_pic_list_mod_data->ai4_abs_diff_view_idx_minus1[i];
        UWORD8 u1_num_ref_bufs =
            ps_dpb_mgr->au1_num_active_st_refs[i] + ps_dpb_mgr->au1_num_active_lt_refs[i];
        UWORD16 u2_buf_mod_bitfield = 0;
        UWORD8 u1_num_bufs_modified = 0;

        if(!ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i] ||
           (3 == pu1_modification_of_pic_nums_idc[0]))
        {
            imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au,
                                                  i);

            imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified,
                                             i);

            continue;
        }

        ps_mvc_ivp_ref_data =
            (0 == u2_view_order_id)
                ? NULL
                : (u1_anchor_pic_flag
                       ? &ps_sps_mvc_ext->as_anchor_ref_data[i][u2_view_order_id]
                       : &ps_sps_mvc_ext->as_non_anchor_ref_data[i][u2_view_order_id]);
        u2_max_view_idx = (0 == u2_view_order_id) ? 0 : ps_mvc_ivp_ref_data->u1_num_refs;

        do
        {
            if((0 == pu1_modification_of_pic_nums_idc[0]) ||
               (1 == pu1_modification_of_pic_nums_idc[0]))
            {
                WORD32 i4_mod_pic_num = pi4_abs_diff_pic_num_minus1[0];

                UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;

                /* According to section 7.4.3.1 from spec, */
                /* this value is expected to be from the */
                /* closed interval [0, i4_max_pic_num - 1] */
                if((i4_mod_pic_num < 0) || (i4_mod_pic_num >= i4_max_pic_num))
                {
                    return ERROR_DBP_MANAGER_T;
                }

                /* +1 not accounted during initialisation, */
                /* mainly to preclude integer overflow */
                i4_mod_pic_num++;

                if(0 == pu1_modification_of_pic_nums_idc[0])
                {
                    i4_mod_pic_num = i4_pred_pic_num - i4_mod_pic_num;

                    if(i4_mod_pic_num < 0)
                    {
                        i4_mod_pic_num += i4_max_pic_num;
                    }
                }
                else
                {
                    i4_mod_pic_num = i4_pred_pic_num + i4_mod_pic_num;

                    if(i4_mod_pic_num >= i4_max_pic_num)
                    {
                        i4_mod_pic_num -= i4_max_pic_num;
                    }
                }

                if(i4_mod_pic_num > i4_cur_pic_num)
                {
                    i4_mod_pic_num -= i4_max_pic_num;
                }

                for(j = 0; j < u1_num_ref_bufs; j++)
                {
                    if(ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_mod_pic_num)
                    {
                        u1_mod_buf_idx = j;

                        break;
                    }
                }

                if(u1_mod_buf_idx == u1_num_ref_bufs)
                {
                    return ERROR_DBP_MANAGER_T;
                }

                ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
                    &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];

                u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
                i4_pred_pic_num = i4_mod_pic_num;
            }
            else if(2 == pu1_modification_of_pic_nums_idc[0])
            {
                WORD32 i4_mod_lt_pic_num = pi4_long_term_pic_num[0];
                UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;

                if(pi4_long_term_pic_num[0] > (MAX_REF_BUFS + 1))
                {
                    return ERROR_DBP_MANAGER_T;
                }

                for(j = 0; j < u1_num_ref_bufs; j++)
                {
                    if(!ps_dpb_mgr->as_init_dpb[i][j].b_is_short_term_ref &&
                       (i4_mod_lt_pic_num == ps_dpb_mgr->as_init_dpb[i][j].u1_long_term_pic_num))
                    {
                        u1_mod_buf_idx = j;

                        break;
                    }
                }

                if(u1_mod_buf_idx == u1_num_ref_bufs)
                {
                    return ERROR_DBP_MANAGER_T;
                }

                ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
                    &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];

                u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
            }
            else if((4 == pu1_modification_of_pic_nums_idc[0]) ||
                    (5 == pu1_modification_of_pic_nums_idc[0]))
            {
                WORD32 i4_target_view_id;

                WORD32 i4_mod_view_order_id = pi4_abs_diff_view_idx_minus1[0];
                UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;

                /* According to section H.7.4.3.1.1 from spec, */
                /* this value is expected to be from the */
                /* closed interval [0, u2_max_view_idx - 1] */
                if((i4_mod_view_order_id < 0) || (i4_mod_view_order_id >= u2_max_view_idx))
                {
                    return ERROR_DBP_MANAGER_T;
                }

                /* +1 not accounted during initialisation, */
                /* mainly to preclude integer overflow */
                i4_mod_view_order_id++;

                if(4 == pu1_modification_of_pic_nums_idc[0])
                {
                    i4_mod_view_order_id = i2_pred_view_order_id - i4_mod_view_order_id;

                    if(i4_mod_view_order_id < 0)
                    {
                        i4_mod_view_order_id += u2_max_view_idx;
                    }
                }
                else
                {
                    i4_mod_view_order_id = i2_pred_view_order_id + i4_mod_view_order_id;

                    if(i4_mod_view_order_id >= u2_max_view_idx)
                    {
                        i4_mod_view_order_id -= u2_max_view_idx;
                    }
                }

                if((0 == u2_view_order_id) || (NULL == ps_mvc_ivp_ref_data))
                {
                    return ERROR_DBP_MANAGER_T;
                }

                i4_target_view_id = ps_mvc_ivp_ref_data->au2_ref_view_ids[i4_mod_view_order_id];

                for(j = 0; j < u1_num_ref_bufs; j++)
                {
                    if(ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.b_is_ivp_ref)
                    {
                        if((ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_cur_pic_num) &&
                           (ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.u2_ref_view_id ==
                            i4_target_view_id))
                        {
                            u1_mod_buf_idx = j;

                            break;
                        }
                    }
                }

                if(u1_mod_buf_idx == u1_num_ref_bufs)
                {
                    return ERROR_DBP_MANAGER_T;
                }

                u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
                ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
                    &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
                i2_pred_view_order_id = i4_mod_view_order_id;
            }
            else if(3 != pu1_modification_of_pic_nums_idc[0])
            {
                return ERROR_REFIDX_ORDER_T;
            }
            else
            {
                break;
            }

            pu1_modification_of_pic_nums_idc++;
            pi4_abs_diff_pic_num_minus1++;
            pi4_long_term_pic_num++;
            pi4_abs_diff_view_idx_minus1++;
        } while(true);

        imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au, i);

        imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified, i);
    }

    return OK;
}

WORD32 imvcd_dpb_insert_st_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_au_buf)
{
    WORD32 i;

    mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
    UWORD8 u1_picture_type = ps_au_buf->u1_picturetype;

    for(i = 0; i < MVC_MAX_REF_PICS; i++)
    {
        if((ps_dpb_info[i].ps_au_buf == ps_au_buf) && ps_dpb_info[i].b_used_as_ref)
        {
            /* Can occur only for field bottom pictures */
            if(ps_dpb_info[i].ps_au_buf->u1_pic_type == FRM_PIC)
            {
                return ERROR_DBP_MANAGER_T;
            }
            else
            {
                ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;

                return OK;
            }
        }

        if(!ps_dpb_info[i].b_used_as_ref &&
           (ps_dpb_info[i].s_top_field.u1_reference_info == UNUSED_FOR_REF) &&
           (ps_dpb_info[i].s_bot_field.u1_reference_info == UNUSED_FOR_REF))
        {
            break;
        }
    }

    if(i == MVC_MAX_REF_PICS)
    {
        return ERROR_DBP_MANAGER_T;
    }

    ps_dpb_info[i].ps_au_buf = ps_au_buf;
    ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
    ps_dpb_info[i].b_used_as_ref = true;

    ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;

    ps_dpb_mgr->u1_num_st_ref_bufs++;

    ps_au_buf->b_is_short_term_ref = true;

    if((u1_picture_type & 0x03) == FRM_PIC)
    {
        ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
        ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
    }
    else if((u1_picture_type & 0x03) == TOP_FLD)
    {
        ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
    }
    else if((u1_picture_type & 0x03) == BOT_FLD)
    {
        ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
    }

    return OK;
}

static WORD32 imvcd_dpb_delete_gap_frm_mmco(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_frame_num,
                                            UWORD8 *pu1_del_node)
{
    WORD8 i, j;
    WORD32 *pi4_start, *pi4_end;
    WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_pic_num;

    /* find the least frame num from gaps and current DPB node    */
    /* Delete the gaps                                            */
    *pu1_del_node = 1;
    pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
    pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
    i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;

    if(0 == ps_dpb_mgr->u1_num_gaps)
    {
        return OK;
    }

    if(i4_frame_num < 0)
    {
        i4_frame_num += i4_max_pic_num;
    }

    for(i = 0; i < MAX_FRAMES; i++)
    {
        i4_start_frm_num = pi4_start[i];

        if(i4_start_frm_num < 0)
        {
            i4_start_frm_num += i4_max_pic_num;
        }

        if(INVALID_FRAME_NUM != i4_start_frm_num)
        {
            i4_end_frm_num = pi4_end[i];

            if(i4_end_frm_num < 0)
            {
                i4_end_frm_num += i4_max_pic_num;
            }

            if((i4_frame_num >= i4_start_frm_num) && (i4_frame_num <= i4_end_frm_num))
            {
                break;
            }
            else
            {
                if(((i4_frame_num + i4_max_pic_num) >= i4_start_frm_num) &&
                   ((i4_frame_num + i4_max_pic_num) <= i4_end_frm_num))
                {
                    return ERROR_DBP_MANAGER_T;
                }
            }
        }
    }

    /* find frame_num index, in the poc_map which needs to be deleted */
    for(j = 0; j < MAX_FRAMES; j++)
    {
        if(i4_frame_num == ps_dpb_mgr->as_display_buf_info[j].i4_frame_num)
        {
            break;
        }
    }

    if(MAX_FRAMES != i)
    {
        if(j == MAX_FRAMES)
        {
            return ERROR_DBP_MANAGER_T;
        }

        ps_dpb_mgr->as_display_buf_info[j].i4_poc_buf_id = -1;
        ps_dpb_mgr->as_display_buf_info[j].i4_poc = 0x7fffffff;
        ps_dpb_mgr->as_display_buf_info[j].i4_frame_num = GAP_FRAME_NUM;

        ps_dpb_mgr->i1_gaps_deleted++;
        ps_dpb_mgr->ai1_gaps_per_seq[i]--;
        ps_dpb_mgr->u1_num_gaps--;
        *pu1_del_node = 0;

        if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
        {
            ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
            ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
        }
    }
    else
    {
        return ERROR_DBP_MANAGER_T;
    }

    return OK;
}

static WORD32 imvcd_dpb_insert_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_dpb_info_t *ps_new_node,
                                       UWORD32 u4_lt_idx)
{
    ps_new_node->s_top_field.u1_reference_info = IS_LONG_TERM;
    ps_new_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
    ps_new_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
    ps_new_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
    ps_new_node->ps_au_buf->u1_long_term_frm_idx = u4_lt_idx;
    ps_new_node->b_used_as_ref = true;

    if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
    {
        WORD32 i;

        mvc_dpb_info_t **pps_next_node = &ps_dpb_mgr->ps_dpb_lt_head;

        for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
        {
            if((*pps_next_node)->ps_au_buf->u1_long_term_frm_idx > u4_lt_idx)
            {
                ps_new_node->ps_prev_long = *pps_next_node;
                *pps_next_node = ps_new_node;

                break;
            }
            else if(NULL == (*pps_next_node)->ps_prev_long)
            {
                (*pps_next_node)->ps_prev_long = ps_new_node;
                ps_new_node->ps_prev_long = NULL;

                break;
            }

            pps_next_node = &(*pps_next_node)->ps_prev_long;
        }
    }
    else
    {
        ps_dpb_mgr->ps_dpb_lt_head = ps_new_node;
        ps_new_node->ps_prev_long = NULL;
    }

    ps_new_node->ps_au_buf->b_is_short_term_ref = false;

    ps_dpb_mgr->u1_num_lt_ref_bufs++;

    return OK;
}

static WORD32 imvcd_dpb_delete_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, UWORD32 u4_lt_idx)
{
    mvc_dpb_info_t *ps_next_dpb;
    mvc_dpb_info_t *ps_unmark_node;

    WORD32 i;

    if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
    {
        ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;

        if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
        {
            ps_unmark_node = ps_next_dpb;
        }
        else
        {
            for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
            {
                if(ps_next_dpb->ps_prev_long->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
                {
                    break;
                }

                ps_next_dpb = ps_next_dpb->ps_prev_long;
            }

            if(i < ps_dpb_mgr->u1_num_lt_ref_bufs)
            {
                ps_unmark_node = ps_next_dpb->ps_prev_long;
            }
            else
            {
                return OK;
            }
        }

        ps_unmark_node->b_used_as_ref = false;

        if(ps_unmark_node == ps_dpb_mgr->ps_dpb_lt_head)
        {
            ps_dpb_mgr->ps_dpb_lt_head = ps_next_dpb->ps_prev_long;
        }

        ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
        ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

        imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr, ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                            ps_unmark_node->ps_au_buf->i4_pic_buf_id);

        ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long;
        ps_unmark_node->ps_prev_long = NULL;
        ps_dpb_mgr->u1_num_lt_ref_bufs--;
    }

    return OK;
}

WORD32 imvcd_dpb_delete_st_node_or_make_lt(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_pic_num,
                                           UWORD32 u4_lt_idx)
{
    WORD32 i4_error_code;

    mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
    mvc_dpb_info_t *ps_unmark_node = NULL;

    UWORD8 u1_del_node = 0, u1_del_st = 0;
    WORD32 i = 0;

    if(ps_next_dpb->ps_au_buf->i4_pic_num == i4_pic_num)
    {
        ps_unmark_node = ps_next_dpb;
    }
    else
    {
        for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
        {
            if(ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num == i4_pic_num)
            {
                ps_unmark_node = ps_next_dpb->ps_prev_short;

                break;
            }

            ps_next_dpb = ps_next_dpb->ps_prev_short;
        }
    }

    if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
    {
        if(ps_dpb_mgr->u1_num_gaps)
        {
            i4_error_code = imvcd_dpb_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_del_st);

            if(i4_error_code != OK)
            {
                return i4_error_code;
            }
        }
        else
        {
            return ERROR_DBP_MANAGER_T;
        }

        if(u1_del_st)
        {
            return ERROR_DBP_MANAGER_T;
        }
        else
        {
            return 0;
        }
    }

    ps_unmark_node->b_used_as_ref = false;
    ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
    ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

    if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
    {
        ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
    }
    else
    {
        ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short;
    }

    ps_dpb_mgr->u1_num_st_ref_bufs--;
    u1_del_node = 1;

    if(u4_lt_idx == (MAX_REF_BUFS + 1))
    {
        if(u1_del_node)
        {
            imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                ps_unmark_node->ps_au_buf->i4_pic_buf_id);

            ps_unmark_node->ps_prev_short = NULL;
        }
    }
    else
    {
        i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);

        if(i4_error_code != OK)
        {
            return i4_error_code;
        }

        i4_error_code = imvcd_dpb_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx);

        if(i4_error_code != OK)
        {
            return i4_error_code;
        }
    }

    return OK;
}

WORD32 imvcd_dpb_do_mmco(dpb_commands_t *ps_dpb_cmds, mvc_dpb_manager_t *ps_dpb_mgr,
                         mvc_au_buffer_t *ps_cur_au, UWORD8 u1_max_num_ref_frames,
                         UWORD8 u1_curr_pic_in_err)
{
    mvc_dpb_info_t *ps_next_dpb;

    WORD32 i, j;
    UWORD8 u1_buf_mode, u1_marked_lt;
    UWORD8 u1_num_gaps;
    WORD32 i4_error_code;

    UWORD8 u1_del_node = 1;
    UWORD8 u1_insert_st_pic = 1;

    // 0 - sliding window; 1 - Adaptive
    u1_buf_mode = ps_dpb_cmds->u1_buf_mode;
    u1_marked_lt = 0;
    u1_num_gaps = ps_dpb_mgr->u1_num_gaps;

    if(!u1_buf_mode)
    {
        // Sliding window - implements 8.2.5.3
        if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps) ==
           u1_max_num_ref_frames)
        {
            UWORD8 u1_new_node_flag = 1;

            if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
            {
                return ERROR_DBP_MANAGER_T;
            }

            // Chase the links to reach the last but one picNum, if available
            ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;

            if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
            {
                if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
                {
                    return ERROR_DBP_MANAGER_T;
                }

                for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
                {
                    if(ps_next_dpb == NULL)
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    ps_next_dpb = ps_next_dpb->ps_prev_short;
                }

                if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
                {
                    return ERROR_DBP_MANAGER_T;
                }

                if(u1_new_node_flag)
                {
                    if(u1_num_gaps)
                    {
                        i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
                            ps_dpb_mgr, ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num,
                            &u1_del_node);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }
                    }

                    if(u1_del_node)
                    {
                        ps_dpb_mgr->u1_num_st_ref_bufs--;
                        ps_next_dpb->ps_prev_short->b_used_as_ref = false;
                        ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = UNUSED_FOR_REF;
                        ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

                        imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                            ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                            ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_buf_id);

                        ps_next_dpb->ps_prev_short->ps_au_buf = NULL;
                        ps_next_dpb->ps_prev_short = NULL;
                    }
                }
            }
            else
            {
                if(ps_dpb_mgr->u1_num_st_ref_bufs)
                {
                    i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
                        ps_dpb_mgr, ps_next_dpb->ps_au_buf->i4_pic_num, &u1_del_node);

                    if(i4_error_code != OK)
                    {
                        return i4_error_code;
                    }

                    if((ps_next_dpb->ps_au_buf->i4_pic_num != ps_cur_au->i4_pic_num) && u1_del_node)
                    {
                        ps_dpb_mgr->u1_num_st_ref_bufs--;
                        ps_next_dpb->b_used_as_ref = false;
                        ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
                        ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

                        imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                            ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                            ps_next_dpb->ps_au_buf->i4_pic_buf_id);

                        ps_next_dpb->ps_au_buf = NULL;
                        ps_next_dpb->ps_prev_short = NULL;
                        ps_dpb_mgr->ps_dpb_st_head = NULL;
                        ps_next_dpb = NULL;
                    }
                    else if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
                    {
                        if(u1_curr_pic_in_err)
                        {
                            u1_insert_st_pic = 0;
                        }
                        else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
                        {
                            ps_dpb_mgr->u1_num_st_ref_bufs--;
                            ps_next_dpb->b_used_as_ref = false;
                            ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
                            ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

                            imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                                ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                                ps_next_dpb->ps_au_buf->i4_pic_buf_id);

                            ps_next_dpb->ps_au_buf = NULL;
                            ps_next_dpb = NULL;
                        }
                    }
                }
                else
                {
                    i4_error_code = imvcd_dpb_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM,
                                                                     &u1_del_node);

                    if(i4_error_code != OK)
                    {
                        return i4_error_code;
                    }

                    if(u1_del_node)
                    {
                        return ERROR_DBP_MANAGER_T;
                    }
                }
            }
        }
    }
    else
    {
        // Adaptive memory control - implements 8.2.5.4
        struct MMCParams *ps_mmc_params;

        UWORD32 u4_mmco;
        UWORD32 u4_diff_pic_num;
        UWORD32 u4_lt_idx;

        UWORD32 au4_num_mmco_cmds[NUM_MMCO_CMD_IDS] = {0};

        for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
        {
            ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
            u4_mmco = ps_mmc_params->u4_mmco;

            switch(u4_mmco)
            {
                case MARK_ST_PICNUM_AS_NONREF:
                {
                    WORD64 i8_pic_num;

                    u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;
                    i8_pic_num =
                        ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));

                    if(IS_OUT_OF_RANGE_S32(i8_pic_num))
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
                    {
                        i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
                            ps_dpb_mgr, (WORD32) i8_pic_num, MAX_REF_BUFS + 1);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }
                    }
                    else
                    {
                        UWORD8 u1_dummy;

                        i4_error_code = imvcd_dpb_delete_gap_frm_mmco(
                            ps_dpb_mgr, (WORD32) i8_pic_num, &u1_dummy);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }
                    }

                    break;
                }
                case MARK_LT_INDEX_AS_NONREF:
                {
                    u4_lt_idx = ps_mmc_params->u4_lt_idx;

                    i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);

                    if(i4_error_code != OK)
                    {
                        return i4_error_code;
                    }

                    break;
                }
                case MARK_ST_PICNUM_AS_LT_INDEX:
                {
                    WORD64 i8_pic_num;

                    u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;

                    i8_pic_num =
                        ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));

                    if(IS_OUT_OF_RANGE_S32(i8_pic_num))
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    u4_lt_idx = ps_mmc_params->u4_lt_idx;

                    if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
                       (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
                    {
                        i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
                            ps_dpb_mgr, (WORD32) i8_pic_num, u4_lt_idx);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }
                    }

                    break;
                }
                case SET_MAX_LT_INDEX:
                {
                    if(au4_num_mmco_cmds[SET_MAX_LT_INDEX] > 0)
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    u4_lt_idx =
                        ps_mmc_params->u4_max_lt_idx_plus1;  // Get Max_long_term_index_plus1

                    if((u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx) &&
                       (ps_dpb_mgr->u1_num_lt_ref_bufs > 0))
                    {
                        mvc_dpb_info_t *ps_nxtDPB;

                        // Set all LT buffers with index >= u4_lt_idx to nonreference
                        ps_nxtDPB = ps_dpb_mgr->ps_dpb_lt_head;
                        ps_next_dpb = ps_nxtDPB->ps_prev_long;

                        if(ps_nxtDPB->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
                        {
                            i = 0;
                            ps_dpb_mgr->ps_dpb_lt_head = NULL;
                        }
                        else
                        {
                            for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
                            {
                                if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
                                {
                                    break;
                                }

                                ps_nxtDPB = ps_next_dpb;
                                ps_next_dpb = ps_next_dpb->ps_prev_long;
                            }

                            ps_nxtDPB->ps_prev_long = NULL;  // Terminate the link of the
                                                             // closest LTIndex that is <=Max
                        }

                        ps_dpb_mgr->u1_num_lt_ref_bufs = i;

                        if(i == 0)
                        {
                            ps_next_dpb = ps_nxtDPB;
                        }

                        for(; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
                        {
                            ps_nxtDPB = ps_next_dpb;
                            ps_nxtDPB->b_used_as_ref = false;
                            ps_nxtDPB->s_top_field.u1_reference_info = UNUSED_FOR_REF;
                            ps_nxtDPB->s_bot_field.u1_reference_info = UNUSED_FOR_REF;

                            imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
                                                ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
                                                ps_nxtDPB->ps_au_buf->i4_pic_buf_id);

                            ps_nxtDPB->ps_au_buf = NULL;

                            ps_next_dpb = ps_nxtDPB->ps_prev_long;
                            ps_nxtDPB->ps_prev_long = NULL;
                        }
                    }

                    if(u4_lt_idx == 0)
                    {
                        ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
                    }
                    else
                    {
                        ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
                    }

                    break;
                }
                case SET_LT_INDEX:
                {
                    if(au4_num_mmco_cmds[SET_LT_INDEX] > 0)
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    u4_lt_idx = ps_mmc_params->u4_lt_idx;  // Get long term index

                    if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
                       (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);

                    if(i4_error_code != OK)
                    {
                        return i4_error_code;
                    }

                    if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
                    {
                        i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
                            ps_dpb_mgr, ps_cur_au->i4_pic_num, u4_lt_idx);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }
                    }
                    else
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    u1_marked_lt = 1;

                    break;
                }
                case RESET_REF_PICTURES:
                {
                    if((au4_num_mmco_cmds[RESET_REF_PICTURES] > 0) ||
                       (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_NONREF] > 0) ||
                       (au4_num_mmco_cmds[MARK_LT_INDEX_AS_NONREF] > 0) ||
                       (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_LT_INDEX] > 0))
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    if((j > 0) && (ps_dpb_cmds->as_mmc_params[j - 1].u4_mmco == SET_LT_INDEX))
                    {
                        return ERROR_DBP_MANAGER_T;
                    }

                    __attribute__((fallthrough));
                }
                case RESET_ALL_PICTURES:
                {
                    WORD32 i4_pic_num = ps_cur_au->i4_frame_num;

                    imvcd_reset_dpb(ps_dpb_mgr);

                    ps_cur_au->i4_frame_num = 0;

                    if(!u1_marked_lt && u1_insert_st_pic)
                    {
                        i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);

                        if(i4_error_code != OK)
                        {
                            return i4_error_code;
                        }
                    }

                    ps_cur_au->i4_frame_num = i4_pic_num;

                    return OK;
                }
                default:
                {
                    return ERROR_DBP_MANAGER_T;
                }
            }

            au4_num_mmco_cmds[u4_mmco]++;
        }
    }

    if(!u1_marked_lt && u1_insert_st_pic)
    {
        i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);

        if(i4_error_code != OK)
        {
            return i4_error_code;
        }
    }

    return OK;
}

WORD32 imvcd_dpb_update_default_index_list(mvc_dpb_manager_t *ps_dpb_mgr)
{
    WORD32 i;

    mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;

    for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
    {
        ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
        ps_next_dpb = ps_next_dpb->ps_prev_short;
    }

    ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;

    for(; i < ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
    {
        ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
        ps_next_dpb = ps_next_dpb->ps_prev_long;
    }

    return OK;
}

bool imvcd_dpb_is_diff_poc_valid(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_curr_poc)
{
    WORD32 i;

    mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;

    /* Check in conformance with section 8.2.1 from spec */
    /* Particularly the statement - */
    /* 'The bitstream shall not contain data that result in values of DiffPicOrderCnt(picA, picB)
     * used in the decoding process that exceed the range of -2^15 to 2^15 - 1 inclusive' */
    for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
    {
        if(((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) >= (1 << 15)) ||
           ((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) < -(1 << 15)))
        {
            return false;
        }

        ps_next_dpb = ps_next_dpb->ps_prev_short;
    }

    return true;
}
