Home | History | Annotate | Download | only in common
      1 /******************************************************************************
      2 *
      3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
      4 *
      5 * Licensed under the Apache License, Version 2.0 (the "License");
      6 * you may not use this file except in compliance with the License.
      7 * You may obtain a copy of the License at:
      8 *
      9 * http://www.apache.org/licenses/LICENSE-2.0
     10 *
     11 * Unless required by applicable law or agreed to in writing, software
     12 * distributed under the License is distributed on an "AS IS" BASIS,
     13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 * See the License for the specific language governing permissions and
     15 * limitations under the License.
     16 *
     17 ******************************************************************************/
     18 /**
     19  *******************************************************************************
     20  * @file
     21  *  ihevc_dpb_mgr.c
     22  *
     23  * @brief
     24  *  Function definitions used for decoded picture buffer management
     25  *
     26  * @author
     27  *  Srinivas T
     28  *
     29  * @par List of Functions:
     30  *   - ihevc_dpb_mgr_init()
     31  *   - ihevc_dpb_mgr_del_lt()
     32  *   - ihevc_dpb_mgr_insert_lt()
     33  *   - ihevc_dpb_mgr_del_st_or_make_lt()
     34  *   - ihevc_dpb_mgr_insert_st()
     35  *   - ihevc_dpb_mgr_reset()
     36  *   - ihevc_dpb_mgr_release_pics()
     37  *
     38  * @remarks
     39  *  None
     40  *
     41  *******************************************************************************
     42  */
     43 
     44 #include <stdio.h>
     45 #include <stdlib.h>
     46 
     47 #include "ihevc_typedefs.h"
     48 #include "ihevc_defs.h"
     49 #include "ihevc_macros.h"
     50 #include "ihevc_func_selector.h"
     51 #include "ihevc_structs.h"
     52 #include "ihevc_buf_mgr.h"
     53 #include "ihevc_dpb_mgr.h"
     54 
     55 /**
     56  *******************************************************************************
     57  *
     58  * @brief
     59  *  DPB manager initializer
     60  *
     61  * @par Description:
     62  *  Initialises the DPB manager structure
     63  *
     64  * @param[in] ps_dpb_mgr
     65  *  Pointer to the DPB manager structure
     66  *
     67  * @returns
     68  *
     69  * @remarks
     70  *
     71  *
     72  *******************************************************************************
     73  */
     74 
     75 void ihevc_dpb_mgr_init(dpb_mgr_t *ps_dpb_mgr)
     76 {
     77     UWORD32 i;
     78     dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
     79     for(i = 0; i < MAX_DPB_BUFS; i++)
     80     {
     81         ps_dpb_info[i].ps_prev_dpb = NULL;
     82         ps_dpb_info[i].ps_pic_buf = NULL;
     83 
     84     }
     85 
     86     ps_dpb_mgr->u1_num_ref_bufs = 0;
     87     ps_dpb_mgr->ps_dpb_head = NULL;
     88 
     89 }
     90 
     91 
     92 /**
     93  *******************************************************************************
     94  *
     95  * @brief
     96  *  Adds a reference picture into the linked  list
     97  *
     98  * @par Description:
     99  *  Adds the reference buffer with the given buffer id into the DPB manager
    100  *
    101  *
    102  * @param[in] ps_dpb_mgr
    103  *  Pointer to the DPB manager structure
    104  *
    105  * @param[in] ps_picBuf
    106  *  Pointer to the picture buffer
    107  *
    108  * @param[in] buf_id
    109  *  buffer id of the picture buffer
    110  *
    111  * @returns  0 if successful, -1 otherwise
    112  *
    113  * @remarks
    114  *
    115  *
    116  *******************************************************************************
    117  */
    118 
    119 WORD32 ihevc_dpb_mgr_insert_ref(dpb_mgr_t *ps_dpb_mgr,
    120                                 pic_buf_t *ps_pic_buf,
    121                                 WORD32 buf_id)
    122 {
    123     int i;
    124     dpb_info_t *ps_dpb_info;
    125 
    126     ps_dpb_info = ps_dpb_mgr->as_dpb_info;
    127 
    128     /* Return error if buffer is already present in the DPB */
    129     for(i = 0; i < MAX_DPB_BUFS; i++)
    130     {
    131         if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf)
    132                         && (ps_dpb_info[i].ps_pic_buf->u1_used_as_ref))
    133         {
    134             return (-1);
    135         }
    136 
    137 
    138     }
    139 
    140     /* Find an unused DPB location */
    141     for(i = 0; i < MAX_DPB_BUFS; i++)
    142     {
    143         if(NULL == ps_dpb_info[i].ps_pic_buf)
    144         {
    145             break;
    146         }
    147     }
    148     if(i == MAX_DPB_BUFS)
    149     {
    150         return (-1);
    151     }
    152 
    153     /* Create DPB info */
    154     ps_dpb_info[i].ps_pic_buf = ps_pic_buf;
    155     ps_dpb_info[i].ps_prev_dpb = ps_dpb_mgr->ps_dpb_head;
    156     ps_dpb_info[i].ps_pic_buf->u1_buf_id = buf_id;
    157     ps_dpb_info[i].ps_pic_buf->u1_used_as_ref = SHORT_TERM_REF;
    158 
    159     /* update the head node of linked list to point to the current picture */
    160     ps_dpb_mgr->ps_dpb_head = ps_dpb_info + i;
    161 
    162     /* Increment Short term buffer count */
    163     ps_dpb_mgr->u1_num_ref_bufs++;
    164 
    165     return 0;
    166 }
    167 
    168 /**
    169  *******************************************************************************
    170  *
    171  * @brief
    172  *  Deletes a reference buffer from the dpb manager
    173  *
    174  * @par Description:
    175  *  Delete short term reference with a given POC from the linked
    176  *  list
    177  *
    178  * @param[in] ps_dpb_mgr
    179  *  Pointer to DPB Manager structure
    180  *
    181  * @param[in] ps_buf_mgr
    182  *  Pointer to buffer manager structure
    183  *
    184  * @param[in] u4_abs_poc
    185  *  Node's absolute poc
    186  *
    187  *
    188  * @returns  0 if successful, -1 otherwise
    189  *
    190  * @remarks
    191  *
    192  *
    193  *******************************************************************************
    194  */
    195 
    196 void ihevc_dpb_mgr_del_ref(dpb_mgr_t *ps_dpb_mgr,
    197                            buf_mgr_t *ps_buf_mgr,
    198                            WORD32 i4_abs_poc)
    199 {
    200     int i;
    201     dpb_info_t *ps_next_dpb;
    202 
    203     dpb_info_t *ps_unmark_node;
    204     UWORD8 u1_del_node;
    205     UNUSED(u1_del_node);
    206     u1_del_node = 0;
    207 
    208     /* Find the node with matching absolute POC */
    209     ps_next_dpb = ps_dpb_mgr->ps_dpb_head;
    210     if(ps_next_dpb->ps_pic_buf->i4_abs_poc == i4_abs_poc)
    211     {
    212         ps_unmark_node = ps_next_dpb;
    213     }
    214     else
    215     {
    216         for(i = 1; i < ps_dpb_mgr->u1_num_ref_bufs; i++)
    217         {
    218             if(ps_next_dpb->ps_prev_dpb->ps_pic_buf->i4_abs_poc == i4_abs_poc)
    219                 break;
    220             ps_next_dpb = ps_next_dpb->ps_prev_dpb;
    221         }
    222 
    223         if(i == ps_dpb_mgr->u1_num_ref_bufs)
    224         {
    225             return;
    226         }
    227         else
    228             ps_unmark_node = ps_next_dpb->ps_prev_dpb;
    229     }
    230 
    231     if(ps_unmark_node == ps_dpb_mgr->ps_dpb_head)
    232     {
    233         ps_dpb_mgr->ps_dpb_head = ps_unmark_node->ps_prev_dpb;
    234     }
    235     else
    236     {
    237         ps_next_dpb->ps_prev_dpb = ps_unmark_node->ps_prev_dpb; //update link
    238         ps_unmark_node->ps_prev_dpb = NULL;
    239     }
    240     ps_dpb_mgr->u1_num_ref_bufs--; //decrement buffer count
    241 
    242     /* Release the physical buffer */
    243     ihevc_buf_mgr_release((buf_mgr_t *)ps_buf_mgr, ps_unmark_node->ps_pic_buf->u1_buf_id,
    244                           BUF_MGR_REF);
    245     ps_unmark_node->ps_prev_dpb = NULL;
    246     ps_unmark_node->ps_pic_buf = NULL;
    247 }
    248 
    249 
    250 /**
    251  *******************************************************************************
    252  *
    253  * @brief
    254  *  Gets a buffer with abs_poc closest to the current poc
    255  *
    256  * @par Description:
    257  *  Returns the pointer to the picture buffer whose poc is equal to abs_poc
    258  *
    259  * @param[in] ps_dpb_mgr
    260  *  Pointer to DPB Manager structure
    261  *
    262  * @param[out] ps_pic_buf
    263  *  Pointer to picture buffer
    264 
    265  * @param[in] abs_poc
    266  *  poc of the buffer to be returned
    267  *
    268  * @returns
    269  *  0 if successful, pic_buf otherwise
    270  * @remarks
    271  *
    272  *
    273  *******************************************************************************
    274  */
    275 pic_buf_t* ihevc_dpb_mgr_get_ref_by_nearest_poc(dpb_mgr_t *ps_dpb_mgr, WORD32 cur_abs_poc)
    276 {
    277     WORD32 i;
    278     WORD32 min_diff = 0x7FFFFFFF;
    279     pic_buf_t *ps_pic_buf = NULL;
    280 
    281     for(i = 0; i < MAX_DPB_BUFS; i++)
    282     {
    283         if((ps_dpb_mgr->as_dpb_info[i].ps_pic_buf) &&
    284                         (ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->u1_used_as_ref != UNUSED_FOR_REF))
    285         {
    286             WORD32 poc_diff = cur_abs_poc - ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->i4_abs_poc;
    287             if((poc_diff > 0) && (poc_diff < min_diff))
    288             {
    289                 min_diff = poc_diff;
    290                 ps_pic_buf = ps_dpb_mgr->as_dpb_info[i].ps_pic_buf;
    291             }
    292         }
    293     }
    294 
    295     if(NULL == ps_pic_buf)
    296     {
    297         min_diff = 0x7FFFFFFF;
    298         for(i = 0; i < MAX_DPB_BUFS; i++)
    299         {
    300             if((ps_dpb_mgr->as_dpb_info[i].ps_pic_buf) &&
    301                             (ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->u1_used_as_ref != UNUSED_FOR_REF))
    302             {
    303                 WORD32 poc_diff = cur_abs_poc - ps_dpb_mgr->as_dpb_info[i].ps_pic_buf->i4_abs_poc;
    304                 if(ABS(poc_diff) < min_diff)
    305                 {
    306                     min_diff = ABS(poc_diff);
    307                     ps_pic_buf = ps_dpb_mgr->as_dpb_info[i].ps_pic_buf;
    308                 }
    309             }
    310         }
    311     }
    312 
    313     return ps_pic_buf;
    314 }
    315 
    316 
    317 /**
    318  *******************************************************************************
    319  *
    320  * @brief
    321  *  Gets a buffer with abs_poc
    322  *
    323  * @par Description:
    324  *  Returns the pointer to the picture buffer whose poc is equal to abs_poc
    325  *
    326  * @param[in] ps_dpb_mgr
    327  *  Pointer to DPB Manager structure
    328  *
    329  * @param[out] ps_pic_buf
    330  *  Pointer to picture buffer
    331 
    332  * @param[in] abs_poc
    333  *  poc of the buffer to be returned
    334  *
    335  * @returns
    336  *  0 if successful, pic_buf otherwise
    337  * @remarks
    338  *
    339  *
    340  *******************************************************************************
    341  */
    342 pic_buf_t* ihevc_dpb_mgr_get_ref_by_poc(dpb_mgr_t *ps_dpb_mgr, WORD32 abs_poc)
    343 {
    344     UWORD32 i;
    345     dpb_info_t *ps_next_ref;
    346     pic_buf_t *ps_pic_buf = NULL;
    347 
    348 
    349     ps_next_ref = ps_dpb_mgr->ps_dpb_head;
    350     for(i = 0; i < ps_dpb_mgr->u1_num_ref_bufs; i++)
    351     {
    352         if(ps_next_ref->ps_pic_buf->i4_abs_poc == abs_poc)
    353         {
    354             ps_pic_buf = ps_next_ref->ps_pic_buf;
    355             break;
    356         }
    357 
    358         ps_next_ref = ps_next_ref->ps_prev_dpb;
    359     }
    360 
    361     if(i == ps_dpb_mgr->u1_num_ref_bufs)
    362     {
    363         ps_pic_buf = NULL;
    364     }
    365 
    366     return ps_pic_buf;
    367 }
    368 
    369 /**
    370  *******************************************************************************
    371  *
    372  * @brief
    373  *  Gets a buffer with poc_lsb
    374  *
    375  * @par Description:
    376  *  Returns the pointer to the picture buffer whose poc is equal to poc_lsb
    377  *
    378  * @param[in] ps_dpb_mgr
    379  *  Pointer to DPB Manager structure
    380  *
    381  * @param[out] ps_pic_buf
    382  *  Pointer to picture buffer
    383 
    384  * @param[in] poc_lsb
    385  *  poc_lsb of the buffer to be returned
    386  *
    387  * @returns
    388  *  0 if successful, pic_buf otherwise
    389  * @remarks
    390  *
    391  *
    392  *******************************************************************************
    393  */
    394 
    395 pic_buf_t* ihevc_dpb_mgr_get_ref_by_poc_lsb(dpb_mgr_t *ps_dpb_mgr, WORD32 poc_lsb)
    396 {
    397     pic_buf_t *ps_pic_buf = NULL;
    398     UWORD32 i;
    399     dpb_info_t *ps_next_ref;
    400 
    401     ps_next_ref = ps_dpb_mgr->ps_dpb_head;
    402     for(i = 0; i < ps_dpb_mgr->u1_num_ref_bufs; i++)
    403     {
    404         if(ps_next_ref->ps_pic_buf->i4_poc_lsb == poc_lsb)
    405         {
    406             ps_pic_buf = ps_next_ref->ps_pic_buf;
    407             break;
    408         }
    409 
    410         ps_next_ref = ps_next_ref->ps_prev_dpb;
    411     }
    412 
    413     if(i == ps_dpb_mgr->u1_num_ref_bufs)
    414     {
    415         ps_pic_buf = NULL;
    416     }
    417 
    418     return ps_pic_buf;
    419 }
    420 
    421 
    422 /**
    423  *******************************************************************************
    424  *
    425  * @brief
    426  *  Resets the DPB manager
    427  *
    428  * @par Description:
    429  *  Re-initialises the DPB manager structure
    430  *
    431  * @param[in] ps_dpb_mgr
    432  *  Pointer to DPB Manager structure
    433  *
    434  * @param[in] ps_buf_mgr
    435  *  Pointer to buffer manager structure
    436  *
    437  * @returns
    438  *
    439  * @remarks
    440  *
    441  *
    442  *******************************************************************************
    443  */
    444 
    445 void ihevc_dpb_mgr_reset(dpb_mgr_t *ps_dpb_mgr, buf_mgr_t *ps_buf_mgr)
    446 {
    447     int i;
    448     dpb_info_t *ps_dpb_info;
    449 
    450     ps_dpb_info = ps_dpb_mgr->as_dpb_info;
    451 
    452     for(i = 0; i < MAX_DPB_BUFS; i++)
    453     {
    454         if(ps_dpb_info[i].ps_pic_buf->u1_used_as_ref)
    455         {
    456             ps_dpb_info[i].ps_pic_buf->u1_used_as_ref = UNUSED_FOR_REF;
    457             ps_dpb_info[i].ps_prev_dpb = NULL;
    458             //Release physical buffer
    459             ihevc_buf_mgr_release(ps_buf_mgr, ps_dpb_info[i].ps_pic_buf->u1_buf_id,
    460                                   BUF_MGR_REF);
    461 
    462             ps_dpb_info[i].ps_pic_buf = NULL;
    463         }
    464     }
    465     ps_dpb_mgr->u1_num_ref_bufs = 0;
    466     ps_dpb_mgr->ps_dpb_head = NULL;
    467 
    468 }
    469 
    470 /**
    471  *******************************************************************************
    472  *
    473  * @brief
    474  *  deletes all pictures from DPB
    475  *
    476  * @par Description:
    477  *  Deletes all pictures present in the DPB manager
    478  *
    479  * @param[in] ps_buf_mgr
    480  *  Pointer to buffer manager structure
    481  *
    482  * @param[in] u1_disp_bufs
    483  *  Number of buffers to be deleted
    484  *
    485  * @returns
    486  *
    487  * @remarks
    488  *
    489  *
    490  *******************************************************************************
    491  */
    492 
    493 void ihevc_dpb_mgr_release_pics(buf_mgr_t *ps_buf_mgr, UWORD8 u1_disp_bufs)
    494 {
    495     WORD8 i;
    496     UWORD32 buf_status;
    497 
    498     for(i = 0; i < u1_disp_bufs; i++)
    499     {
    500         buf_status = ihevc_buf_mgr_get_status(ps_buf_mgr, i);
    501         if(0 != buf_status)
    502         {
    503             ihevc_buf_mgr_release((buf_mgr_t *)ps_buf_mgr, i, BUF_MGR_REF);
    504         }
    505     }
    506 }
    507