Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2  *
      3  * Copyright (C) 2015 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at:
      8  *
      9  * http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  *****************************************************************************
     18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
     19 */
     20 #include "log/log.h"
     21 #include <cutils/log.h>
     22 
     23 #include "ih264_typedefs.h"
     24 #include "ih264_macros.h"
     25 #include "ih264_platform_macros.h"
     26 #include "iv.h"
     27 #include "ih264d_dpb_manager.h"
     28 #include "ih264d_bitstrm.h"
     29 #include "ih264d_parse_cavlc.h"
     30 #include "ih264d_defs.h"
     31 #include "ih264d_structs.h"
     32 #include "ih264d_process_bslice.h"
     33 #include "ih264d_debug.h"
     34 #include "ih264d_tables.h"
     35 #include "ih264d_error_handler.h"
     36 #include "string.h"
     37 #include "ih264d_defs.h"
     38 #include "ih264_error.h"
     39 #include "ih264_buf_mgr.h"
     40 #include "assert.h"
     41 
     42 /*!
     43  ***************************************************************************
     44  * \file ih264d_dpb_mgr.c
     45  *
     46  * \brief
     47  *    Functions for managing the decoded picture buffer
     48  *
     49  * Detailed_description
     50  *
     51  * \date
     52  *    19-12-2002
     53  *
     54  * \author  Sriram Sethuraman
     55  ***************************************************************************
     56  */
     57 
     58 /*!
     59  **************************************************************************
     60  * \if Function name : ih264d_init_ref_bufs \endif
     61  *
     62  * \brief
     63  *    Called at the start for initialization.
     64  *
     65  * \return
     66  *    none
     67  **************************************************************************
     68  */
     69 void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr)
     70 {
     71     UWORD32 i;
     72     struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
     73     for(i = 0; i < MAX_REF_BUFS; i++)
     74     {
     75         ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
     76         ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
     77         ps_dpb_info[i].ps_prev_short = NULL;
     78         ps_dpb_info[i].ps_prev_long = NULL;
     79         ps_dpb_info[i].ps_pic_buf = NULL;
     80         ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
     81         ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
     82         ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
     83         ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
     84 
     85     }
     86     ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
     87     ps_dpb_mgr->ps_dpb_st_head = NULL;
     88     ps_dpb_mgr->ps_dpb_ht_head = NULL;
     89     ps_dpb_mgr->i1_gaps_deleted = 0;
     90     ps_dpb_mgr->i1_poc_buf_id_entries = 0;
     91 
     92     ps_dpb_mgr->u1_num_gaps = 0;
     93     for(i = 0; i < MAX_FRAMES; i++)
     94     {
     95         ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
     96         ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
     97         ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
     98         ps_dpb_mgr->ai4_poc_buf_id_map[i][0] = -1;
     99         ps_dpb_mgr->ai4_poc_buf_id_map[i][1] = 0x7fffffff;
    100         ps_dpb_mgr->ai4_poc_buf_id_map[i][2] = 0;
    101     }
    102 
    103 }
    104 
    105 void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id)
    106 {
    107     dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
    108 
    109     if((pic_buf_id == ps_dec->u1_pic_buf_id) &&
    110                     ps_dec->ps_cur_slice->u1_field_pic_flag &&
    111                     (ps_dec->u1_top_bottom_decoded == 0))
    112     {
    113         return;
    114     }
    115 
    116     ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
    117                           pic_buf_id,
    118                           BUF_MGR_REF);
    119     ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
    120                           ps_dec->au1_pic_buf_id_mv_buf_id_map[pic_buf_id],
    121                           BUF_MGR_REF);
    122 }
    123 /*!
    124  **************************************************************************
    125  * \if Function name : ih264d_delete_lt_node \endif
    126  *
    127  * \brief
    128  *    Delete a buffer with a long term index from the LT linked list
    129  *
    130  * \return
    131  *    none
    132  **************************************************************************
    133  */
    134 WORD32 ih264d_delete_lt_node(dpb_manager_t *ps_dpb_mgr,
    135                              UWORD32 u4_lt_idx,
    136                              UWORD8 u1_fld_pic_flag,
    137                              struct dpb_info_t *ps_lt_node_to_insert,
    138                              WORD32 *pi4_status)
    139 {
    140     *pi4_status = 0;
    141     if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
    142     {
    143         WORD32 i;
    144         struct dpb_info_t *ps_next_dpb;
    145         /* ps_unmark_node points to the node to be removed */
    146         /* from long term list.                            */
    147         struct dpb_info_t *ps_unmark_node;
    148         //Find the node with matching LTIndex
    149         ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
    150         if(ps_next_dpb->u1_lt_idx == u4_lt_idx)
    151         {
    152             ps_unmark_node = ps_next_dpb;
    153         }
    154         else
    155         {
    156             for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
    157             {
    158                 if(ps_next_dpb->ps_prev_long->u1_lt_idx == u4_lt_idx)
    159                     break;
    160                 ps_next_dpb = ps_next_dpb->ps_prev_long;
    161             }
    162             if(i == ps_dpb_mgr->u1_num_lt_ref_bufs)
    163                 *pi4_status = 1;
    164             else
    165                 ps_unmark_node = ps_next_dpb->ps_prev_long;
    166         }
    167 
    168         if(*pi4_status == 0)
    169         {
    170             if(u1_fld_pic_flag)
    171             {
    172                 if(ps_lt_node_to_insert != ps_unmark_node)
    173                 {
    174                     UWORD8 u1_deleted = 0;
    175                     /* for the ps_unmark_node mark the corresponding field */
    176                     /* field as unused for reference                       */
    177 
    178                     if(ps_unmark_node->s_top_field.u1_long_term_frame_idx
    179                                     == u4_lt_idx)
    180                     {
    181                         ps_unmark_node->s_top_field.u1_reference_info =
    182                                         UNUSED_FOR_REF;
    183                         ps_unmark_node->s_top_field.u1_long_term_frame_idx =
    184                         MAX_REF_BUFS + 1;
    185                         u1_deleted = 1;
    186                     }
    187                     if(ps_unmark_node->s_bot_field.u1_long_term_frame_idx
    188                                     == u4_lt_idx)
    189                     {
    190                         ps_unmark_node->s_bot_field.u1_reference_info =
    191                                         UNUSED_FOR_REF;
    192                         ps_unmark_node->s_bot_field.u1_long_term_frame_idx =
    193                         MAX_REF_BUFS + 1;
    194                         u1_deleted = 1;
    195                     }
    196 
    197                     if(!u1_deleted)
    198                     {
    199 
    200                         UWORD32 i4_error_code;
    201                         i4_error_code = ERROR_DBP_MANAGER_T;
    202 
    203                         return i4_error_code;
    204                     }
    205                 }
    206 
    207                 ps_unmark_node->u1_used_as_ref =
    208                                 ps_unmark_node->s_top_field.u1_reference_info
    209                                                 | ps_unmark_node->s_bot_field.u1_reference_info;
    210             }
    211             else
    212                 ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
    213 
    214             if(UNUSED_FOR_REF == ps_unmark_node->u1_used_as_ref)
    215             {
    216                 if(ps_unmark_node == ps_dpb_mgr->ps_dpb_ht_head)
    217                     ps_dpb_mgr->ps_dpb_ht_head = ps_next_dpb->ps_prev_long;
    218 
    219                 ps_unmark_node->u1_lt_idx = MAX_REF_BUFS + 1;
    220                 ps_unmark_node->s_top_field.u1_reference_info =
    221                 UNUSED_FOR_REF;
    222                 ps_unmark_node->s_bot_field.u1_reference_info =
    223                 UNUSED_FOR_REF;
    224                 // Release the physical buffer
    225                 ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
    226                                             ps_unmark_node->u1_buf_id);
    227                 ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long; //update link
    228                 ps_unmark_node->ps_prev_long = NULL;
    229                 ps_dpb_mgr->u1_num_lt_ref_bufs--; //decrement LT buf count
    230             }
    231         }
    232     }
    233     return OK;
    234 }
    235 
    236 /*!
    237  **************************************************************************
    238  * \if Function name : ih264d_insert_lt_node \endif
    239  *
    240  * \brief
    241  *    Insert a buffer into the LT linked list at a given LT index
    242  *
    243  * \return
    244  *    none
    245  **************************************************************************
    246  */
    247 WORD32 ih264d_insert_lt_node(dpb_manager_t *ps_dpb_mgr,
    248                            struct dpb_info_t *ps_mov_node,
    249                            UWORD32 u4_lt_idx,
    250                            UWORD8 u1_fld_pic_flag)
    251 {
    252     UWORD8 u1_mark_top_field_long_term = 0;
    253     UWORD8 u1_mark_bot_field_long_term = 0;
    254 
    255     {
    256         if(u1_fld_pic_flag)
    257         {
    258             /* Assign corresponding field (top or bottom) long_term_frame_idx */
    259 
    260             if((ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
    261                             && (ps_mov_node->s_bot_field.u1_reference_info
    262                                             == IS_LONG_TERM))
    263             {
    264                 if(ps_mov_node->u1_lt_idx == u4_lt_idx)
    265                     u1_mark_bot_field_long_term = 1;
    266                 else
    267                 {
    268 
    269                     UWORD32 i4_error_code;
    270                     i4_error_code = ERROR_DBP_MANAGER_T;
    271 
    272                     return i4_error_code;
    273 
    274                 }
    275             }
    276             else if(ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM)
    277             {
    278                 u1_mark_top_field_long_term = 1;
    279             }
    280 
    281             if(!(u1_mark_top_field_long_term || u1_mark_bot_field_long_term))
    282             {
    283                 UWORD32 i4_error_code;
    284                 i4_error_code = ERROR_DBP_MANAGER_T;
    285                 return i4_error_code;
    286             }
    287         }
    288         else
    289         {
    290             ps_mov_node->s_top_field.u1_reference_info = IS_LONG_TERM;
    291             ps_mov_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
    292             ps_mov_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
    293             ps_mov_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
    294         }
    295 
    296         ps_mov_node->u1_lt_idx = u4_lt_idx; //Assign the LT index to the node
    297         ps_mov_node->ps_pic_buf->u1_long_term_frm_idx = u4_lt_idx;
    298         ps_mov_node->u1_used_as_ref = IS_LONG_TERM;
    299 
    300         /* Insert the new long term in the LT list with  u4_lt_idx    */
    301         /* in ascending order.                                         */
    302         if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
    303         {
    304             struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
    305             if(u4_lt_idx < ps_next_dpb->u1_lt_idx)
    306             {
    307                 //LTIndex to be inserted is the smallest LT index
    308                 //Update head and point prev to the next higher index
    309                 ps_mov_node->ps_prev_long = ps_next_dpb;
    310                 ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
    311             }
    312             else
    313             {
    314                 WORD32 i;
    315                 struct dpb_info_t *ps_nxtDPB = ps_next_dpb;
    316                 ps_next_dpb = ps_next_dpb->ps_prev_long;
    317                 for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
    318                 {
    319                     if(ps_next_dpb->u1_lt_idx > u4_lt_idx)
    320                         break;
    321                     ps_nxtDPB = ps_next_dpb;
    322                     ps_next_dpb = ps_next_dpb->ps_prev_long;
    323                 }
    324 
    325                 ps_nxtDPB->ps_prev_long = ps_mov_node;
    326                 ps_mov_node->ps_prev_long = ps_next_dpb;
    327             }
    328         }
    329         else
    330         {
    331             ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node;
    332             ps_mov_node->ps_prev_long = NULL;
    333         }
    334         /* Identify the picture buffer as a long term picture buffer */
    335         ps_mov_node->ps_pic_buf->u1_is_short = 0;
    336 
    337         /* Increment LT buf count only if new LT node inserted    */
    338         /* If Increment during top_field is done, don't increment */
    339         /* for bottom field, as both them are part of same pic.   */
    340         if(!u1_mark_bot_field_long_term)
    341             ps_dpb_mgr->u1_num_lt_ref_bufs++;
    342 
    343     }
    344     return OK;
    345 }
    346 
    347 /*!
    348  **************************************************************************
    349  * \if Function name : ih264d_insert_st_node \endif
    350  *
    351  * \brief
    352  *    Adds a short term reference picture into the ST linked list
    353  *
    354  * \return
    355  *    None
    356  *
    357  * \note
    358  *    Called only for a new coded picture with nal_ref_idc!=0
    359  **************************************************************************
    360  */
    361 WORD32 ih264d_insert_st_node(dpb_manager_t *ps_dpb_mgr,
    362                           struct pic_buffer_t *ps_pic_buf,
    363                           UWORD8 u1_buf_id,
    364                           UWORD32 u4_cur_pic_num)
    365 {
    366     WORD32 i;
    367     struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
    368     UWORD8 u1_picture_type = ps_pic_buf->u1_picturetype;
    369     /* Find an unused dpb location */
    370     for(i = 0; i < MAX_REF_BUFS; i++)
    371     {
    372         if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf)
    373                         && ps_dpb_info[i].u1_used_as_ref)
    374         {
    375             /* Can occur only for field bottom pictures */
    376             ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
    377 
    378             /*signal an error in the case of frame pic*/
    379             if(ps_dpb_info[i].ps_pic_buf->u1_pic_type == FRM_PIC)
    380             {
    381                 return ERROR_DBP_MANAGER_T;
    382             }
    383             else
    384             {
    385                 return OK;
    386             }
    387         }
    388 
    389         if((ps_dpb_info[i].u1_used_as_ref == UNUSED_FOR_REF)
    390                         && (ps_dpb_info[i].s_top_field.u1_reference_info
    391                                         == UNUSED_FOR_REF)
    392                         && (ps_dpb_info[i].s_bot_field.u1_reference_info
    393                                         == UNUSED_FOR_REF))
    394             break;
    395     }
    396     if(i == MAX_REF_BUFS)
    397     {
    398         UWORD32 i4_error_code;
    399         i4_error_code = ERROR_DBP_MANAGER_T;
    400         return i4_error_code;
    401     }
    402 
    403     /* Create dpb info */
    404     ps_dpb_info[i].ps_pic_buf = ps_pic_buf;
    405     ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
    406     ps_dpb_info[i].u1_buf_id = u1_buf_id;
    407     ps_dpb_info[i].u1_used_as_ref = TRUE;
    408     ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
    409     ps_dpb_info[i].i4_frame_num = u4_cur_pic_num;
    410     ps_dpb_info[i].ps_pic_buf->i4_frame_num = u4_cur_pic_num;
    411 
    412     /* update the head node of linked list to point to the cur Pic */
    413     ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;
    414 
    415     // Increment Short term bufCount
    416     ps_dpb_mgr->u1_num_st_ref_bufs++;
    417     /* Identify the picture as a short term picture buffer */
    418     ps_pic_buf->u1_is_short = IS_SHORT_TERM;
    419 
    420     if((u1_picture_type & 0x03) == FRM_PIC)
    421     {
    422         ps_dpb_info[i].u1_used_as_ref = IS_SHORT_TERM;
    423         ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
    424         ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
    425     }
    426 
    427     if((u1_picture_type & 0x03) == TOP_FLD)
    428         ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
    429 
    430     if((u1_picture_type & 0x03) == BOT_FLD)
    431         ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
    432 
    433     return OK;
    434 }
    435 
    436 /*!
    437  **************************************************************************
    438  * \if Function name : ih264d_delete_st_node_or_make_lt \endif
    439  *
    440  * \brief
    441  *    Delete short term ref with a given picNum from the ST linked list or
    442  *     make it an LT node
    443  *
    444  * \return
    445  *    0 - if successful; -1 - otherwise
    446  *
    447  * \note
    448  *    Common parts to MMCO==1 and MMCO==3 have been combined here
    449  **************************************************************************
    450  */
    451 WORD32 ih264d_delete_st_node_or_make_lt(dpb_manager_t *ps_dpb_mgr,
    452                                       WORD32 i4_pic_num,
    453                                       UWORD32 u4_lt_idx,
    454                                       UWORD8 u1_fld_pic_flag)
    455 {
    456     WORD32 i;
    457     struct dpb_info_t *ps_next_dpb;
    458     WORD32 i4_frame_num = i4_pic_num;
    459     struct dpb_info_t *ps_unmark_node = NULL;
    460     UWORD8 u1_del_node = 0, u1_del_st = 0;
    461     UWORD8 u1_reference_type = UNUSED_FOR_REF;
    462     WORD32 ret;
    463 
    464     if(u1_fld_pic_flag)
    465     {
    466         i4_frame_num = i4_frame_num >> 1;
    467 
    468         if(u4_lt_idx == (MAX_REF_BUFS + 1))
    469             u1_reference_type = UNUSED_FOR_REF;
    470         else
    471             u1_reference_type = IS_LONG_TERM;
    472     }
    473 
    474     //Find the node with matching picNum
    475     ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
    476     if((WORD32)ps_next_dpb->i4_frame_num == i4_frame_num)
    477     {
    478         ps_unmark_node = ps_next_dpb;
    479     }
    480     else
    481     {
    482         for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
    483         {
    484             if((WORD32)ps_next_dpb->ps_prev_short->i4_frame_num == i4_frame_num)
    485                 break;
    486             ps_next_dpb = ps_next_dpb->ps_prev_short;
    487         }
    488 
    489         if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
    490         {
    491             if(ps_dpb_mgr->u1_num_gaps)
    492             {
    493                 ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_frame_num, &u1_del_st);
    494                 if(ret != OK)
    495                     return ret;
    496             }
    497             else
    498             {
    499                 UWORD32 i4_error_code;
    500                 i4_error_code = ERROR_DBP_MANAGER_T;
    501 
    502                 return i4_error_code;
    503             }
    504 
    505             if(u1_del_st)
    506             {
    507                 UWORD32 i4_error_code;
    508                 i4_error_code = ERROR_DBP_MANAGER_T;
    509                 return i4_error_code;
    510             }
    511             else
    512             {
    513                 return 0;
    514             }
    515         }
    516         else
    517             ps_unmark_node = ps_next_dpb->ps_prev_short;
    518     }
    519 
    520     if(u1_fld_pic_flag)
    521     {
    522         /* Mark the corresponding field ( top or bot) as  */
    523         /* UNUSED_FOR_REF or IS_LONG_TERM depending on    */
    524         /* u1_reference_type.                             */
    525         if(ps_unmark_node->s_top_field.i4_pic_num == i4_pic_num)
    526         {
    527             ps_unmark_node->s_top_field.u1_reference_info = u1_reference_type;
    528             ps_unmark_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
    529             {
    530                 UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
    531                 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
    532                                 * ps_dpb_mgr->u2_pic_ht) >> 5);
    533                 /* memset the colocated zero u4_flag buffer */
    534                 memset(pu1_src, 0, i4_size);
    535             }
    536         }
    537 
    538         else if(ps_unmark_node->s_bot_field.i4_pic_num == i4_pic_num)
    539         {
    540 
    541             ps_unmark_node->s_bot_field.u1_reference_info = u1_reference_type;
    542             ps_unmark_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
    543             {
    544                 UWORD8 *pu1_src =
    545                                 ps_unmark_node->ps_pic_buf->pu1_col_zero_flag
    546                                                 + ((ps_dpb_mgr->u2_pic_wd
    547                                                                 * ps_dpb_mgr->u2_pic_ht)
    548                                                                 >> 5);
    549                 WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
    550                                 * ps_dpb_mgr->u2_pic_ht) >> 5);
    551                 /* memset the colocated zero u4_flag buffer */
    552                 memset(pu1_src, 0, i4_size);
    553             }
    554         }
    555         ps_unmark_node->u1_used_as_ref =
    556                         ps_unmark_node->s_top_field.u1_reference_info
    557                                         | ps_unmark_node->s_bot_field.u1_reference_info;
    558     }
    559     else
    560     {
    561         ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF;
    562         ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
    563         ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
    564 
    565         {
    566             UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag;
    567 
    568             WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd
    569                             * ps_dpb_mgr->u2_pic_ht) >> 4);
    570             /* memset the colocated zero u4_flag buffer */
    571             memset(pu1_src, 0, i4_size);
    572         }
    573     }
    574 
    575     if(!(ps_unmark_node->u1_used_as_ref & IS_SHORT_TERM))
    576     {
    577         if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
    578             ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
    579         else
    580             ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short; //update link
    581         ps_dpb_mgr->u1_num_st_ref_bufs--; //decrement ST buf count
    582         u1_del_node = 1;
    583     }
    584 
    585     if(u4_lt_idx == MAX_REF_BUFS + 1)
    586     {
    587         if(u1_del_node)
    588         {
    589             // Release the physical buffer
    590             ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
    591                                         ps_unmark_node->u1_buf_id);
    592             ps_unmark_node->ps_prev_short = NULL;
    593         }
    594     }
    595     else
    596     {
    597         WORD32 i4_status;
    598         //If another node has the same LT index, delete that node
    599         ret = ih264d_delete_lt_node(ps_dpb_mgr, u4_lt_idx,
    600                               u1_fld_pic_flag, ps_unmark_node, &i4_status);
    601         if(ret != OK)
    602             return ret;
    603         // Now insert the short term node as a long term node
    604         ret = ih264d_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx,
    605                               u1_fld_pic_flag);
    606         if(ret != OK)
    607             return ret;
    608     }
    609     return OK;
    610 }
    611 /*!
    612  **************************************************************************
    613  * \if Function name : ih264d_reset_ref_bufs \endif
    614  *
    615  * \brief
    616  *    Called if MMCO==5/7 or on the first slice of an IDR picture
    617  *
    618  * \return
    619  *    none
    620  **************************************************************************
    621  */
    622 void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr)
    623 {
    624     WORD32 i;
    625     struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
    626 
    627     for(i = 0; i < MAX_REF_BUFS; i++)
    628     {
    629         if(ps_dpb_info[i].u1_used_as_ref)
    630         {
    631             ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF;
    632             ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1;
    633             ps_dpb_info[i].ps_prev_short = NULL;
    634             ps_dpb_info[i].ps_prev_long = NULL;
    635             ps_dpb_info[i].ps_pic_buf = NULL;
    636             ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
    637             ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
    638             ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
    639             ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1;
    640 
    641             //Release physical buffer
    642             ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
    643                                         ps_dpb_info[i].u1_buf_id);
    644         }
    645     }
    646     ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
    647     ps_dpb_mgr->ps_dpb_st_head = NULL;
    648     ps_dpb_mgr->ps_dpb_ht_head = NULL;
    649 
    650     /* release all gaps */
    651     ps_dpb_mgr->u1_num_gaps = 0;
    652     for(i = 0; i < MAX_FRAMES; i++)
    653     {
    654         ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
    655         ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
    656         ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
    657     }
    658 }
    659 
    660 /*!
    661  **************************************************************************
    662  * \if Function name : Name \endif
    663  *
    664  * \brief
    665  *     create the default index list after an MMCO
    666  *
    667  * \return
    668  *    0 - if no_error; -1 - error
    669  *
    670  **************************************************************************
    671  */
    672 WORD32 ih264d_update_default_index_list(dpb_manager_t *ps_dpb_mgr)
    673 {
    674     WORD32 i;
    675     struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
    676 
    677     for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
    678     {
    679         ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
    680         ps_next_dpb = ps_next_dpb->ps_prev_short;
    681     }
    682 
    683     ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
    684     for(;i< ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
    685     {
    686         ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf;
    687         ps_next_dpb = ps_next_dpb->ps_prev_long;
    688     }
    689     return 0;
    690 }
    691 
    692 /*!
    693  **************************************************************************
    694  * \if Function name : ref_idx_reordering \endif
    695  *
    696  * \brief
    697  *     Parse the bitstream and reorder indices for the current slice
    698  *
    699  * \return
    700  *    0 - if no_error; -1 - error
    701  *
    702  * \note
    703  *    Called only if ref_idx_reordering_flag_l0 is decoded as 1
    704  *    Remove error checking for unmatching picNum or LTIndex later (if not needed)
    705  * \para
    706  *    This section implements 7.3.3.1 and 8.2.6.4
    707  *    Uses the default index list as the starting point and
    708  *    remaps the picNums sent to the next higher index in the
    709  *    modified list. The unmodified ones are copied from the
    710  *    default to modified list retaining their order in the default list.
    711  *
    712  **************************************************************************
    713  */
    714 WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx)
    715 {
    716     dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr;
    717     UWORD16 u4_cur_pic_num = ps_dec->ps_cur_slice->u2_frame_num;
    718     /*< Maximum Picture Number Minus 1 */
    719     UWORD16 ui_max_frame_num =
    720                     ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1;
    721 
    722     WORD32 i;
    723     UWORD32 ui_remapIdc, ui_nextUev;
    724     WORD16 u2_pred_frame_num = u4_cur_pic_num;
    725     WORD32 i_temp;
    726     UWORD16 u2_def_mod_flag = 0; /* Flag to keep track of which indices have been remapped */
    727     UWORD8 modCount = 0;
    728     UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
    729     UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
    730     dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
    731     UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
    732 
    733     if(u1_field_pic_flag)
    734     {
    735         u4_cur_pic_num = u4_cur_pic_num * 2 + 1;
    736         ui_max_frame_num = ui_max_frame_num * 2;
    737     }
    738 
    739     u2_pred_frame_num = u4_cur_pic_num;
    740 
    741     ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
    742 
    743     while(ui_remapIdc != 3)
    744     {
    745         ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
    746         if(ui_remapIdc != 2)
    747         {
    748             ui_nextUev = ui_nextUev + 1;
    749             if(ui_remapIdc == 0)
    750             {
    751                 // diffPicNum is -ve
    752                 i_temp = u2_pred_frame_num - ui_nextUev;
    753                 if(i_temp < 0)
    754                     i_temp += ui_max_frame_num;
    755             }
    756             else
    757             {
    758                 // diffPicNum is +ve
    759                 i_temp = u2_pred_frame_num + ui_nextUev;
    760                 if(i_temp >= ui_max_frame_num)
    761                     i_temp -= ui_max_frame_num;
    762             }
    763             /* Find the dpb with the matching picNum (picNum==frameNum for framePic) */
    764 
    765             if(i_temp > u4_cur_pic_num)
    766                 i_temp = i_temp - ui_max_frame_num;
    767 
    768             for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
    769             {
    770                 if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->i4_pic_num == i_temp)
    771                     break;
    772             }
    773             if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
    774             {
    775                 UWORD32 i4_error_code;
    776                 i4_error_code = ERROR_DBP_MANAGER_T;
    777                 return i4_error_code;
    778             }
    779 
    780             u2_def_mod_flag |= (1 << i);
    781             ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
    782                             ps_dpb_mgr->ps_init_dpb[uc_lx][i];
    783             u2_pred_frame_num = i_temp; //update predictor to be the picNum just obtained
    784         }
    785         else //2
    786         {
    787             UWORD8 u1_lt_idx = (UWORD8)ui_nextUev;
    788 
    789             for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++)
    790             {
    791                 if(!ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_is_short)
    792                 {
    793                     if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_long_term_pic_num
    794                                     == u1_lt_idx)
    795                         break;
    796                 }
    797             }
    798             if(i == (ps_cur_slice->u1_initial_list_size[uc_lx]))
    799             {
    800                 UWORD32 i4_error_code;
    801                 i4_error_code = ERROR_DBP_MANAGER_T;
    802                 return i4_error_code;
    803             }
    804 
    805             u2_def_mod_flag |= (1 << i);
    806             ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
    807                             ps_dpb_mgr->ps_init_dpb[uc_lx][i];
    808         }
    809 
    810         ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
    811         /* Get the remapping_idc - 0/1/2/3 */
    812     }
    813 
    814     //Handle the ref indices that were not remapped
    815     for(i = 0; i < (ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]); i++)
    816     {
    817         if(!(u2_def_mod_flag & (1 << i)))
    818             ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] =
    819                             ps_dpb_mgr->ps_init_dpb[uc_lx][i];
    820     }
    821     return OK;
    822 }
    823 /*!
    824  **************************************************************************
    825  * \if Function name : ih264d_read_mmco_commands \endif
    826  *
    827  * \brief
    828  *    Parses MMCO commands and stores them in a structure for later use.
    829  *
    830  * \return
    831  *    0 - No error; -1 - Error
    832  *
    833  * \note
    834  *    This function stores MMCO commands in structure only for the first time.
    835  *    In case of MMCO commands being issued for same Picture Number, they are
    836  *    just parsed and not stored them in the structure.
    837  *
    838  **************************************************************************
    839  */
    840 WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
    841 {
    842     dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
    843     dpb_commands_t *ps_dpb_cmds = ps_dec->ps_dpb_cmds;
    844     dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice;
    845     WORD32 j;
    846     UWORD8 u1_buf_mode;
    847     struct MMCParams *ps_mmc_params;
    848     UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
    849     UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
    850     UWORD32 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst;
    851 
    852     ps_slice->u1_mmco_equalto5 = 0;
    853     {
    854         if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL)
    855         {
    856             ps_slice->u1_no_output_of_prior_pics_flag =
    857                             ih264d_get_bit_h264(ps_bitstrm);
    858             COPYTHECONTEXT("SH: no_output_of_prior_pics_flag",
    859                             ps_slice->u1_no_output_of_prior_pics_flag);
    860             ps_slice->u1_long_term_reference_flag = ih264d_get_bit_h264(
    861                             ps_bitstrm);
    862             COPYTHECONTEXT("SH: long_term_reference_flag",
    863                             ps_slice->u1_long_term_reference_flag);
    864             ps_dpb_cmds->u1_idr_pic = 1;
    865             ps_dpb_cmds->u1_no_output_of_prior_pics_flag =
    866                             ps_slice->u1_no_output_of_prior_pics_flag;
    867             ps_dpb_cmds->u1_long_term_reference_flag =
    868                             ps_slice->u1_long_term_reference_flag;
    869         }
    870         else
    871         {
    872             u1_buf_mode = ih264d_get_bit_h264(ps_bitstrm); //0 - sliding window; 1 - arbitrary
    873             COPYTHECONTEXT("SH: adaptive_ref_pic_buffering_flag", u1_buf_mode);
    874             ps_dpb_cmds->u1_buf_mode = u1_buf_mode;
    875             j = 0;
    876 
    877             if(u1_buf_mode == 1)
    878             {
    879                 UWORD32 u4_mmco;
    880                 UWORD32 u4_diff_pic_num;
    881                 UWORD32 u4_lt_idx, u4_max_lt_idx;
    882 
    883                 u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
    884                                      pu4_bitstrm_buf);
    885                 while(u4_mmco != END_OF_MMCO)
    886                 {
    887                     if (j >= MAX_REF_BUFS)
    888                     {
    889                         ALOGE("b/25818142");
    890                         android_errorWriteLog(0x534e4554, "25818142");
    891                         ps_dpb_cmds->u1_num_of_commands = 0;
    892                         return -1;
    893                     }
    894                     ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
    895                     ps_mmc_params->u4_mmco = u4_mmco;
    896                     switch(u4_mmco)
    897                     {
    898                         case MARK_ST_PICNUM_AS_NONREF:
    899                             u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
    900                                                          pu4_bitstrm_buf);
    901                             //Get absDiffPicnumMinus1
    902                             ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
    903                             break;
    904 
    905                         case MARK_LT_INDEX_AS_NONREF:
    906                             u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
    907                                                    pu4_bitstrm_buf);
    908                             ps_mmc_params->u4_lt_idx = u4_lt_idx;
    909                             break;
    910 
    911                         case MARK_ST_PICNUM_AS_LT_INDEX:
    912                             u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst,
    913                                                          pu4_bitstrm_buf);
    914                             ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num;
    915                             u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
    916                                                    pu4_bitstrm_buf);
    917                             ps_mmc_params->u4_lt_idx = u4_lt_idx;
    918                             break;
    919 
    920                         case SET_MAX_LT_INDEX:
    921                         {
    922                             u4_max_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
    923                                                        pu4_bitstrm_buf);
    924                             ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx;
    925                             break;
    926                         }
    927                         case RESET_REF_PICTURES:
    928                         {
    929                             ps_slice->u1_mmco_equalto5 = 1;
    930                             break;
    931                         }
    932 
    933                         case SET_LT_INDEX:
    934                             u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
    935                                                    pu4_bitstrm_buf);
    936                             ps_mmc_params->u4_lt_idx = u4_lt_idx;
    937                             break;
    938 
    939                         default:
    940                             break;
    941                     }
    942                     u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
    943                                          pu4_bitstrm_buf);
    944 
    945                     j++;
    946                 }
    947                 ps_dpb_cmds->u1_num_of_commands = j;
    948 
    949             }
    950         }
    951         ps_dpb_cmds->u1_dpb_commands_read = 1;
    952         ps_dpb_cmds->u1_dpb_commands_read_slc = 1;
    953 
    954     }
    955     u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst - u4_bit_ofst;
    956     return u4_bit_ofst;
    957 }
    958 
    959 /*!
    960  **************************************************************************
    961  * \if Function name : ih264d_do_mmco_buffer \endif
    962  *
    963  * \brief
    964  *    Perform decoded picture buffer memory management control operations
    965  *
    966  * \return
    967  *    0 - No error; -1 - Error
    968  *
    969  * \note
    970  *    Bitstream is also parsed here to get the MMCOs
    971  *
    972  **************************************************************************
    973  */
    974 WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds,
    975                           dpb_manager_t *ps_dpb_mgr,
    976                           UWORD8 u1_numRef_frames_for_seq, /*!< num_ref_frames from active SeqParSet*/
    977                           UWORD32 u4_cur_pic_num,
    978                           UWORD32 u2_u4_max_pic_num_minus1,
    979                           UWORD8 u1_nal_unit_type,
    980                           struct pic_buffer_t *ps_pic_buf,
    981                           UWORD8 u1_buf_id,
    982                           UWORD8 u1_fld_pic_flag,
    983                           UWORD8 u1_curr_pic_in_err)
    984 {
    985     WORD32 i;
    986     UWORD8 u1_buf_mode, u1_marked_lt;
    987     struct dpb_info_t *ps_next_dpb;
    988     UWORD8 u1_num_gaps;
    989     UWORD8 u1_del_node = 1;
    990     UWORD8 u1_insert_st_pic = 1;
    991     WORD32 ret;
    992     UNUSED(u1_nal_unit_type);
    993     UNUSED(u2_u4_max_pic_num_minus1);
    994     u1_buf_mode = ps_dpb_cmds->u1_buf_mode; //0 - sliding window; 1 - Adaptive
    995     u1_marked_lt = 0;
    996     u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
    997 
    998     if(!u1_buf_mode)
    999     {
   1000         //Sliding window - implements 8.2.5.3
   1001         if((ps_dpb_mgr->u1_num_st_ref_bufs
   1002                         + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps)
   1003                         == u1_numRef_frames_for_seq)
   1004         {
   1005             UWORD8 u1_new_node_flag = 1;
   1006             if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
   1007             {
   1008                 UWORD32 i4_error_code;
   1009                 i4_error_code = ERROR_DBP_MANAGER_T;
   1010                 return i4_error_code;
   1011             }
   1012 
   1013             // Chase the links to reach the last but one picNum, if available
   1014             ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
   1015 
   1016             if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
   1017             {
   1018                 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
   1019                 {
   1020                     /* Incase of  filed pictures top_field has been allocated   */
   1021                     /* picture buffer and complementary bottom field pair comes */
   1022                     /* then the sliding window mechanism should not allocate a  */
   1023                     /* new node                                                 */
   1024                     u1_new_node_flag = 0;
   1025                 }
   1026 
   1027                 for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
   1028                 {
   1029                     if(ps_next_dpb == NULL)
   1030                     {
   1031                         UWORD32 i4_error_code;
   1032                         i4_error_code = ERROR_DBP_MANAGER_T;
   1033                         return i4_error_code;
   1034                     }
   1035                     if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
   1036                     {
   1037                         /* Incase of  field pictures top_field has been allocated   */
   1038                         /* picture buffer and complementary bottom field pair comes */
   1039                         /* then the sliding window mechanism should not allocate a  */
   1040                         /* new node                                                 */
   1041                         u1_new_node_flag = 0;
   1042                     }
   1043                     ps_next_dpb = ps_next_dpb->ps_prev_short;
   1044                 }
   1045 
   1046                 if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
   1047                 {
   1048                     UWORD32 i4_error_code;
   1049                     i4_error_code = ERROR_DBP_MANAGER_T;
   1050                     return i4_error_code;
   1051                 }
   1052 
   1053                 if(u1_new_node_flag)
   1054                 {
   1055                     if(u1_num_gaps)
   1056                     {
   1057                         ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1058                                                             ps_next_dpb->ps_prev_short->i4_frame_num,
   1059                                                             &u1_del_node);
   1060                         if(ret != OK)
   1061                             return ret;
   1062                     }
   1063 
   1064                     if(u1_del_node)
   1065                     {
   1066                         ps_dpb_mgr->u1_num_st_ref_bufs--;
   1067                         ps_next_dpb->ps_prev_short->u1_used_as_ref =
   1068                                         UNUSED_FOR_REF;
   1069                         ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
   1070                                         UNUSED_FOR_REF;
   1071                         ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
   1072                                         UNUSED_FOR_REF;
   1073                         ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1074                                                     ps_next_dpb->ps_prev_short->u1_buf_id);
   1075                         ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
   1076                         ps_next_dpb->ps_prev_short = NULL;
   1077                     }
   1078                 }
   1079             }
   1080             else
   1081             {
   1082                 if(ps_dpb_mgr->u1_num_st_ref_bufs)
   1083                 {
   1084                     ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1085                                                        ps_next_dpb->i4_frame_num,
   1086                                                        &u1_del_node);
   1087                     if(ret != OK)
   1088                         return ret;
   1089                     if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
   1090                                     && u1_del_node)
   1091                     {
   1092                         ps_dpb_mgr->u1_num_st_ref_bufs--;
   1093                         ps_next_dpb->u1_used_as_ref = FALSE;
   1094                         ps_next_dpb->s_top_field.u1_reference_info =
   1095                                         UNUSED_FOR_REF;
   1096                         ps_next_dpb->s_bot_field.u1_reference_info =
   1097                                         UNUSED_FOR_REF;
   1098                         ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1099                                                     ps_next_dpb->u1_buf_id);
   1100                         ps_next_dpb->ps_pic_buf = NULL;
   1101                         ps_next_dpb->ps_prev_short = NULL;
   1102                         ps_dpb_mgr->ps_dpb_st_head = NULL;
   1103                         ps_next_dpb = NULL;
   1104                     }
   1105                     else if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
   1106                     {
   1107                         if(u1_curr_pic_in_err)
   1108                         {
   1109                             u1_insert_st_pic = 0;
   1110                         }
   1111                         else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
   1112                         {
   1113                             ps_dpb_mgr->u1_num_st_ref_bufs--;
   1114                             ps_next_dpb->u1_used_as_ref = FALSE;
   1115                             ps_next_dpb->s_top_field.u1_reference_info =
   1116                                             UNUSED_FOR_REF;
   1117                             ps_next_dpb->s_bot_field.u1_reference_info =
   1118                                             UNUSED_FOR_REF;
   1119                             ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1120                                                         ps_next_dpb->u1_buf_id);
   1121                             ps_next_dpb->ps_pic_buf = NULL;
   1122                             ps_next_dpb = NULL;
   1123                         }
   1124                     }
   1125                 }
   1126                 else
   1127                 {
   1128                     ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1129                                                         INVALID_FRAME_NUM,
   1130                                                         &u1_del_node);
   1131                     if(ret != OK)
   1132                         return ret;
   1133                     if(u1_del_node)
   1134                     {
   1135                         UWORD32 i4_error_code;
   1136                         i4_error_code = ERROR_DBP_MANAGER_T;
   1137                         return i4_error_code;
   1138                     }
   1139                 }
   1140             }
   1141         }
   1142     }
   1143     else
   1144     {
   1145         //Adaptive memory control - implements 8.2.5.4
   1146         UWORD32 u4_mmco;
   1147         UWORD32 u4_diff_pic_num;
   1148         WORD32 i4_pic_num;
   1149         UWORD32 u4_lt_idx;
   1150         WORD32 j;
   1151         struct MMCParams *ps_mmc_params;
   1152 
   1153         for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
   1154         {
   1155             ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
   1156             u4_mmco = ps_mmc_params->u4_mmco; //Get MMCO
   1157 
   1158             switch(u4_mmco)
   1159             {
   1160                 case MARK_ST_PICNUM_AS_NONREF:
   1161                 {
   1162 
   1163                     {
   1164                         UWORD32 i4_cur_pic_num = u4_cur_pic_num;
   1165                         u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
   1166                         if(u1_fld_pic_flag)
   1167                             i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
   1168                         i4_pic_num = i4_cur_pic_num - (u4_diff_pic_num + 1);
   1169                     }
   1170 
   1171                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
   1172                     {
   1173                         ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
   1174                                                                i4_pic_num,
   1175                                                                MAX_REF_BUFS + 1,
   1176                                                                u1_fld_pic_flag);
   1177                         if(ret != OK)
   1178                             return ret;
   1179                     }
   1180                     else
   1181                     {
   1182                         UWORD8 u1_dummy;
   1183                         ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_dummy);
   1184                         if(ret != OK)
   1185                             return ret;
   1186                     }
   1187                     break;
   1188                 }
   1189                 case MARK_LT_INDEX_AS_NONREF:
   1190                 {
   1191                     WORD32 i4_status;
   1192                     u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
   1193                     ret = ih264d_delete_lt_node(ps_dpb_mgr,
   1194                                                 u4_lt_idx,
   1195                                                 u1_fld_pic_flag,
   1196                                                 0, &i4_status);
   1197                     if(ret != OK)
   1198                         return ret;
   1199                     if(i4_status)
   1200                     {
   1201                         UWORD32 i4_error_code;
   1202                         i4_error_code = ERROR_DBP_MANAGER_T;
   1203                         return i4_error_code;
   1204                     }
   1205                     break;
   1206                 }
   1207 
   1208                 case MARK_ST_PICNUM_AS_LT_INDEX:
   1209                 {
   1210                     {
   1211                         UWORD32 i4_cur_pic_num = u4_cur_pic_num;
   1212                         u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1
   1213                         if(u1_fld_pic_flag)
   1214                             i4_cur_pic_num = i4_cur_pic_num * 2 + 1;
   1215 
   1216                         i4_pic_num = i4_cur_pic_num - (u4_diff_pic_num + 1);
   1217                     }
   1218 
   1219                     u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
   1220                     if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
   1221                     {
   1222                         ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
   1223                                                                i4_pic_num, u4_lt_idx,
   1224                                                                u1_fld_pic_flag);
   1225                         if(ret != OK)
   1226                             return ret;
   1227                     }
   1228                     break;
   1229                 }
   1230                 case SET_MAX_LT_INDEX:
   1231                 {
   1232                     UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs;
   1233                     u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1
   1234                     if(u4_lt_idx < ps_dpb_mgr->u1_max_lt_pic_idx_plus1
   1235                                     && uc_numLT > 0)
   1236                     {
   1237                         struct dpb_info_t *ps_nxtDPB;
   1238                         //Set all LT buffers with index >= u4_lt_idx to nonreference
   1239                         ps_nxtDPB = ps_dpb_mgr->ps_dpb_ht_head;
   1240                         ps_next_dpb = ps_nxtDPB->ps_prev_long;
   1241                         if(ps_nxtDPB->u1_lt_idx >= u4_lt_idx)
   1242                         {
   1243                             i = 0;
   1244                             ps_dpb_mgr->ps_dpb_ht_head = NULL;
   1245                         }
   1246                         else
   1247                         {
   1248                             for(i = 1; i < uc_numLT; i++)
   1249                             {
   1250                                 if(ps_next_dpb->u1_lt_idx >= u4_lt_idx)
   1251                                     break;
   1252                                 ps_nxtDPB = ps_next_dpb;
   1253                                 ps_next_dpb = ps_next_dpb->ps_prev_long;
   1254                             }
   1255                             ps_nxtDPB->ps_prev_long = NULL; //Terminate the link of the closest LTIndex that is <=Max
   1256                         }
   1257                         ps_dpb_mgr->u1_num_lt_ref_bufs = i;
   1258                         if(i == 0)
   1259                             ps_next_dpb = ps_nxtDPB;
   1260 
   1261                         for(; i < uc_numLT; i++)
   1262                         {
   1263                             ps_nxtDPB = ps_next_dpb;
   1264                             ps_nxtDPB->u1_lt_idx = MAX_REF_BUFS + 1;
   1265                             ps_nxtDPB->u1_used_as_ref = UNUSED_FOR_REF;
   1266                             ps_nxtDPB->s_top_field.u1_reference_info =
   1267                                             UNUSED_FOR_REF;
   1268                             ps_nxtDPB->s_bot_field.u1_reference_info =
   1269                                             UNUSED_FOR_REF;
   1270 
   1271                             ps_nxtDPB->ps_pic_buf = NULL;
   1272                             //Release buffer
   1273                             ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1274                                                         ps_nxtDPB->u1_buf_id);
   1275                             ps_next_dpb = ps_nxtDPB->ps_prev_long;
   1276                             ps_nxtDPB->ps_prev_long = NULL;
   1277                         }
   1278                     }
   1279                     ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = u4_lt_idx;
   1280 
   1281                     break;
   1282                 }
   1283                 case SET_LT_INDEX:
   1284                 {
   1285                     u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
   1286                     ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
   1287                                           u4_cur_pic_num);
   1288                     if(ret != OK)
   1289                         return ret;
   1290                     ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
   1291                                                      u4_cur_pic_num, u4_lt_idx,
   1292                                                      u1_fld_pic_flag);
   1293                     if(ret != OK)
   1294                         return ret;
   1295                     u1_marked_lt = 1;
   1296                     break;
   1297                 }
   1298 
   1299                 default:
   1300                     break;
   1301             }
   1302             if(u4_mmco == RESET_REF_PICTURES || u4_mmco == RESET_ALL_PICTURES)
   1303             {
   1304                 ih264d_reset_ref_bufs(ps_dpb_mgr);
   1305                 u4_cur_pic_num = 0;
   1306             }
   1307         }
   1308     }
   1309     if(!u1_marked_lt && u1_insert_st_pic)
   1310     {
   1311         ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
   1312                               u4_cur_pic_num);
   1313         if(ret != OK)
   1314             return ret;
   1315     }
   1316     return OK;
   1317 }
   1318 
   1319 /*****************************************************************************/
   1320 /*                                                                           */
   1321 /*  Function Name : ih264d_release_pics_in_dpb                                         */
   1322 /*                                                                           */
   1323 /*  Description   : This function deletes all pictures from DPB              */
   1324 /*                                                                           */
   1325 /*  Inputs        : h_pic_buf_api: pointer to picture buffer API               */
   1326 /*                  u1_disp_bufs: number pictures ready for display           */
   1327 /*                                                                           */
   1328 /*  Globals       : None                                                     */
   1329 /*  Outputs       : None                                                     */
   1330 /*  Returns       : None                                                     */
   1331 /*                                                                           */
   1332 /*  Issues        : None                                                     */
   1333 /*                                                                           */
   1334 /*  Revision History:                                                        */
   1335 /*                                                                           */
   1336 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
   1337 /*         22 06 2005   NS              Draft                                */
   1338 /*                                                                           */
   1339 /*****************************************************************************/
   1340 void ih264d_release_pics_in_dpb(void *pv_dec,
   1341                                 UWORD8 u1_disp_bufs)
   1342 {
   1343     WORD8 i;
   1344     dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
   1345 
   1346     for(i = 0; i < u1_disp_bufs; i++)
   1347     {
   1348         ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
   1349                               i,
   1350                               BUF_MGR_REF);
   1351         ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
   1352                               ps_dec->au1_pic_buf_id_mv_buf_id_map[i],
   1353                               BUF_MGR_REF);
   1354     }
   1355 }
   1356 
   1357 /*****************************************************************************/
   1358 /*                                                                           */
   1359 /*  Function Name : ih264d_delete_gap_frm_sliding                            */
   1360 /*                                                                           */
   1361 /*  Description   : This function deletes a picture from the list of gaps,   */
   1362 /*                  if the frame number of gap frame is lesser than the one  */
   1363 /*                  to be deleted by sliding window                          */
   1364 /*  Inputs        : ps_dpb_mgr: pointer to dpb manager                       */
   1365 /*                  i4_frame_num:  frame number of picture that's going to   */
   1366 /*                  be deleted by sliding window                             */
   1367 /*                  pu1_del_node: holds 0 if a gap is deleted else 1         */
   1368 /*  Globals       : None                                                     */
   1369 /*  Processing    : Function searches for frame number lesser than           */
   1370 /*                  i4_frame_num in the gaps list                            */
   1371 /*  Outputs       : None                                                     */
   1372 /*  Returns       : None                                                     */
   1373 /*                                                                           */
   1374 /*  Issues        : None                                                     */
   1375 /*                                                                           */
   1376 /*  Revision History:                                                        */
   1377 /*                                                                           */
   1378 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
   1379 /*         22 06 2005   NS              Draft                                */
   1380 /*                                                                           */
   1381 /*****************************************************************************/
   1382 WORD32 ih264d_delete_gap_frm_sliding(dpb_manager_t *ps_dpb_mgr,
   1383                                     WORD32 i4_frame_num,
   1384                                     UWORD8 *pu1_del_node)
   1385 {
   1386     WORD8 i1_gap_idx, i, j, j_min;
   1387     WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num;
   1388     WORD32 i4_start_frm_num, i4_end_frm_num;
   1389     WORD32 i4_max_frm_num;
   1390     WORD32 i4_frm_num, i4_gap_frm_num_min;
   1391 
   1392     /* find the least frame num from gaps and current DPB node    */
   1393     /* Delete the least one                                       */
   1394     *pu1_del_node = 1;
   1395     if(0 == ps_dpb_mgr->u1_num_gaps)
   1396         return OK;
   1397     pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
   1398     pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num;
   1399     i4_gap_frame_num = INVALID_FRAME_NUM;
   1400     i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
   1401 
   1402     i1_gap_idx = -1;
   1403     if(INVALID_FRAME_NUM != i4_frame_num)
   1404     {
   1405         i4_gap_frame_num = i4_frame_num;
   1406         for(i = 0; i < MAX_FRAMES; i++)
   1407         {
   1408             i4_start_frm_num = pi4_gaps_start_frm_num[i];
   1409             if(INVALID_FRAME_NUM != i4_start_frm_num)
   1410             {
   1411                 i4_end_frm_num = pi4_gaps_end_frm_num[i];
   1412                 if(i4_end_frm_num < i4_max_frm_num)
   1413                 {
   1414                     if(i4_start_frm_num <= i4_gap_frame_num)
   1415                     {
   1416                         i4_gap_frame_num = i4_start_frm_num;
   1417                         i1_gap_idx = i;
   1418                     }
   1419                 }
   1420                 else
   1421                 {
   1422                     if(((i4_start_frm_num <= i4_gap_frame_num)
   1423                                     && (i4_gap_frame_num <= i4_max_frm_num))
   1424                                     || ((i4_start_frm_num >= i4_gap_frame_num)
   1425                                                     && ((i4_gap_frame_num
   1426                                                                     + i4_max_frm_num)
   1427                                                                     >= i4_end_frm_num)))
   1428                     {
   1429                         i4_gap_frame_num = i4_start_frm_num;
   1430                         i1_gap_idx = i;
   1431                     }
   1432                 }
   1433             }
   1434         }
   1435     }
   1436     else
   1437     {
   1438         /* no valid short term buffers, delete one gap from the least start */
   1439         /* of gap sequence                                                  */
   1440         i4_gap_frame_num = pi4_gaps_start_frm_num[0];
   1441         i1_gap_idx = 0;
   1442         for(i = 1; i < MAX_FRAMES; i++)
   1443         {
   1444             if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i])
   1445             {
   1446                 if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num)
   1447                 {
   1448                     i4_gap_frame_num = pi4_gaps_start_frm_num[i];
   1449                     i1_gap_idx = i;
   1450                 }
   1451             }
   1452         }
   1453         if(INVALID_FRAME_NUM == i4_gap_frame_num)
   1454         {
   1455             UWORD32 i4_error_code;
   1456             i4_error_code = ERROR_DBP_MANAGER_T;
   1457             return i4_error_code;
   1458         }
   1459     }
   1460 
   1461     if(-1 != i1_gap_idx)
   1462     {
   1463         /* find least frame_num in the poc_map, which is in this range */
   1464         i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx];
   1465         if(i4_start_frm_num < 0)
   1466             i4_start_frm_num += i4_max_frm_num;
   1467         i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx];
   1468         if(i4_end_frm_num < 0)
   1469             i4_end_frm_num += i4_max_frm_num;
   1470 
   1471         i4_gap_frm_num_min = 0xfffffff;
   1472         j_min = MAX_FRAMES;
   1473         for(j = 0; j < MAX_FRAMES; j++)
   1474         {
   1475             i4_frm_num = ps_dpb_mgr->ai4_poc_buf_id_map[j][2];
   1476             if((i4_start_frm_num <= i4_frm_num)
   1477                             && (i4_end_frm_num >= i4_frm_num))
   1478             {
   1479                 if(i4_frm_num < i4_gap_frm_num_min)
   1480                 {
   1481                     j_min = j;
   1482                     i4_gap_frm_num_min = i4_frm_num;
   1483                 }
   1484             }
   1485         }
   1486 
   1487         if(j_min != MAX_FRAMES)
   1488         {
   1489 
   1490             ps_dpb_mgr->ai4_poc_buf_id_map[j_min][0] = -1;
   1491             ps_dpb_mgr->ai4_poc_buf_id_map[j_min][1] = 0x7fffffff;
   1492             ps_dpb_mgr->ai4_poc_buf_id_map[j_min][2] = GAP_FRAME_NUM;
   1493             ps_dpb_mgr->i1_gaps_deleted++;
   1494 
   1495             ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--;
   1496             ps_dpb_mgr->u1_num_gaps--;
   1497             *pu1_del_node = 0;
   1498             if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx])
   1499             {
   1500                 ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] =
   1501                 INVALID_FRAME_NUM;
   1502                 ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0;
   1503             }
   1504         }
   1505     }
   1506 
   1507     return OK;
   1508 }
   1509 
   1510 /*****************************************************************************/
   1511 /*                                                                           */
   1512 /*  Function Name : ih264d_delete_gap_frm_mmco                               */
   1513 /*                                                                           */
   1514 /*  Description   : This function deletes a picture from the list of gaps,   */
   1515 /*                  if the frame number (specified by mmco commands) to be   */
   1516 /*                  deleted is in the range by gap sequence.                 */
   1517 /*                                                                           */
   1518 /*  Inputs        : ps_dpb_mgr: pointer to dpb manager                       */
   1519 /*                  i4_frame_num:  frame number of picture that's going to   */
   1520 /*                  be deleted by mmco                                       */
   1521 /*                  pu1_del_node: holds 0 if a gap is deleted else 1         */
   1522 /*  Globals       : None                                                     */
   1523 /*  Processing    : Function searches for frame number lesser in the range   */
   1524 /*                  specified by gap sequence                                */
   1525 /*  Outputs       : None                                                     */
   1526 /*  Returns       : None                                                     */
   1527 /*                                                                           */
   1528 /*  Issues        : None                                                     */
   1529 /*                                                                           */
   1530 /*  Revision History:                                                        */
   1531 /*                                                                           */
   1532 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
   1533 /*         22 06 2005   NS              Draft                                */
   1534 /*                                                                           */
   1535 /*****************************************************************************/
   1536 WORD32 ih264d_delete_gap_frm_mmco(dpb_manager_t *ps_dpb_mgr,
   1537                                   WORD32 i4_frame_num,
   1538                                   UWORD8 *pu1_del_node)
   1539 {
   1540     WORD8 i, j;
   1541     WORD32 *pi4_start, *pi4_end;
   1542     WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_frm_num;
   1543 
   1544     /* find the least frame num from gaps and current DPB node    */
   1545     /* Delete the gaps                                            */
   1546     *pu1_del_node = 1;
   1547     pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
   1548     pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
   1549     i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num;
   1550 
   1551     if(0 == ps_dpb_mgr->u1_num_gaps)
   1552         return OK;
   1553 
   1554     if(i4_frame_num < 0)
   1555         i4_frame_num += i4_max_frm_num;
   1556     for(i = 0; i < MAX_FRAMES; i++)
   1557     {
   1558         i4_start_frm_num = pi4_start[i];
   1559         if(i4_start_frm_num < 0)
   1560             i4_start_frm_num += i4_max_frm_num;
   1561         if(INVALID_FRAME_NUM != i4_start_frm_num)
   1562         {
   1563             i4_end_frm_num = pi4_end[i];
   1564             if(i4_end_frm_num < 0)
   1565                 i4_end_frm_num += i4_max_frm_num;
   1566 
   1567             if((i4_frame_num >= i4_start_frm_num)
   1568                             && (i4_frame_num <= i4_end_frm_num))
   1569             {
   1570                 break;
   1571             }
   1572             else
   1573             {
   1574                 if(((i4_frame_num + i4_max_frm_num) >= i4_start_frm_num)
   1575                                 && ((i4_frame_num + i4_max_frm_num)
   1576                                                 <= i4_end_frm_num))
   1577                 {
   1578                     UWORD32 i4_error_code;
   1579                     i4_error_code = ERROR_DBP_MANAGER_T;
   1580                     return i4_error_code;
   1581                 }
   1582             }
   1583         }
   1584     }
   1585 
   1586     /* find frame_num index, in the poc_map which needs to be deleted */
   1587     for(j = 0; j < MAX_FRAMES; j++)
   1588     {
   1589         if(i4_frame_num == ps_dpb_mgr->ai4_poc_buf_id_map[j][2])
   1590             break;
   1591     }
   1592 
   1593     if(MAX_FRAMES != i)
   1594     {
   1595         if(j == MAX_FRAMES)
   1596         {
   1597             UWORD32 i4_error_code;
   1598             i4_error_code = ERROR_DBP_MANAGER_T;
   1599             return i4_error_code;
   1600         }
   1601 
   1602         ps_dpb_mgr->ai4_poc_buf_id_map[j][0] = -1;
   1603         ps_dpb_mgr->ai4_poc_buf_id_map[j][1] = 0x7fffffff;
   1604         ps_dpb_mgr->ai4_poc_buf_id_map[j][2] = GAP_FRAME_NUM;
   1605         ps_dpb_mgr->i1_gaps_deleted++;
   1606 
   1607         ps_dpb_mgr->ai1_gaps_per_seq[i]--;
   1608         ps_dpb_mgr->u1_num_gaps--;
   1609         *pu1_del_node = 0;
   1610         if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
   1611         {
   1612             ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
   1613             ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
   1614         }
   1615     }
   1616     else
   1617     {
   1618         UWORD32 i4_error_code;
   1619         i4_error_code = ERROR_DBP_MANAGER_T;
   1620         return i4_error_code;
   1621     }
   1622 
   1623     return OK;
   1624 }
   1625 
   1626 /*!
   1627  **************************************************************************
   1628  * \if Function name : ih264d_do_mmco_for_gaps \endif
   1629  *
   1630  * \brief
   1631  *    Perform decoded picture buffer memory management control operations
   1632  *
   1633  * \return
   1634  *    0 - No error; -1 - Error
   1635  *
   1636  * \note
   1637  *    Bitstream is also parsed here to get the MMCOs
   1638  *
   1639  **************************************************************************
   1640  */
   1641 WORD32 ih264d_do_mmco_for_gaps(dpb_manager_t *ps_dpb_mgr,
   1642                              UWORD8 u1_num_ref_frames /*!< num_ref_frames from active SeqParSet*/
   1643                              )
   1644 {
   1645     struct dpb_info_t *ps_next_dpb;
   1646     UWORD8 u1_num_gaps;
   1647     UWORD8 u1_st_ref_bufs, u1_lt_ref_bufs, u1_del_node;
   1648     WORD8 i;
   1649     WORD32 i4_frame_gaps = 1;
   1650     WORD32 ret;
   1651 
   1652     //Sliding window - implements 8.2.5.3, flush out buffers
   1653     u1_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs;
   1654     u1_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs;
   1655 
   1656     while(1)
   1657     {
   1658         u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
   1659         if((u1_st_ref_bufs + u1_lt_ref_bufs + u1_num_gaps + i4_frame_gaps)
   1660                         > u1_num_ref_frames)
   1661         {
   1662             if(0 == (u1_st_ref_bufs + u1_num_gaps))
   1663             {
   1664                 i4_frame_gaps = 0;
   1665                 ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames
   1666                                 - u1_lt_ref_bufs);
   1667             }
   1668             else
   1669             {
   1670                 u1_del_node = 1;
   1671                 ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
   1672 
   1673                 if(u1_st_ref_bufs > 1)
   1674                 {
   1675                     for(i = 1; i < (u1_st_ref_bufs - 1); i++)
   1676                     {
   1677                         if(ps_next_dpb == NULL)
   1678                         {
   1679                             UWORD32 i4_error_code;
   1680                             i4_error_code = ERROR_DBP_MANAGER_T;
   1681                             return i4_error_code;
   1682                         }
   1683                         ps_next_dpb = ps_next_dpb->ps_prev_short;
   1684                     }
   1685 
   1686                     if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
   1687                     {
   1688                         return ERROR_DBP_MANAGER_T;
   1689                     }
   1690 
   1691                     if(u1_num_gaps)
   1692                     {
   1693                         ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1694                                                             ps_next_dpb->ps_prev_short->i4_frame_num,
   1695                                                             &u1_del_node);
   1696                         if(ret != OK)
   1697                             return ret;
   1698                     }
   1699 
   1700                     if(u1_del_node)
   1701                     {
   1702                         u1_st_ref_bufs--;
   1703                         ps_next_dpb->ps_prev_short->u1_used_as_ref =
   1704                                         UNUSED_FOR_REF;
   1705                         ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
   1706                                         UNUSED_FOR_REF;
   1707                         ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
   1708                                         UNUSED_FOR_REF;
   1709                         ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1710                                                     ps_next_dpb->ps_prev_short->u1_buf_id);
   1711                         ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
   1712                         ps_next_dpb->ps_prev_short = NULL;
   1713                     }
   1714                 }
   1715                 else
   1716                 {
   1717                     if(u1_st_ref_bufs)
   1718                     {
   1719                         if(u1_num_gaps)
   1720                         {
   1721                             ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1722                                                                 ps_next_dpb->i4_frame_num,
   1723                                                                 &u1_del_node);
   1724                             if(ret != OK)
   1725                                 return ret;
   1726                         }
   1727 
   1728                         if(u1_del_node)
   1729                         {
   1730                             u1_st_ref_bufs--;
   1731                             ps_next_dpb->u1_used_as_ref = FALSE;
   1732                             ps_next_dpb->s_top_field.u1_reference_info =
   1733                                             UNUSED_FOR_REF;
   1734                             ps_next_dpb->s_bot_field.u1_reference_info =
   1735                                             UNUSED_FOR_REF;
   1736                             ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1737                                                         ps_next_dpb->u1_buf_id);
   1738                             ps_next_dpb->ps_pic_buf = NULL;
   1739                             ps_next_dpb = NULL;
   1740                             ps_dpb_mgr->ps_dpb_st_head = NULL;
   1741                             ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
   1742                         }
   1743                     }
   1744                     else
   1745                     {
   1746                         ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1747                                                             INVALID_FRAME_NUM,
   1748                                                             &u1_del_node);
   1749                         if(ret != OK)
   1750                             return ret;
   1751                         if(u1_del_node)
   1752                         {
   1753                             return ERROR_DBP_MANAGER_T;
   1754                         }
   1755                     }
   1756                 }
   1757             }
   1758         }
   1759         else
   1760         {
   1761             ps_dpb_mgr->u1_num_gaps += i4_frame_gaps;
   1762             break;
   1763         }
   1764     }
   1765 
   1766     ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs;
   1767 
   1768     return OK;
   1769 }
   1770 /****************************************************************************/
   1771 /*                                                                          */
   1772 /* Function Name  : ih264d_free_node_from_dpb                                      */
   1773 /*                                                                          */
   1774 /* Description    :                                                         */
   1775 /*                                                                          */
   1776 /* Inputs         :                                                         */
   1777 /*                                                                          */
   1778 /* Globals        :                                                         */
   1779 /*                                                                          */
   1780 /* Processing     :                                                         */
   1781 /*                                                                          */
   1782 /* Outputs        :                                                         */
   1783 /*                                                                          */
   1784 /* Returns        :                                                         */
   1785 /*                                                                          */
   1786 /* Known Issues   :                                                         */
   1787 /*                                                                          */
   1788 /* Revision History                                                         */
   1789 /*                                                                          */
   1790 /*      DD MM YY            Author        Changes                           */
   1791 /*                          Sarat                                           */
   1792 /****************************************************************************/
   1793 /**** Function Added for Error Resilience *****/
   1794 WORD32 ih264d_free_node_from_dpb(dpb_manager_t *ps_dpb_mgr,
   1795                                UWORD32 u4_cur_pic_num,
   1796                                UWORD8 u1_numRef_frames_for_seq)
   1797 {
   1798     WORD32 i;
   1799     UWORD8 u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
   1800     struct dpb_info_t *ps_next_dpb;
   1801     UWORD8 u1_del_node = 1;
   1802     WORD32 ret;
   1803 
   1804     //Sliding window - implements 8.2.5.3
   1805     if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs
   1806                     + u1_num_gaps) == u1_numRef_frames_for_seq)
   1807     {
   1808         UWORD8 u1_new_node_flag = 1;
   1809         if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
   1810         {
   1811             return ERROR_DBP_MANAGER_T;
   1812         }
   1813 
   1814         // Chase the links to reach the last but one picNum, if available
   1815         ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
   1816 
   1817         if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
   1818         {
   1819             if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
   1820             {
   1821                 /* Incase of  filed pictures top_field has been allocated   */
   1822                 /* picture buffer and complementary bottom field pair comes */
   1823                 /* then the sliding window mechanism should not allocate a  */
   1824                 /* new node                                                 */
   1825                 u1_new_node_flag = 0;
   1826             }
   1827 
   1828             for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
   1829             {
   1830                 if(ps_next_dpb == NULL)
   1831                     return ERROR_DBP_MANAGER_T;
   1832 
   1833                 if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num)
   1834                 {
   1835                     /* Incase of  field pictures top_field has been allocated   */
   1836                     /* picture buffer and complementary bottom field pair comes */
   1837                     /* then the sliding window mechanism should not allocate a  */
   1838                     /* new node                                                 */
   1839                     u1_new_node_flag = 0;
   1840                 }
   1841                 ps_next_dpb = ps_next_dpb->ps_prev_short;
   1842             }
   1843 
   1844             if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
   1845                 return ERROR_DBP_MANAGER_T;
   1846 
   1847             if(u1_new_node_flag)
   1848             {
   1849                 if(u1_num_gaps)
   1850                 {
   1851                     ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1852                                                         ps_next_dpb->ps_prev_short->i4_frame_num,
   1853                                                         &u1_del_node);
   1854                     if(ret != OK)
   1855                         return ret;
   1856                 }
   1857 
   1858                 if(u1_del_node)
   1859                 {
   1860                     ps_dpb_mgr->u1_num_st_ref_bufs--;
   1861                     ps_next_dpb->ps_prev_short->u1_used_as_ref = UNUSED_FOR_REF;
   1862                     ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info =
   1863                                     UNUSED_FOR_REF;
   1864                     ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info =
   1865                                     UNUSED_FOR_REF;
   1866                     ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1867                                                 ps_next_dpb->ps_prev_short->u1_buf_id);
   1868                     ps_next_dpb->ps_prev_short->ps_pic_buf = NULL;
   1869                     ps_next_dpb->ps_prev_short = NULL;
   1870                 }
   1871             }
   1872         }
   1873         else
   1874         {
   1875             if(ps_dpb_mgr->u1_num_st_ref_bufs)
   1876             {
   1877                 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr,
   1878                                                     ps_next_dpb->i4_frame_num,
   1879                                                     &u1_del_node);
   1880                 if(ret != OK)
   1881                     return ret;
   1882                 if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num)
   1883                                 && u1_del_node)
   1884                 {
   1885                     ps_dpb_mgr->u1_num_st_ref_bufs--;
   1886                     ps_next_dpb->u1_used_as_ref = FALSE;
   1887                     ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
   1888                     ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
   1889                     ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle,
   1890                                                 ps_next_dpb->u1_buf_id);
   1891                     ps_next_dpb->ps_pic_buf = NULL;
   1892                     ps_next_dpb = NULL;
   1893                 }
   1894             }
   1895             else
   1896             {
   1897                 ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node);
   1898                 if(ret != OK)
   1899                     return ret;
   1900                 if(u1_del_node)
   1901                     return ERROR_DBP_MANAGER_T;
   1902             }
   1903         }
   1904     }
   1905     return OK;
   1906 }
   1907 /*****************************************************************************/
   1908 /*                                                                           */
   1909 /*  Function Name : ih264d_delete_nonref_nondisplay_pics                            */
   1910 /*                                                                           */
   1911 /*  Description   :                                                          */
   1912 /*                                                                           */
   1913 /*                                                                           */
   1914 /*  Inputs        :                                                          */
   1915 /*  Globals       :                                                          */
   1916 /*  Processing    :                                                          */
   1917 /*                                                                           */
   1918 /*  Outputs       :                                                          */
   1919 /*  Returns       :                                                          */
   1920 /*                                                                           */
   1921 /*  Issues        :                                                          */
   1922 /*                                                                           */
   1923 /*  Revision History:                                                        */
   1924 /*                                                                           */
   1925 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
   1926 /*         05 06 2007   Varun           Draft                                */
   1927 /*                                                                           */
   1928 /*****************************************************************************/
   1929 
   1930 void ih264d_delete_nonref_nondisplay_pics(dpb_manager_t *ps_dpb_mgr)
   1931 {
   1932     WORD8 i;
   1933     WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
   1934 
   1935     /* remove all gaps marked as unused for ref */
   1936     for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++)
   1937     {
   1938         if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
   1939         {
   1940             ps_dpb_mgr->i1_gaps_deleted--;
   1941             ps_dpb_mgr->i1_poc_buf_id_entries--;
   1942             i4_poc_buf_id_map[i][0] = -1;
   1943             i4_poc_buf_id_map[i][1] = 0x7fffffff;
   1944             i4_poc_buf_id_map[i][2] = 0;
   1945         }
   1946     }
   1947 }
   1948 /*****************************************************************************/
   1949 /*                                                                           */
   1950 /*  Function Name : ih264d_insert_pic_in_display_list                               */
   1951 /*                                                                           */
   1952 /*  Description   :                                                          */
   1953 /*                                                                           */
   1954 /*                                                                           */
   1955 /*  Inputs        :                                                          */
   1956 /*  Globals       :                                                          */
   1957 /*  Processing    :                                                          */
   1958 /*                                                                           */
   1959 /*  Outputs       :                                                          */
   1960 /*  Returns       :                                                          */
   1961 /*                                                                           */
   1962 /*  Issues        :                                                          */
   1963 /*                                                                           */
   1964 /*  Revision History:                                                        */
   1965 /*                                                                           */
   1966 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
   1967 /*         05 06 2007   Varun           Draft                                */
   1968 /*                                                                           */
   1969 /*****************************************************************************/
   1970 
   1971 WORD32 ih264d_insert_pic_in_display_list(dpb_manager_t *ps_dpb_mgr,
   1972                                          UWORD8 u1_buf_id,
   1973                                          WORD32 i4_display_poc,
   1974                                          UWORD32 u4_frame_num)
   1975 {
   1976     WORD8 i;
   1977     WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
   1978 
   1979     for(i = 0; i < MAX_FRAMES; i++)
   1980     {
   1981         /* Find an empty slot */
   1982         if(i4_poc_buf_id_map[i][0] == -1)
   1983         {
   1984             if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2])
   1985                 ps_dpb_mgr->i1_gaps_deleted--;
   1986             else
   1987                 ps_dpb_mgr->i1_poc_buf_id_entries++;
   1988 
   1989             i4_poc_buf_id_map[i][0] = u1_buf_id;
   1990             i4_poc_buf_id_map[i][1] = i4_display_poc;
   1991             i4_poc_buf_id_map[i][2] = u4_frame_num;
   1992 
   1993             break;
   1994         }
   1995     }
   1996 
   1997     if(MAX_FRAMES == i)
   1998     {
   1999 
   2000         UWORD32 i4_error_code;
   2001         i4_error_code = ERROR_GAPS_IN_FRM_NUM;
   2002         return i4_error_code;
   2003     }
   2004     return OK;
   2005 }
   2006 
   2007