Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2 *
      3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
      4 *
      5 * Licensed under the Apache License, Version 2.0 (the "License");
      6 * you may not use this file except in compliance with the License.
      7 * You may obtain a copy of the License at:
      8 *
      9 * http://www.apache.org/licenses/LICENSE-2.0
     10 *
     11 * Unless required by applicable law or agreed to in writing, software
     12 * distributed under the License is distributed on an "AS IS" BASIS,
     13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 * See the License for the specific language governing permissions and
     15 * limitations under the License.
     16 *
     17 ******************************************************************************/
     18 /**
     19 *******************************************************************************
     20 * @file
     21 *  ihevcd_utils.c
     22 *
     23 * @brief
     24 *  Contains miscellaneous utility functions such as init() etc
     25 *
     26 * @author
     27 *  Harish
     28 *
     29 * @par List of Functions:
     30 *
     31 * @remarks
     32 *  None
     33 *
     34 *******************************************************************************
     35 */
     36 /*****************************************************************************/
     37 /* File Includes                                                             */
     38 /*****************************************************************************/
     39 #include <stdio.h>
     40 #include <stddef.h>
     41 #include <stdlib.h>
     42 #include <string.h>
     43 #include <assert.h>
     44 
     45 #include "ihevc_typedefs.h"
     46 #include "iv.h"
     47 #include "ivd.h"
     48 #include "ihevcd_cxa.h"
     49 #include "ithread.h"
     50 
     51 #include "ihevc_defs.h"
     52 #include "ihevc_debug.h"
     53 #include "ihevc_defs.h"
     54 #include "ihevc_error.h"
     55 #include "ihevc_structs.h"
     56 #include "ihevc_buf_mgr.h"
     57 #include "ihevc_dpb_mgr.h"
     58 #include "ihevc_macros.h"
     59 #include "ihevc_platform_macros.h"
     60 
     61 #include "ihevc_common_tables.h"
     62 #include "ihevc_buf_mgr.h"
     63 #include "ihevc_disp_mgr.h"
     64 #include "ihevc_cabac_tables.h"
     65 
     66 #include "ihevcd_defs.h"
     67 
     68 #include "ihevcd_function_selector.h"
     69 #include "ihevcd_structs.h"
     70 #include "ihevcd_error.h"
     71 #include "ihevcd_nal.h"
     72 #include "ihevcd_bitstream.h"
     73 #include "ihevcd_utils.h"
     74 #include "ihevcd_trace.h"
     75 #include "ihevcd_process_slice.h"
     76 #include "ihevcd_job_queue.h"
     77 #define MAX_DPB_PIC_BUF 6
     78 
     79 /* Function declarations */
     80 mv_buf_t* ihevcd_mv_mgr_get_poc(buf_mgr_t *ps_mv_buf_mgr, UWORD32 abs_poc);
     81 
     82 /**
     83 *******************************************************************************
     84 *
     85 * @brief
     86 *  Used to get level index for a given level
     87 *
     88 * @par Description:
     89 *  Converts from level_idc (which is multiplied by 30) to an index that can be
     90 *  used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
     91 *
     92 * @param[in] level
     93 *  Level of the stream
     94 *
     95 * @returns  Level index for a given level
     96 *
     97 * @remarks
     98 *
     99 *
    100 *******************************************************************************
    101 */
    102 WORD32 ihevcd_get_lvl_idx(WORD32 level)
    103 {
    104     WORD32 lvl_idx = 0;
    105 
    106     if(level < IHEVC_LEVEL_20)
    107     {
    108         lvl_idx = 0;
    109     }
    110     else if(level >= IHEVC_LEVEL_20 && level < IHEVC_LEVEL_21)
    111     {
    112         lvl_idx = 1;
    113     }
    114     else if(level >= IHEVC_LEVEL_21 && level < IHEVC_LEVEL_30)
    115     {
    116         lvl_idx = 2;
    117     }
    118     else if(level >= IHEVC_LEVEL_30 && level < IHEVC_LEVEL_31)
    119     {
    120         lvl_idx = 3;
    121     }
    122     else if(level >= IHEVC_LEVEL_31 && level < IHEVC_LEVEL_40)
    123     {
    124         lvl_idx = 4;
    125     }
    126     else if(level >= IHEVC_LEVEL_40 && level < IHEVC_LEVEL_41)
    127     {
    128         lvl_idx = 5;
    129     }
    130     else if(level >= IHEVC_LEVEL_41 && level < IHEVC_LEVEL_50)
    131     {
    132         lvl_idx = 6;
    133     }
    134     else if(level >= IHEVC_LEVEL_50 && level < IHEVC_LEVEL_51)
    135     {
    136         lvl_idx = 7;
    137     }
    138     else if(level >= IHEVC_LEVEL_51 && level < IHEVC_LEVEL_52)
    139     {
    140         lvl_idx = 8;
    141     }
    142     else if(level >= IHEVC_LEVEL_52 && level < IHEVC_LEVEL_60)
    143     {
    144         lvl_idx = 9;
    145     }
    146     else if(level >= IHEVC_LEVEL_60 && level < IHEVC_LEVEL_61)
    147     {
    148         lvl_idx = 10;
    149     }
    150     else if(level >= IHEVC_LEVEL_61 && level < IHEVC_LEVEL_62)
    151     {
    152         lvl_idx = 11;
    153     }
    154     else if(level >= IHEVC_LEVEL_62)
    155     {
    156         lvl_idx = 12;
    157     }
    158 
    159     return (lvl_idx);
    160 }
    161 
    162 /**
    163 *******************************************************************************
    164 *
    165 * @brief
    166 *  Used to get reference picture buffer size for a given level and
    167 *  and padding used
    168 *
    169 * @par Description:
    170 *  Used to get reference picture buffer size for a given level and padding used
    171 *  Each picture is padded on all four sides
    172 *
    173 * @param[in] pic_size
    174 *  Mumber of luma samples (Width * Height)
    175 *
    176 * @param[in] level
    177 *  Level
    178 *
    179 * @param[in] horz_pad
    180 *  Total padding used in horizontal direction
    181 *
    182 * @param[in] vert_pad
    183 *  Total padding used in vertical direction
    184 *
    185 * @returns  Total picture buffer size
    186 *
    187 * @remarks
    188 *
    189 *
    190 *******************************************************************************
    191 */
    192 WORD32 ihevcd_get_total_pic_buf_size(codec_t *ps_codec,
    193                                      WORD32 wd,
    194                                      WORD32 ht)
    195 {
    196     WORD32 size;
    197     WORD32 num_luma_samples;
    198     WORD32 max_dpb_size;
    199     WORD32 num_samples;
    200 
    201 
    202     sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
    203 
    204     /* Get maximum number of buffers for the current picture size */
    205     max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
    206 
    207     if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
    208         max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
    209 
    210     max_dpb_size++;
    211     /* Allocation is required for
    212      * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
    213      */
    214 
    215     /* Account for padding area */
    216     num_luma_samples = (wd + PAD_WD) * (ht + PAD_HT);
    217 
    218     /* Account for chroma */
    219     num_samples = num_luma_samples * 3 / 2;
    220 
    221     /* Number of bytes in reference pictures */
    222     size = num_samples * max_dpb_size;
    223 
    224 
    225     return size;
    226 }
    227 /**
    228 *******************************************************************************
    229 *
    230 * @brief
    231 *  Used to get MV bank size for a given number of luma samples
    232 *
    233 * @par Description:
    234 *  For given number of luma samples  one MV bank size is computed
    235 *  Each MV bank includes pu_map and pu_t for all the min PUs(4x4) in a picture
    236 *
    237 * @param[in] num_luma_samples
    238 *  Max number of luma pixels in the frame
    239 *
    240 * @returns  Total MV Bank size
    241 *
    242 * @remarks
    243 *
    244 *
    245 *******************************************************************************
    246 */
    247 WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)
    248 {
    249     WORD32 size;
    250 
    251     WORD32 pic_size;
    252 
    253     WORD32 mv_bank_size;
    254     WORD32 num_pu;
    255     WORD32 num_ctb;
    256     pic_size = num_luma_samples;
    257 
    258 
    259     num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
    260     num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
    261 
    262     mv_bank_size = 0;
    263 
    264     /* Size for storing pu_t start index each CTB */
    265     /* One extra entry is needed to compute number of PUs in the last CTB */
    266     mv_bank_size += (num_ctb + 1) * sizeof(WORD32);
    267 
    268     /* Size for pu_map */
    269     mv_bank_size += num_pu;
    270 
    271     /* Size for storing pu_t for each PU */
    272     mv_bank_size += num_pu * sizeof(pu_t);
    273 
    274     /* Size for storing slice_idx for each CTB */
    275     mv_bank_size += ALIGN4(num_ctb * sizeof(UWORD16));
    276 
    277     size =  mv_bank_size;
    278     return size;
    279 }
    280 /**
    281 *******************************************************************************
    282 *
    283 * @brief
    284 *  Used to get TU data size for a given number luma samples
    285 *
    286 * @par Description:
    287 *  For a given number of luma samples TU data size is computed
    288 *  Each TU data includes tu_map and tu_t and coeff data for all
    289 *  the min TUs(4x4) in given CTB
    290 *
    291 * @param[in] num_luma_samples
    292 *  Number of 64 x 64 CTBs for which TU data has to be allocated.
    293 *
    294 * @returns  Total TU data size
    295 *
    296 * @remarks Assumption is num_luma_samples will be at least
    297 * 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well
    298 *
    299 *******************************************************************************
    300 */
    301 WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples)
    302 {
    303 
    304 
    305     WORD32 tu_data_size;
    306     WORD32 num_ctb;
    307     WORD32 num_luma_tu, num_chroma_tu, num_tu;
    308     num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE);
    309 
    310     num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE);
    311     num_chroma_tu = num_luma_tu >> 1;
    312 
    313     num_tu = num_luma_tu + num_chroma_tu;
    314     tu_data_size = 0;
    315 
    316     /* Size for storing tu_t start index each CTB */
    317     /* One extra entry is needed to compute number of TUs in the last CTB */
    318     tu_data_size += (num_ctb + 1) * sizeof(WORD32);
    319 
    320     /* Size for storing tu map */
    321     tu_data_size += num_luma_tu * sizeof(UWORD8);
    322 
    323     /* Size for storing tu_t for each TU */
    324     tu_data_size += num_tu * sizeof(tu_t);
    325 
    326     /* Size for storing number of coded subblocks and scan_idx for each TU */
    327     tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8));
    328 
    329     /* Size for storing coeff data for each TU */
    330     tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t);
    331 
    332 
    333     return tu_data_size;
    334 }
    335 
    336 
    337 WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps)
    338 {
    339     WORD32 nctb = 1;
    340     UNUSED(ps_codec);
    341     //TODO: Currently set to 1
    342     /* If CTB size is less than 32 x 32 then set nCTB as 4 */
    343     if(ps_sps->i1_log2_ctb_size < 5)
    344         nctb = 1;
    345 
    346     return nctb;
    347 }
    348 
    349 IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps,
    350                                    sps_t *ps_sps,
    351                                    WORD32 ctb_x,
    352                                    WORD32 ctb_y,
    353                                    WORD32 *pi4_ctb_tile_x,
    354                                    WORD32 *pi4_ctb_tile_y,
    355                                    WORD32 *pi4_tile_idx)
    356 {
    357 
    358     tile_t *ps_tile_tmp;
    359     WORD32 i;
    360     WORD32 tile_row, tile_col;
    361 
    362     if(ctb_x < 0 || ctb_y < 0)
    363     {
    364         *pi4_ctb_tile_x = 0;
    365         *pi4_ctb_tile_y = 0;
    366         *pi4_tile_idx = 0;
    367 
    368         return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    369     }
    370 
    371     tile_row = 0;
    372     tile_col = 0;
    373     ps_tile_tmp = ps_pps->ps_tile;
    374     if(0 == ps_pps->i1_tiles_enabled_flag)
    375     {
    376         *pi4_ctb_tile_x = ctb_x;
    377         *pi4_ctb_tile_y = ctb_y;
    378         *pi4_tile_idx = 0;
    379     }
    380     else
    381     {
    382         for(i = 0; i < ps_pps->i1_num_tile_columns; i++)
    383         {
    384             WORD16 next_tile_ctb_x;
    385             ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows;
    386             if((ps_pps->i1_num_tile_columns - 1) == i)
    387             {
    388                 next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb;
    389             }
    390             else
    391             {
    392                 tile_t *ps_tile_next_tmp;
    393                 ps_tile_next_tmp = ps_pps->ps_tile + i + 1;
    394                 next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x;
    395             }
    396             if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x))
    397             {
    398                 tile_col = i;
    399                 break;
    400             }
    401         }
    402         *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x;
    403 
    404         for(i = 0; i < ps_pps->i1_num_tile_rows; i++)
    405         {
    406             WORD16 next_tile_ctb_y;
    407             ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns;
    408             if((ps_pps->i1_num_tile_rows - 1) == i)
    409             {
    410                 next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb;
    411             }
    412             else
    413             {
    414                 tile_t *ps_tile_next_tmp;
    415                 ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns);
    416                 next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y;
    417             }
    418             if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y))
    419             {
    420                 tile_row = i;
    421                 break;
    422             }
    423 
    424         }
    425         *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y;
    426         *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns
    427                         + tile_col;
    428     }
    429     return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    430 }
    431 /**
    432 *******************************************************************************
    433 *
    434 * @brief
    435 *  Function to initialize ps_pic_buf structs add pic buffers to
    436 *  buffer manager in case of non-shared mode
    437 *
    438 * @par Description:
    439 *  Function to initialize ps_pic_buf structs add pic buffers to
    440 *  buffer manager in case of non-shared mode
    441 *  To be called once per stream or for every reset
    442 *
    443 * @param[in] ps_codec
    444 *  Pointer to codec context
    445 *
    446 * @returns  Error from IHEVCD_ERROR_T
    447 *
    448 * @remarks
    449 *
    450 *
    451 *******************************************************************************
    452 */
    453 IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
    454 {
    455     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    456     WORD32 i;
    457     WORD32 max_dpb_size;
    458     sps_t *ps_sps;
    459     UWORD8 *pu1_buf;
    460     pic_buf_t *ps_pic_buf;
    461     WORD32 pic_buf_size_allocated;
    462 
    463 
    464 
    465 
    466     /* Initialize Pic buffer manager */
    467     ps_sps = ps_codec->s_parse.ps_sps;
    468 
    469     /* Compute the number of Pic buffers needed */
    470     max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
    471 
    472     if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
    473         max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
    474 
    475     /* Allocate one extra picture to handle current frame
    476      * In case of asynchronous parsing and processing, number of buffers should increase here
    477      * based on when parsing and processing threads are synchronized
    478      */
    479     max_dpb_size++;
    480 
    481 
    482     pu1_buf = (UWORD8 *)ps_codec->pu1_ref_pic_buf_base;
    483 
    484     ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
    485 
    486     /* In case of non-shared mode, add picture buffers to buffer manager
    487      * In case of shared mode buffers are added in the run-time
    488      */
    489     if(0 == ps_codec->i4_share_disp_buf)
    490     {
    491         WORD32 buf_ret;
    492         WORD32 luma_samples;
    493         WORD32 chroma_samples;
    494         pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size;
    495 
    496         luma_samples = (ps_codec->i4_strd) *
    497                         (ps_sps->i2_pic_height_in_luma_samples + PAD_HT);
    498 
    499         chroma_samples = luma_samples / 2;
    500 
    501         /* Try to add as many buffers as possible since memory is already allocated */
    502         /* If the number of buffers that can be added is less than max_num_bufs
    503          * return with an error.
    504          */
    505         for(i = 0; i < max_dpb_size; i++)
    506         {
    507             pic_buf_size_allocated -= (luma_samples + chroma_samples);
    508 
    509             if(pic_buf_size_allocated < 0)
    510             {
    511                 ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
    512                 return IHEVCD_INSUFFICIENT_MEM_PICBUF;
    513             }
    514 
    515             ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
    516             pu1_buf += luma_samples;
    517 
    518             ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
    519             pu1_buf += chroma_samples;
    520 
    521             /* Pad boundary pixels (one pixel on all sides) */
    522             /* This ensures SAO does not read uninitialized pixels */
    523             /* Note these are not used in actual processing */
    524             {
    525                 UWORD8 *pu1_buf;
    526                 WORD32 strd, wd, ht;
    527                 WORD32 i;
    528                 strd = ps_codec->i4_strd;
    529                 wd = ps_codec->i4_wd;
    530                 ht = ps_codec->i4_ht;
    531 
    532                 pu1_buf = ps_pic_buf->pu1_luma;
    533                 for(i = 0; i < ht; i++)
    534                 {
    535                     pu1_buf[-1] = 0;
    536                     pu1_buf[wd] = 0;
    537                     pu1_buf += strd;
    538                 }
    539                 pu1_buf = ps_pic_buf->pu1_luma;
    540                 memset(pu1_buf - strd - 1, 0, wd + 2);
    541 
    542                 pu1_buf += strd * ht;
    543                 memset(pu1_buf - 1, 0, wd + 2);
    544 
    545                 pu1_buf = ps_pic_buf->pu1_chroma;
    546                 ht >>= 1;
    547                 for(i = 0; i < ht; i++)
    548                 {
    549                     pu1_buf[-1] = 0;
    550                     pu1_buf[-2] = 0;
    551                     pu1_buf[wd] = 0;
    552                     pu1_buf[wd + 1] = 0;
    553                     pu1_buf += strd;
    554                 }
    555                 pu1_buf = ps_pic_buf->pu1_chroma;
    556                 memset(pu1_buf - strd - 2, 0, wd + 4);
    557 
    558                 pu1_buf += strd * ht;
    559                 memset(pu1_buf - 2, 0, wd + 4);
    560             }
    561 
    562             buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
    563 
    564 
    565             if(0 != buf_ret)
    566             {
    567                 ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
    568                 return IHEVCD_BUF_MGR_ERROR;
    569             }
    570             ps_pic_buf++;
    571         }
    572     }
    573     else
    574     {
    575         /* In case of shared mode, buffers are added without adjusting for padding.
    576            Update luma and chroma pointers here to account for padding as per stride.
    577            In some cases stride might not be available when set_display_frame is called.
    578            Hence updated luma and chroma pointers here */
    579 
    580         for(i = 0; i < BUF_MGR_MAX_CNT; i++)
    581         {
    582             ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i);
    583             if((NULL == ps_pic_buf) ||
    584                (NULL == ps_pic_buf->pu1_luma) ||
    585                (NULL == ps_pic_buf->pu1_chroma))
    586             {
    587                 break;
    588             }
    589             ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
    590             ps_pic_buf->pu1_chroma += ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
    591         }
    592     }
    593 
    594     return ret;
    595 }
    596 /**
    597 *******************************************************************************
    598 *
    599 * @brief
    600 *  Function to add buffers to MV Bank buffer manager
    601 *
    602 * @par Description:
    603 *  Function to add buffers to MV Bank buffer manager
    604 *  To be called once per stream or for every reset
    605 *
    606 * @param[in] ps_codec
    607 *  Pointer to codec context
    608 *
    609 * @returns  Error from IHEVCD_ERROR_T
    610 *
    611 * @remarks
    612 *
    613 *
    614 *******************************************************************************
    615 */
    616 IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
    617 {
    618     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    619     WORD32 i;
    620     WORD32 max_dpb_size;
    621     WORD32 mv_bank_size_allocated;
    622     WORD32 pic_mv_bank_size;
    623 
    624     sps_t *ps_sps;
    625     UWORD8 *pu1_buf;
    626     mv_buf_t *ps_mv_buf;
    627 
    628 
    629     /* Initialize MV Bank buffer manager */
    630     ps_sps = ps_codec->s_parse.ps_sps;
    631 
    632 
    633     /* Compute the number of MV Bank buffers needed */
    634     max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
    635 
    636     /* Allocate one extra MV Bank to handle current frame
    637      * In case of asynchronous parsing and processing, number of buffers should increase here
    638      * based on when parsing and processing threads are synchronized
    639      */
    640     max_dpb_size++;
    641 
    642     ps_codec->i4_max_dpb_size = max_dpb_size;
    643 
    644     pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
    645 
    646     ps_mv_buf = (mv_buf_t *)pu1_buf;
    647     pu1_buf += max_dpb_size * sizeof(mv_buf_t);
    648     ps_codec->ps_mv_buf = ps_mv_buf;
    649     mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - max_dpb_size  * sizeof(mv_buf_t);
    650 
    651     /* Compute MV bank size per picture */
    652     pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
    653                                                    ALIGN64(ps_sps->i2_pic_height_in_luma_samples));
    654 
    655     for(i = 0; i < max_dpb_size; i++)
    656     {
    657         WORD32 buf_ret;
    658         WORD32 num_pu;
    659         WORD32 num_ctb;
    660         WORD32 pic_size;
    661         pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
    662                         ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
    663 
    664 
    665         num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
    666         num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
    667 
    668 
    669         mv_bank_size_allocated -= pic_mv_bank_size;
    670 
    671         if(mv_bank_size_allocated < 0)
    672         {
    673             ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
    674             return IHEVCD_INSUFFICIENT_MEM_MVBANK;
    675         }
    676 
    677         ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
    678         pu1_buf += (num_ctb + 1) * sizeof(WORD32);
    679 
    680         ps_mv_buf->pu1_pic_pu_map = pu1_buf;
    681         pu1_buf += num_pu;
    682 
    683         ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
    684         pu1_buf += ALIGN4(num_ctb * sizeof(UWORD16));
    685 
    686         ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
    687         pu1_buf += num_pu * sizeof(pu_t);
    688 
    689         buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);
    690 
    691         if(0 != buf_ret)
    692         {
    693             ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
    694             return IHEVCD_BUF_MGR_ERROR;
    695         }
    696 
    697         ps_mv_buf++;
    698 
    699     }
    700     return ret;
    701 }
    702 /**
    703 *******************************************************************************
    704 *
    705 * @brief
    706 *  Output buffer check
    707 *
    708 * @par Description:
    709 *  Check for the number of buffers and buffer sizes of output buffer
    710 *
    711 * @param[in] ps_codec
    712 *  Pointer to codec context
    713 *
    714 * @returns  Error from IHEVCD_ERROR_T
    715 *
    716 * @remarks
    717 *
    718 *
    719 *******************************************************************************
    720 */
    721 IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec)
    722 {
    723     ivd_out_bufdesc_t *ps_out_buffer = ps_codec->ps_out_buffer;
    724     UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
    725     UWORD32 u4_min_num_out_bufs = 0, i;
    726     UWORD32 wd, ht;
    727 
    728     if(0 == ps_codec->i4_share_disp_buf)
    729     {
    730         wd = ps_codec->i4_disp_wd;
    731         ht = ps_codec->i4_disp_ht;
    732     }
    733     else
    734     {
    735         /* In case of shared mode, do not check validity of ps_codec->ps_out_buffer */
    736         return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    737     }
    738 
    739     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
    740         u4_min_num_out_bufs = MIN_OUT_BUFS_420;
    741     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
    742         u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
    743     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
    744         u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
    745     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
    746         u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
    747     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
    748                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
    749         u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
    750 
    751     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
    752     {
    753         au4_min_out_buf_size[0] = (wd * ht);
    754         au4_min_out_buf_size[1] = (wd * ht) >> 2;
    755         au4_min_out_buf_size[2] = (wd * ht) >> 2;
    756     }
    757     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
    758     {
    759         au4_min_out_buf_size[0] = (wd * ht) * 2;
    760         au4_min_out_buf_size[1] =
    761                         au4_min_out_buf_size[2] = 0;
    762     }
    763     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
    764     {
    765         au4_min_out_buf_size[0] = (wd * ht) * 2;
    766         au4_min_out_buf_size[1] =
    767                         au4_min_out_buf_size[2] = 0;
    768     }
    769     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
    770     {
    771         au4_min_out_buf_size[0] = (wd * ht) * 4;
    772         au4_min_out_buf_size[1] =
    773                         au4_min_out_buf_size[2] = 0;
    774     }
    775     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
    776                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
    777     {
    778         au4_min_out_buf_size[0] = (wd * ht);
    779         au4_min_out_buf_size[1] = (wd * ht) >> 1;
    780         au4_min_out_buf_size[2] = 0;
    781     }
    782 
    783     if(ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs)
    784     {
    785         return (IHEVCD_ERROR_T)IV_FAIL;
    786     }
    787 
    788     for (i = 0 ; i < u4_min_num_out_bufs; i++)
    789     {
    790         if(ps_out_buffer->u4_min_out_buf_size[i] < au4_min_out_buf_size[i])
    791         {
    792             return (IHEVCD_ERROR_T)IV_FAIL;
    793         }
    794     }
    795 
    796     return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    797 }
    798 
    799 /**
    800 *******************************************************************************
    801 *
    802 * @brief
    803 *  Picture level initializations required during parsing
    804 *
    805 * @par Description:
    806 *  Initialize picture level context variables during parsing Initialize mv
    807 * bank buffer manager in the first init call
    808 *
    809 * @param[in] ps_codec
    810 *  Pointer to codec context
    811 *
    812 * @returns  Error from IHEVCD_ERROR_T
    813 *
    814 * @remarks
    815 *
    816 *
    817 *******************************************************************************
    818 */
    819 IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
    820 {
    821     IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
    822     mv_buf_t *ps_mv_buf;
    823     sps_t *ps_sps;
    824     WORD32 num_min_cu;
    825     WORD32 cur_pic_buf_id;
    826     WORD32 cur_mv_bank_buf_id;
    827     pic_buf_t *ps_cur_pic;
    828     slice_header_t *ps_slice_hdr;
    829     UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
    830     WORD32 i;
    831 
    832     ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
    833     ps_sps = ps_codec->s_parse.ps_sps;
    834     ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
    835 
    836     /* Memset picture level intra map and transquant bypass map to zero */
    837     num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
    838     memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
    839     memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);
    840 
    841 
    842 
    843     if(0 == ps_codec->s_parse.i4_first_pic_init)
    844     {
    845         ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
    846         RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
    847 
    848         ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
    849         RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
    850 
    851         ps_codec->s_parse.i4_first_pic_init = 1;
    852     }
    853 
    854     /* Output buffer check */
    855     ret = ihevcd_check_out_buf_size(ps_codec);
    856     RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
    857 
    858     /* Initialize all the slice headers' slice addresses to zero */
    859     {
    860         WORD32 slice_idx;
    861         WORD32 slice_start_idx;
    862 
    863         slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;
    864 
    865         for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
    866         {
    867             slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
    868             ps_slice_hdr_tmp->i2_ctb_x = -1;
    869             ps_slice_hdr_tmp->i2_ctb_y = -1;
    870 
    871         }
    872     }
    873 
    874     /* Get free MV Bank to hold current picture's motion vector data */
    875     {
    876         ps_mv_buf = (mv_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, &cur_mv_bank_buf_id);
    877 
    878         /* If there are no free buffers then return with an error code.
    879          * If the buffer is to be freed by another thread , change the
    880          * following to call thread yield and wait for buffer to be freed
    881          */
    882         if(NULL == ps_mv_buf)
    883         {
    884             ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
    885             ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
    886             return IHEVCD_NO_FREE_MVBANK;
    887         }
    888 
    889         ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf;
    890         /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
    891          * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
    892          * and getting a buffer id to free
    893          */
    894         ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
    895     }
    896 
    897     /* Get free picture buffer to hold current picture recon data */
    898     /* TODO: For asynchronous api the following initializations related to picture
    899      * buffer should be moved to processing side
    900      */
    901     {
    902 
    903         UWORD8 *pu1_buf;
    904         ps_cur_pic = (pic_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, &cur_pic_buf_id);
    905 
    906         /* If there are no free buffers then return with an error code.
    907          * TODO: If the buffer is to be freed by another thread , change the
    908          * following to call thread yield and wait for buffer to be freed
    909          */
    910         if(NULL == ps_cur_pic)
    911         {
    912             ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
    913             ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
    914             return IHEVCD_NO_FREE_PICBUF;
    915         }
    916 
    917         /* Store input timestamp sent with input buffer */
    918         ps_cur_pic->u4_ts = ps_codec->u4_ts;
    919         ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
    920         ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
    921         pu1_buf = ps_cur_pic->pu1_luma;
    922         pu1_cur_pic_luma = pu1_buf;
    923 
    924         pu1_buf = ps_cur_pic->pu1_chroma;
    925 
    926         pu1_cur_pic_chroma = pu1_buf;
    927 
    928         ps_cur_pic->s_sei_params.i1_sei_parameters_present_flag = 0;
    929         if(ps_codec->s_parse.s_sei_params.i1_sei_parameters_present_flag)
    930         {
    931             sei_params_t *ps_sei = &ps_codec->s_parse.s_sei_params;
    932             ps_cur_pic->s_sei_params = ps_codec->s_parse.s_sei_params;
    933 
    934             /* Once sei_params is copied to pic_buf,
    935              * mark sei_params in s_parse as not present,
    936              * this ensures that future frames do not use this data again.
    937              */
    938             ps_sei->i1_sei_parameters_present_flag = 0;
    939             ps_sei->i1_user_data_registered_present_flag = 0;
    940             ps_sei->i1_aud_present_flag = 0;
    941             ps_sei->i1_time_code_present_flag = 0;
    942             ps_sei->i1_buf_period_params_present_flag = 0;
    943             ps_sei->i1_pic_timing_params_present_flag = 0;
    944             ps_sei->i1_recovery_point_params_present_flag = 0;
    945             ps_sei->i1_active_parameter_set = 0;
    946             ps_sei->i4_sei_mastering_disp_colour_vol_params_present_flags = 0;
    947         }
    948     }
    949 
    950     if(0 == ps_codec->u4_pic_cnt)
    951     {
    952         memset(ps_cur_pic->pu1_luma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples);
    953         memset(ps_cur_pic->pu1_chroma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples / 2);
    954     }
    955 
    956     /* Fill the remaining entries of the reference lists with the nearest POC
    957      * This is done to handle cases where there is a corruption in the reference index */
    958     {
    959         pic_buf_t *ps_pic_buf_ref;
    960         mv_buf_t *ps_mv_buf_ref;
    961         WORD32 r_idx;
    962         dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
    963         buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;
    964 
    965         ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
    966         if(NULL == ps_pic_buf_ref)
    967         {
    968             WORD32 size;
    969 
    970             WORD32 num_pu;
    971             WORD32 num_ctb;
    972             WORD32 pic_size;
    973             /* In case current mv buffer itself is being used as reference mv buffer for colocated
    974              * calculations, then memset all the buffers to zero.
    975              */
    976             pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
    977                             ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
    978 
    979             num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
    980             num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
    981 
    982             memset(ps_mv_buf->ai4_l0_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l0_collocated_poc));
    983             memset(ps_mv_buf->ai1_l0_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l0_collocated_poc_lt));
    984             memset(ps_mv_buf->ai4_l1_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l1_collocated_poc));
    985             memset(ps_mv_buf->ai1_l1_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l1_collocated_poc_lt));
    986 
    987             size = (num_ctb + 1) * sizeof(WORD32);
    988             memset(ps_mv_buf->pu4_pic_pu_idx, 0, size);
    989 
    990             size = num_pu;
    991             memset(ps_mv_buf->pu1_pic_pu_map, 0, size);
    992             size = ALIGN4(num_ctb * sizeof(UWORD16));
    993             memset(ps_mv_buf->pu1_pic_slice_map, 0, size);
    994             size = num_pu * sizeof(pu_t);
    995             memset(ps_mv_buf->ps_pic_pu, 0, size);
    996 
    997             ps_pic_buf_ref = ps_cur_pic;
    998             ps_mv_buf_ref = ps_mv_buf;
    999         }
   1000         else
   1001         {
   1002             ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
   1003         }
   1004 
   1005         for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
   1006         {
   1007             if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
   1008             {
   1009                 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
   1010                 ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
   1011             }
   1012         }
   1013 
   1014         for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
   1015         {
   1016             ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
   1017             ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
   1018         }
   1019 
   1020         for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
   1021         {
   1022             if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
   1023             {
   1024                 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
   1025                 ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
   1026             }
   1027         }
   1028 
   1029         for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
   1030         {
   1031             ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
   1032             ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
   1033         }
   1034     }
   1035 
   1036 
   1037     /* Reset the jobq to start of the jobq buffer */
   1038     ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);
   1039 
   1040     ps_codec->s_parse.i4_pic_pu_idx = 0;
   1041     ps_codec->s_parse.i4_pic_tu_idx = 0;
   1042 
   1043     ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
   1044     ps_codec->s_parse.ps_pic_pu      = ps_mv_buf->ps_pic_pu;
   1045     ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
   1046     ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
   1047     for(i = 0; i < MAX_PROCESS_THREADS; i++)
   1048     {
   1049         ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
   1050     }
   1051     ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
   1052     ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;
   1053 
   1054     {
   1055         UWORD8 *pu1_buf;
   1056         WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
   1057         WORD32 pic_size;
   1058         WORD32 num_ctb;
   1059 
   1060         pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
   1061                         ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
   1062 
   1063         ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);
   1064 
   1065         ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;
   1066 
   1067         ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;
   1068 
   1069         num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
   1070         pu1_buf  = (UWORD8 *)ps_codec->pv_tu_data;
   1071         ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
   1072         pu1_buf += (num_ctb + 1) * sizeof(WORD32);
   1073 
   1074         ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
   1075         pu1_buf += ctb_min_tu_cnt;
   1076 
   1077         ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
   1078         pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);
   1079 
   1080         ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;
   1081 
   1082         ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
   1083         ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
   1084         ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
   1085     }
   1086 
   1087     ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
   1088     ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
   1089     ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
   1090 
   1091 
   1092     /* Set number of CTBs to be processed simultaneously */
   1093     ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);
   1094 
   1095     /* Memset Parse Map and process map at the start of frame */
   1096     //TODO: In case of asynchronous API proc_map can not be set to zero here
   1097     {
   1098         WORD32 num_ctb;
   1099 
   1100         num_ctb = ps_sps->i4_pic_size_in_ctb;
   1101 
   1102         memset(ps_codec->pu1_parse_map, 0, num_ctb);
   1103 
   1104         memset(ps_codec->pu1_proc_map, 0, num_ctb);
   1105     }
   1106 
   1107 
   1108 
   1109     /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
   1110      * buffer to be displayed
   1111      */
   1112     ps_codec->i4_disp_buf_id = -1;
   1113     ps_codec->ps_disp_buf = NULL;
   1114 
   1115     ps_codec->i4_disable_deblk_pic  = 0;
   1116     ps_codec->i4_disable_sao_pic    = 0;
   1117     ps_codec->i4_fullpel_inter_pred = 0;
   1118     ps_codec->i4_mv_frac_mask       = 0x7FFFFFFF;
   1119 
   1120     /* If degrade is enabled, set the degrade flags appropriately */
   1121     if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
   1122     {
   1123         WORD32 degrade_pic;
   1124         ps_codec->i4_degrade_pic_cnt++;
   1125         degrade_pic = 0;
   1126 
   1127         /* If degrade is to be done in all frames, then do not check further */
   1128         switch(ps_codec->i4_degrade_pics)
   1129         {
   1130             case 4:
   1131             {
   1132                 degrade_pic = 1;
   1133                 break;
   1134             }
   1135             case 3:
   1136             {
   1137                 if(ps_slice_hdr->i1_slice_type != ISLICE)
   1138                     degrade_pic = 1;
   1139 
   1140                 break;
   1141             }
   1142             case 2:
   1143             {
   1144 
   1145                 /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
   1146                 if((ps_slice_hdr->i1_slice_type != ISLICE) &&
   1147                    (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
   1148                     degrade_pic = 1;
   1149 
   1150                 break;
   1151             }
   1152             case 1:
   1153             {
   1154                 /* Check if the current picture is non-ref */
   1155                 if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
   1156                    (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
   1157                 {
   1158                     degrade_pic = 1;
   1159                 }
   1160                 break;
   1161             }
   1162 
   1163 
   1164         }
   1165         if(degrade_pic)
   1166         {
   1167             if(ps_codec->i4_degrade_type & 0x1)
   1168                 ps_codec->i4_disable_sao_pic = 1;
   1169 
   1170             if(ps_codec->i4_degrade_type & 0x2)
   1171                 ps_codec->i4_disable_deblk_pic = 1;
   1172 
   1173             /* MC degrading is done only for non-ref pictures */
   1174             if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
   1175                (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
   1176             {
   1177                 if(ps_codec->i4_degrade_type & 0x4)
   1178                     ps_codec->i4_mv_frac_mask = 0;
   1179 
   1180                 if(ps_codec->i4_degrade_type & 0x8)
   1181                     ps_codec->i4_mv_frac_mask = 0;
   1182             }
   1183         }
   1184         else
   1185             ps_codec->i4_degrade_pic_cnt = 0;
   1186     }
   1187 
   1188 
   1189     {
   1190         WORD32 i;
   1191         for(i = 0; i < MAX_PROCESS_THREADS; i++)
   1192         {
   1193             ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
   1194             ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
   1195             ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
   1196             ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
   1197             ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
   1198             ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
   1199             ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
   1200             ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
   1201             ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
   1202             ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;
   1203 
   1204             /* TODO: For asynchronous api the following initializations related to picture
   1205              * buffer should be moved to processing side
   1206              */
   1207             ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
   1208             ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1209             ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
   1210             ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;
   1211 
   1212             ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
   1213             if(1 < ps_codec->i4_num_cores)
   1214             {
   1215                 ps_codec->as_process[i].i4_check_parse_status = 1;
   1216                 ps_codec->as_process[i].i4_check_proc_status = 1;
   1217             }
   1218             else
   1219             {
   1220                 ps_codec->as_process[i].i4_check_parse_status = 0;
   1221                 ps_codec->as_process[i].i4_check_proc_status = 0;
   1222             }
   1223             ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
   1224             ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
   1225             ps_codec->as_process[i].i4_init_done = 0;
   1226 
   1227             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
   1228             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
   1229             ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
   1230             ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
   1231             ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1232             ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1233             ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
   1234             ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1235             ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1236             if(i < (ps_codec->i4_num_cores - 1))
   1237             {
   1238                 ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
   1239                                (void *)ihevcd_process_thread,
   1240                                (void *)&ps_codec->as_process[i]);
   1241                 ps_codec->ai4_process_thread_created[i] = 1;
   1242             }
   1243             else
   1244             {
   1245                 ps_codec->ai4_process_thread_created[i] = 0;
   1246             }
   1247 
   1248         }
   1249         ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1250         ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1251 
   1252         ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
   1253         ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
   1254     }
   1255     /* Since any input bitstream buffer that contains slice data will be sent to output(even in
   1256      * case of error, this buffer is added to display queue and next buffer in the display queue
   1257      * will be returned as the display buffer.
   1258      * Note: If format conversion (or frame copy) is used and is scheduled
   1259      * in a different thread then it has to check if the processing for the current row is complete before
   1260      * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
   1261      * returned, which requires a status check to ensure that the current row is reconstructed before copying.
   1262      */
   1263     /* Add current picture to display manager */
   1264     {
   1265         WORD32 abs_poc;
   1266         slice_header_t *ps_slice_hdr;
   1267         ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
   1268         abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
   1269         ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
   1270                            ps_codec->as_process[0].i4_cur_pic_buf_id,
   1271                            abs_poc,
   1272                            ps_codec->as_process[0].ps_cur_pic);
   1273     }
   1274     ps_codec->ps_disp_buf = NULL;
   1275     /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
   1276     /* Since the current will be decoded, check is fore >= instead of > */
   1277     if(((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]) ||
   1278        (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT))
   1279 
   1280     {
   1281         ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
   1282         ps_codec->u4_disp_cnt++;
   1283     }
   1284 
   1285     ps_codec->s_fmt_conv.i4_cur_row = 0;
   1286     /* Set number of rows to be processed at a time */
   1287     ps_codec->s_fmt_conv.i4_num_rows = 4;
   1288 
   1289     if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
   1290     {
   1291         process_ctxt_t *ps_proc;
   1292 
   1293         /* i4_num_cores - 1 contexts are currently being used by other threads */
   1294         ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
   1295 
   1296         /* If the frame being decoded and displayed are different, schedule format conversion jobs
   1297          * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
   1298          * If the frame being decoded and displayed are same, then format conversion is scheduled later.
   1299          */
   1300         if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
   1301            ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
   1302         {
   1303 
   1304             for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
   1305             {
   1306                 proc_job_t s_job;
   1307                 IHEVCD_ERROR_T ret;
   1308                 s_job.i4_cmd = CMD_FMTCONV;
   1309                 s_job.i2_ctb_cnt = 0;
   1310                 s_job.i2_ctb_x = 0;
   1311                 s_job.i2_ctb_y = i;
   1312                 s_job.i2_slice_idx = 0;
   1313                 s_job.i4_tu_coeff_data_ofst = 0;
   1314                 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
   1315                                         &s_job, sizeof(proc_job_t), 1);
   1316                 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
   1317                     return ret;
   1318             }
   1319         }
   1320     }
   1321 
   1322     /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
   1323     ps_codec->i4_pic_present = 1;
   1324 
   1325     return ret;
   1326 }
   1327 
   1328 
   1329